Much of the software engineering industry uses testing techniques that aren’t often available to those of us in the embedded industry. In my experience, this has definitely been true of automated UI testing while working on ISOBUS VT clients. In a previous position, I spent much of my time creating test frameworks, including those for testing web applications through the UI.
Regular DISTek blog readers will have noticed that we took a VT server implementation to AEF PlugFest in spring 2017. Part of our motivation from the start of this project has been to give VT client developers the ability to automate functional testing of their applications.
If you want to write automated UI tests for a web application, you’ll find that there are hundreds of tools and libraries that already exist. We’ve decided to use the following:
- Selenium, specifically, Selenium WebDriver
Using these tools saves us a lot of time and makes our tests nice and short. I’m a fan of C#, so these tools are commonly used by C# developers. If you prefer a different language or framework, there are many to choose from and they all work in more or less the same way. There are no restrictions on the tools you can use to automate functional tests with our VT.
Here’s a simple test:
A lot of the work here is done by the Laurus.UiTest library. In general, a large part of the work in writing UI tests is writing code to reliably address the different components on the UI. We’ve used the fact that every ISOBUS object has a unique ID to simplify things here. Here’s how we map the UI controls for the data mask used in this test:
In this example we’ve created an interface for our test code to use to access the controls on the data mask, and a class to tell the test library how to find those controls. You can find more details on how all of this works in the Laurus.UiTest documentation.
At this point, we have a functional test that we can execute every time a developer makes a change to our VT client application. We’ll get immediate feedback on whether or not those changes break any existing functionality. That’s a huge step forward for us as engineers, but it only deals with changes to past behavior. That brings us to…
It’s great to be able to automate your testing, but it’s not clear to non-developers exactly what is being tested. That’s where behavioral testing becomes useful. My team at DISTek has been experimenting with behavioral driven development for the past few months and have found it very useful. Our general process for a project is to receive requirements from a customer, convert them into a behavioral statement of work, and implement functionality to satisfy the behavioral requirements. If you’d like to learn more about behavioral driven development, the Wikipedia page is a good place to start.
Let’s convert the button press test from earlier into a behavioral scenario. For this example I’ll use xBehave, but there are a lot of other BDD frameworks to choose from in whatever language you prefer.
Here’s a BDD scenario with empty test code:
Actual implementations of the test steps have been left out for clarity, but to make this test work you’d just need to bring the test code from the first test into the step blocks.
Running this test gives us nicely formatted output that describes how the system behaves:
With this output we can communicate to all stakeholders what the status of the system is. As application developers we have feedback throughout a project telling us exactly how far along we are.
With automated UI testing and behavior driven development, we’ve found that we’re able to much more reliably deliver projects to our customers. It’s important to note, however, that UI acceptance testing shouldn’t be overused. An important concept here is the test pyramid. Automated UI testing is a powerful tool, but it shouldn’t be the only one used to ensure quality.