Work with my current client mostly consists of building an automated testing framework, one that utilizes Cucumber, an automated behavioral testing framework, and Gherkin, the language that Cucumber uses to define tests in plain English. The end goal is for the framework to reach a sufficient amount of coverage across the client’s application, so that non-programmers can easily write new test cases in plain English. The project has progressed quickly, and as more people have come on, the amount of written step definitions have risen exponentially. We designed things so that we could use English, assuming that it would be universally understood across any team. However, we failed to take into account that while English is powerful, it’s frustratingly fluid and interpretive. That’s not to say that it’s a difficult language to understand or that some people on the project are bad at English, quite the contrary; everyone on the project is proficient enough in English that it harms us. Below is the Gherkin for a few step definitions I found in our code.
- I access the dashboard
- I go to the dashboard
- The dashboard is accessed
This is messy, in a lot of ways. It all makes sense, but clearly there’s no standard, universal definition for this action, at least not where the broad world of English is concerned. Step definitions should be written so that, without knowing whether it exists, I can immediately know how that definition should be written, and subsequently find out if it’s already been done or not. But as you notice, none of the steps above are ‘wrong’, they all accurately describe the action taken, and are in proper forms of English. So we need to ignore typical English, and make our own subset that decides what’s wrong and right.
In developing a descriptivist rule set for a largely subjective entity, we quickly run into an issue about language that David Foster Wallace talks about in his essay, “Authority and American Usage”.
“Even if, as a thought experiment, we assume a kind of 19th-century scientific realism – in which, even though some scientists’ interpretations of natural phenomena might be biased, the natural phenomena themselves can be supposed to exist wholly independent of either observation or interpretation – it’s still true that no such realist supposition can be made about ‘language behavior’ because such behavior is both human and fundamentally normative.”
Designing a realist system when it comes to an ever-evolving language is an impossible task. These proposed rules will likely cause some issues of their own (probably some drawback like your team hating you for being scrupulous when it comes to small issues with usage), but it comes with the benefits of stopping duplicated work, keeping your code clean, and giving your testing team clear instructions for writing their steps.
Creating the Usage Rulebook
There are some general things we can easily solve when it comes to tense and perspective (see table), but the big issue tends to be the use of synonyms, and specifically verbs.
|Perspective||Third Person||Third Person||Third Person|
This is where the real work (and benefit) starts to kick in, you need to standardize all the verbs and nouns you will use for your application. I doubt there’s a (good) universal lexicon that all projects can use, especially when it comes to nouns, so this will have to vary heavily based on project. Which is fine, you just need to take time to write the rulebook, and heavily enforce it. With enough time, the system will likely establish itself enough so that it requires no more human enforcement; you and your team naturally adhere to it like any other programming language, making it a sort of language of its own.
Below is a small example list for the project we’re currently working on.
|Something is visibly on the screen||Visible|
|“Going through” a form / large amount of input||Complete|
|Navigating to a specific part of the application||Access|
|Something new is instantiated / created||Created|
Nouns should get a similar treatment, think about if you want to refer to links and buttons differently, does it matter to differentiate them? What are official names for sections of the application? Do any of them conflict? Are you running tests from multiple perspectives (User, Admin)?
Consider a similar example to what we started with above. If an example test is to register a user, have them access the dashboard, and assert that a certain header is present, imagine the different verbiage that could be utilized to create each of these steps. Then observe the ones that are built from this system.
Given the user has been created
When the user accesses the dashboard
Then the header <header> will be visible
Some of the definitions above might seem redundant, but to your six other team members who all learned different forms of English in different parts of the world (many as a second language) it will likely be the exact opposite. Keeping your wording consistent helps avoid a lot of issues with duplication and disorganization, and will eventually save you time down the road when your team begins requesting and writing steps that you have already written, but with slightly different wording.