Assuming my previous article got you convinced into writing your specifications in Gherkin, we can go on to the next step: The automation of these specifications. This article will show you how to automate your acceptance process using those specifications, speeding up your acceptance process as well as as making your regression tests for the UI-layer fully automated.
When it comes to continuous delivery (CD), automation is key. The automation of your specification will help a lot in the long run, speeding up your CD flow drastically.
Because I love C# and mobile, I’ll show you how to automate these tests using SpecFlow (which is Cucumber for .NET) and a little bit of Xamarin.UITest (which makes it able to run on a phone).
This article is the second part about this subject and I’ll post the next updates in the upcoming weeks. If you want to hear me speak about this subject, feel free to join my "Turn specs into high quality apps"-presentation at TechDaysNL 2016.
The setup
In order to get everything up and running, you’ll need to have the following:
- The Visual Studio with the Xamarin Plugin (Windows) or Xamarin Studio (MacOS) IDE.
- NUnit to run the tests.
- Install SpecFlow for Visual Studio or Xamarin Studio.
- The source code or
*.apk
-file of the app you’re going to test.
We’ll use the following scenario based on one from my previous article as an example. Simply add the *.feature
-file to your project.
Scenario: User successfully checks out a book
Given book that has not been checked out
When user checks out a book
Then book is marked as checked out
When everything is loaded into your IDE, start a new SpecFlow NUnit Project. Add the Xamarin.UITest Nuget package and you’re all set to go.
Automate the steps
When the *.feature
-file is added, SpecFlow automagically creates a partial C# class that can execute the tests. Let’s create a new class to hook into those steps:
using TechTalk.SpecFlow;
using Xamarin.UITest;
[Binding]
public class Steps
{
[Given(@"book that has not been checked out")]
public void BookThatHasNotBeenCheckedOut() {
// (Arrange / Setup) Setup your test
}
[When(@"user checks out a book")]
public void UserChecksOutABook() {
// (Act / Trigger) Act on the object of the test
}
[Then(@"book is marked as checked out")]
public void BookIsMarkedAsCheckedOut() {
// (Assert / Verify) Check if the outcome is as expected
}
}
Let’s see what’s going on here:
- The
[Binding]
-attribute is added to the class. - The methods have the
[Given]
,[When]
or[Then]
attributes with a regular expression that matches the*.feature
-file. - Simply implement these steps as like it was an AAA unittest.
Now that we understand that part, we’ll need to use the power of Xamarin.UITest to hook into the app itself. I’ll dive into this specific part in another article on how to do this, but it might look like something like this:
[When(@"user checks out a book")]
public void UserChecksOutABook() {
// (Act / Trigger) Act on the object of the test
app.WaitForElement (c => c.Marked("Checkout"));
app.Tap (c => c.Marked("Checkout"));
}
Now run your tests and validate the outcome by just using Asserts
. It might take some practice and time, but implement all these steps to automate your specifications. When you write the *.feature
-file in such a way, some steps can easily be re-used.
Scenario outlines & variables
Like I said in my previous article, one of the strong parts when working this way is the usage of Scenario Outlines, making it more like Specification by example (SBE). But how does this work inside these step definitions?
Let’s say we have the following *.feature
-file:
Feature: User can check out books
Scenario Outline: User successfully checks out a book
Given there are <available> books available
When the user checks out <checkout> books
Then there are <left> books left
Examples:
| available | checkout | left |
| 12 | 5 | 7 |
| 20 | 5 | 15 |
SpecFlow will treat these Examples as parameters passed into your tests which are marked by the (.*)
. The following code will be generated:
[Given(@"there are (.*) books available")]
public void ThereAreBooksAvailable(int available) { }
[When(@"the user checks out (.*) books")]
public void TheUserChecksOutBooks(int checkout) { }
[Then(@"there are (.*) books left")]
public void ThereAreBooksLeft(int left) { }
The tests will run multiple times, each time for each example (so two times in this case). Also the test output will show you which one of the examples failed or succeeded. Pretty neat!
Closing thoughts
Now that the specifications have been automated, you can run them over and over to make sure the regression is good. Having all tests pass means that everything works as specified. That’s pretty awesome in my opinion! Take note these tests don’t replace manual testing – on some level, this is still needed. But it definitely speeds up the process
In the upcoming articles, I’ll show how you can work with Xamarin.UITest to actually implement those steps even further. To wrap it all up, I’ll dive into executing these tests not only locally, but in the cloud using Xamarin Test Cloud. This would mean an ever bigger reach of devices on which these tests will be executed and can be integrated in your (nightly) builds as well, which will keep that continuous delivery flow going. Let me know what you think through Twitter!
Want to learn more about this subject? Feel free to join my "Turn specs into high quality apps"-presentation at TechDaysNL 2016. Hope to see you there!