How to use the Business Involvement Patterns in the project.
In my recent article, I reviewed the main automation patterns that can be applied in your work if necessary. Today I continue a series of articles devoted to the consideration of design patterns. In this article, we’ll talk about Business Involvement Patterns and the behavior specification and steps patterns.
The main goal of these patterns is to are trying to bring product owners, business analysts, and other people in charge of requirements as close to test automation as possible, so that they see the benefits of it, and they invest in it as much as we do because we are a single team. It’s the perfect scenario for all the members of the team, isn’t it?
Behavior Specification.
It suggests transforming the writing of the tests into defining the expected behavior. This way the feature can be described in the form of behavior scenarios. Here is a simple example of this pattern:
Feature: Multiplication In order to avoid silly mistakes
As a math idiot
I want to be told the sum of two numbers
Scenario: Multiplication two numbers Given I entered 10 into the calculator
And I entered 10 into the calculator
When I pressed the multiply button
Then The result should be 100 on the screen
The scenario describes a simple workflow of the multiplication of two numbers using calculator buttons and verification of the result on its screen. This test is not a “test” in common sense, it’s more a behavior specification. It’s easy to read and can be understood by anyone. But again, this pattern will be super useful only if the business wants to be involved in the testing process (e.g. by creating the acceptance criteria based on those specs and tracking the results of tests).
Steps.
When we’re talking about logic scenarios, we think about them as if they consist of steps. But when you implement them in your code, these steps often get lost among all the technical details, data manipulations, and other things we’re doing in our tests. It would be great if we could isolate those steps from other code showing what this particular test does and easing the hurdle of its maintenance. The Steps pattern will help us to do that.
Your test steps might be divided into groups by functionality and gathered into special classes or methods. If you don’t have the step you need in your test, you can simply create one. You can use the Steps Pattern either with some technical framework (e.g. Page Object) or without any. It doesn’t matter as long as you divide your logic into the Steps:
/**
* The class Simple test.
*/
public class SimpleTest {
/**
* Test book searched by name.
*/
@Test
public void testBookSearchedByName() {
openAuthenticationPage();
enterLoginAndPassword("admin", "admin");
openSearchPage();
enterSearchString("name", "Selenium WebDriver");
assertFalse(isEmptySearchResult());
openBookByIndex(1);
assertEquals("Selenium Testing Tools", getTitle());
assertEquals("Alexey Barancev", getAuthor());
}
}
Steps:
1. Open Main Page
2. Open authentication page
3. Login as user 'admin' and password 'admin'
4. Open search page
5. Try to search by word 'Selenium Web Driver'
6. Results should not be empty
7. Open the first found book
Expected results:
1. Book title is 'Selenium Testing Tools'
2. Author is 'Alexey Barancev'
Writing test scenarios in this way may help to avoid using any extra Test Case Management system, since all of the Test Steps, either automated or manual ones, are stored in one place, which is your framework. As a bonus now you can easily track, how many steps are automated, how many of them are broken, who was responsible for their creation etc.
Behavior Driven Development says that first, we need to specify all the behavior of our functionality, then we need to implement it in code and write falling tests, and in the end, we will get working tests at a low level, behavioral scenarios at a high level, and everyone will be happy.
If the business on your project is not ready for this kind of approach, you don’t have a problem that needs the given solution, and by implementing it you’d create another unnecessary layer of abstraction above your test logic.