00:00:11.120
I want to share a brief anecdote before I get into the main content of my talk. The very first time I stood in front of a conference room full of people and gave a talk was in 1997 at a vendor tool conference focused on test automation. I was presenting a technique that involved some deep magic with a fascinating, albeit undocumented, aspect of the programming language. I prepared 25 slides that were incredibly code-dense, and when I get nervous, I tend to speak faster. This tendency led me to rush through those slides, and by the time I reached the end, I realized I had used up 25 minutes of my 45-minute speaking slot without any sense of time. I looked at the audience and noticed they all seemed puzzled. I asked, 'Did I go too fast?' but the audience continued to look at me in confusion, except for one person in the front row who said, 'No, that wasn't too fast; that was perfect!' I suspect he understood everything because he was likely intimately familiar with the topic. Yesterday, while sitting in the audience, I realized that I was in front of a room full of people who are much smarter than I am.
00:01:20.560
I am more concerned about whether you, as the audience, will find this session useful. Yesterday, I learned that there are many people here who program in Ruby and are involved in testing, especially those who drive development with tests. I know someone asked how many use Cucumber, but I forgot to ask how many are actually using it. So, how many of you use Cucumber? Wow, that's a lot of hands! That's fabulous, but I want to clarify that this talk isn't solely about Cucumber even though all the examples I’ll use are taken from it.
00:01:37.040
Now, I'm curious to know how many of you take the time to properly maintain your code. Do you refactor, ensure your method and class names are evocative, and remove duplication? Let’s see a show of hands. That's great, but now how many of you treat your acceptance tests the same way? Yes? Well, there are many fewer hands, which makes me a bit sad. But that's okay because this talk isn’t about how to treat your tests like code or how to refactor them. It's also not a technical talk about Ruby or other specific tools, though some technical details may sneak in. Instead, this talk is about being nice to humans – all of you, remember you are human as well.
00:02:52.400
Being nice means communicating in a language that everyone on your team can understand. While some teams might communicate in Ruby or code, chances are your team speaks in English, or at least English is the primary language used. Where better to find guidance for effective communication than in the timeless classic 'The Elements of Style'? As Ryan Henricks reminded us yesterday, tests are a means of communication, so our tests should follow some fundamental rules. Let's take a look at one of the key rules from this book: begin each paragraph with a topic sentence and end in conformity with the beginning.
00:03:40.080
Isn’t it interesting that Strunk and White were indirectly discussing acceptance tests? Let’s reflect on that. Instead of 'scenario,' we could use 'paragraph,' and we should strive for evocative names. But let’s also ensure our expectations are aligned with our statements and names. For example, looking at Cucumber tests, I see many suites where the tests are either verbose or muddy in their intent. We tend to get lost in details that hardly clarify what is being tested. This is a common issue I face with testing frameworks. When looking at a suite of tests, I often find myself thinking, 'What is the intent here?' If I can’t easily determine what is being tested, something needs to change.
00:04:38.080
Let’s explore how to refactor these tests for clarity. Suppose I’m using a trading system called Magix, where users called players wish to trade commodities. If I’m logged in as the fairy godmother on the make offer page and we have a convoluted series of conditions to meet, how can we boil that down to its essence? Often, tests become swamped with UI details that are extraneous to the logic we’re trying to validate. Tests should focus on the intent – here, to make an offer – rather than on the minutiae of filling in the fields of a UI form. This is a widespread practice, and it's essential, especially in acceptance testing.
00:05:53.440
Now that we’ve refactored our test for clarity, we should also adopt another principle: omit needless words. This echoes Strunk and White's Rule number 13. We want our test to express its essence without any unnecessary details. When reviewing our test, if we find any statements that refer to the UI and distract from the main intent, we should consider whether we can eliminate them.
00:06:32.800
We must ensure our test remains focused. For instance, if our expectations are to verify that an offer is created and visible on the market, we do not need to burden our test with UI components unless we are specifically testing the UI. By allowing such superfluous details to seep into our tests, we obscure the intent – the customers want to express their intent about the system clearly. Ultimately, our tests should convey what matters: making offers and seeing them represented clearly in our system.
00:07:59.040
Moving forward, I would like to highlight that clarity and brevity should dominate our acceptance tests akin to how one might approach English in writing. In fact, Strunk and White’s advice can be applied here predominantly: one topic per paragraph. Following Rule 15, we should also put similarly corresponding ideas in similar forms. In Cucumber, this means using scenario outlines and tables to articulate complex situations without creating overly lengthy tests. We must keep tests organized during longer acceptance tests; this will keep both developers and stakeholders in sync regarding expectations.
00:09:02.720
One effective way to be nice to humans is to allow them to express themselves in simple yet meaningful ways. Consider a situation where Jack offers one magic bean bag and T-Bell offers five. If we are too literal in our step definitions, this can stifle the narrative. Instead, we should encourage users to express scenarios as naturally as possible. Cucumber allows us to utilize regular expressions, which can be instrumental in creating flexible and human-friendly steps. This flexibility will help alleviate confusion and miscommunication.
00:10:09.440
Now, let's take a moment to understand the importance of creating these clear acceptance tests. Our approach to acceptance tests ultimately informs how well we understand customer expectations. It’s crucial that we focus on using the tests as a communication tool that aligns with customer needs and the core philosophy of user acceptance. Our tests should capture the essence of what our software aims to achieve, enabling stakeholders to review them meaningfully.
00:11:06.720
Acceptance tests, at their core, should serve as executable documentation that avoids path dependencies. As we become accustomed to writing them, acceptance tests become an important aspect of ensuring shared understanding among teams. They should allow effective communication across all parties – developers, testers, and stakeholders alike. If we face pushback in utilizing natural language in acceptance tests, it highlights a need for further collaboration in developing these tests.
00:12:03.680
Now, I’d like to shift gears and mention the importance of maintaining clarity in our acceptance tests. As developers, we inherently lean toward coding languages and abstract terminologies unique to our domain. This leads to a disconnect, especially when we forget to utilize clear human languages. Ensuring that potential language barriers don’t impede our work is vital; acceptance tests should expand access to knowledge and clarity rather than constraining them.
00:13:26.400
As we tread further into crafting our acceptance tests, I cannot stress enough the importance of clarity. As George Orwell pointed out, "if thought corrupts language, language can also corrupt thought." The way we express our acceptance tests directly influences our understanding of the functionalities we are building. This can unravel into confusion and miscommunication that ultimately leads to tragic misunderstandings weeks later.
00:14:05.440
It’s vital to emphasize that acceptance tests form an essential alignment tool that can bridge the communication gap. We must focus on maintaining clear acceptance tests to ensure that we meet customers’ expectations. When acceptance tests transform into self-explanatory documentation, they enable clients and stakeholders to engage effectively, providing a clearer understanding of the functionalities being implemented.
00:15:37.920
In conclusion, I'd like to extend my gratitude to Steve Conover for reminding me of George Orwell’s wisdom. The collaboration on writing acceptance tests can be incredibly enriching for teams, enabling us to maintain a focus on delivering customer value while ensuring clarity throughout all phases of a project. Moreover, I will share my materials online later today when they are up on GitHub.
00:16:20.480
As we approach the conclusion of my talk, I'm eager to address any questions or discussions on the topics we've covered. I want to encourage you to share your experiences and thoughts regarding acceptance tests. The conversation around improving our practices related to acceptance testing can lead to more effective testing environments. So, feel free to ask, dive into the nuances, and let’s keep the discussion going!
00:17:39.920
Regarding acceptance tests written in natural language, it is an essential conversation to have. When creating acceptance tests, we should balance the expressiveness of our language with the need to avoid redundancy and repetition. This leads to the realization that we can code our tests using a small set of step definitions that may reflect multiple scenarios. However, avoiding redundancy should not come at the cost of clarity. Thus, while striving for DRY principles in our tests, we also need to maintain readability and natural language fluidity.
00:21:03.520
Overall, my goal for today was to emphasize the need for balance: writing acceptance tests that are clear, expressive, and aligned with the core needs and expectations of customers. Let’s work together to develop acceptance tests that serve as effective communication tools, ensuring we can deliver valuable and functional software while fostering collaboration among all stakeholders involved. Thank you!