“This feature is almost ready, but I still need to write some tests.” This a regular statement from developers during client update meetings at Novaya, but what does it mean? Our developers are referring to automated testing via unit tests, a systematic process used to validate a software solution such as a mobile app or website.
Similar to a professor teaching a class, developers create a rubric of features that define what the program should do. Then they create questions to ask the program that evaluate if the features are implemented correctly. Testing is an essential part of modern software development because it validates that features are built correctly and that existing functionality is preserved.
The Importance of Software Testing
Without testing we live in a “that seems about right” world; in software that can only lead to trouble. In order to aid in communication and set appropriate expectations, we work with our customers to come up with a list of stories and acceptance tests that define how each feature should work. The acceptance tests take a story from a vague idea to a feature that can implemented, and ultimately tested.
Story and Acceptance Tests
For example, an app that includes a messaging system may have the following story and acceptance tests.
As a user I want to see all of the messages in a conversation so that I can communicate with other users.
- All messages between myself and my conversation partner are displayed.
- My messages display to the right and my partner’s messages display on the left.
- The messages are displayed from oldest to newest, top to bottom.
Unit testing takes these acceptance tests and turns them into something that can be run automatically any time we want to check our app. Each acceptance test has a corresponding test that directly checks examples in our app. Once these examples are mocked up, we can write code to evaluate our first acceptance test.
All messages between myself and my conversation partner are displayed.
- Generate a set of messages between the correspondents.
- Generate a message that is not between the correspondents.
- Visit the conversation screen.
- Get a list of the messages displayed.
- Compare the list of displayed messages and compare to the list from step one.
Breaking Down the Steps
In steps one and two, we generate test users and messages, known as mocks. Since there are multiple message lists that could potentially be displayed, both examples and counter-examples need creation. Essentially, in order to demonstrate success, the program needs to be given the option to fail. If a professor gives a multiple choice test with only correct answers, the test is meaningless.
Step three points to the location we are testing. For a website this could consist of visiting a URL. If you are testing an app, you could simulate the clicks necessary to reach a particular screen.
In step four we gather what actually happened in our app. It’s the app’s “answer” to the test question.
Finally, in step five we check the answer against what we already know is the correct response. If the list of messages from the screen matches the original list, then the test “passed.” Our app can successfully handle the first acceptance test! If the tests “failed,” the testing tool will display the answer your app produced so that you can work to correct it.
My messages display to the right and my partner’s messages display on the left.
The other stories are similar. As before, create mocks, visit the relevant screen, capture what is there and compare what is displayed to what you wanted to see.
- Display the messages on either side of the screen:
- Generate messages between two users.
- Visit the conversation screen.
- Get a list of all of the left side messages and a list of the right side messages.
- Check the list of right side messages matches the list of logged-in user messages.
- Check the list of right side messages matches the list of other user messages.
The messages are displayed from oldest to newest, top to bottom.
This last one requires more specific, generated messages.
- Generate a message from 3 hours ago, 2 hours ago, and 1 hour ago.
- Visit the conversation screen.
- Get the list of messages on the screen
- Check that the message from 3 hours prior is first on the screen, then the one from 2 hours ago, and finally the 1 hour-old message.
Regression Tests
Sometimes scenarios that were not covered by the initial story and acceptance tests arise. When these are resolved, we write “regression tests” to cover those scenarios. When an app is implemented, the development and testing team will create tests that touch every aspect of the app. When new features are added, these regression tests must updated accordingly to reflect the new changes.
Between regression tests and the initial unit tests we wrote for each feature, we can make changes to the system with confidence. If the tests within the testing suite all pass we can be reasonably sure the changes have not broken existing features or caused bugs to resurface. We don’t want to implement new features at the expense of breaking the current ones!
Testing is Essential for a Quality Product
At Novaya, we believe that testing is essential. Acceptance tests and stories aid in communication between the developer and the client to set expectations. Unit tests use this information to ensure that the code performs correctly. Finally, regression testing evaluates existing features to make sure they have not been affected by new code.
If you need a maintainable, quality application, work with developers who not only understand how to test their code but also incorporate it into all of their projects.