A data model and the related database of course change from time to time. New features are introduced, old and deprecated data types are removed and new relations embedded. Data integrity ensures your application works as it’s supposed to. Consider two different scenarios:
- Another system introduces changes, which affects the API in whatever way. You are able to say for sure, no changes of your own system lead to this error and you can easily take action to solve this issue instead of tracking down the instance which could have been responsible for the error. In theory ;-)
- Some changes lead to side effects and affect other test scenarios. React on them and keep everybody’s daily-business up and running instead of facing a problem several days after a change, when the error finally occurs.
At last: be honest. How many times did you think: „This solution is engraved in stone, my children’s children will still benefit from this“ – and now let’s face reality ;-)
While Unit Tests cover a certain method or function, integration tests aim to validate and verify the correct behavior of such correlations. For example, a certain function calls and interprets another functionality.
Our unit tests have proven: both functions work as they should on their own. The integration test will now cover the case of the combinations also working as intended. This might happen if you run different functions in different threads and still like to ensure this does not lead to memory leaks or misinterpreted results.
I like two kinds of integrations tests in particular which I’d like to elaborate further:
- Database integration
- API Tests (testing the communication layer and the correct interpretation of the request results)
I think the advantages are quite obvious. In the MyMedela app for example, we’re able to automatically create app users with certain data sets and without the necessity to fill out everything on our own. Furthermore, you can easily ensure that, for example, the user creation process is working as it should according to the sequence diagram of the documentation.
You can easily erase and clear up the database or – all hail to the persistency – you can use results of former tests to run follow up tests, which make use of this data. This could also cover an entire use case, specified or identified in the project setup.
- First, a user is created. We like to ensure the user is correctly stored in the database. Unit tests cover the case that data is set according to the specification. The integration test just ensures the data integrity. The object is stored to and accessible from the database, from whatever thread.
- In a second test case we can now start to add related data objects, which were not yet assigned but are related to the user object. In addition, we could also edit or modify certain properties.
- Finally, we will range up everything and clear the database and all created objects, to ensure the tests do not interfere with any other test cases, where we want to make us of a database (in case no specific test database was created).
This opportunity has granted us an on the fly debugging for several thousands of user trackings. Just by pressing the „start testing“ button and editing the amount of trackings being created, we were easily able to reproduce user problems that way.
Please let me emphasize this once again: We did not add data to a user from the backend system to the backend database. Instead we were creating data sets the way a “real” user would: directly on the device by making use of the device’s network connection and hardware limitations. In fact, in such a synchronisation mechanism you are facing crucial challenges.
Let’s face the above integration test scenario again. As the above test scenario only takes care of the local data handling, API Tests (especially the ones, which communicate with other systems) are even more complex.
- The created user requires to be created on the backend system.
- After the creation was successful, we should not be able to login with incorrect user credentials
- And of course, we should be able to login with correct user credentials.
- Now we can start to modify and manipulate user data or add certain data sets
- Finally, don’t forget to restore the state before we tested: Logout the user from the server
- Clean up the local database (if the logout process did not cover this yet)
I do know, project managers tend to be afraid of integration tests. They are time consuming and therefore cost money and are supposed not to have much value for the client’s needs, as you simply test something, which have been tested either way.
Nevertheless, let’s face the fact:
For the sake of conscientiousness, please ensure that at least the logic layer of your software is tested, so you can react in an appropriate timeframe if something breaks.