Test Driven Development (TDD) — is a software development methodology, when tests a written before the main code. This approach makes it possible to maintain the stability and operability of the main code while making functional changes and refactoring, enforces a developer to write more modular code and makes it easier to reproduce bugs.
TDD usually means unit tests — code that tests the atomic functionality of a program.
Integration tests check overall system functionality and test the interaction between different parts of the system.
Integration Test Driven Development
The Integration Test Driven Development (ITDD) approach is suggested in the article when integration tests should be written before the main code, right after the functional specification is ready.
Integration test development is much more difficult than unit test development because it involves different tools — deploying and shutting down a test infrastructure, interaction with a browser or an API client, databases, messaging systems, etc.
But if software evolves on a regular basis, the effort for the integration tests development pays off many times over.
The most time and effort-consuming stage is developing the framework for integration tests. As a developer adds or changes functionality, integration tests are relatively easy to modify.
Integration Test Driven Development advantages
The advantages of ITDD are about the same as of TDD.
- When writing integration tests before the main code, flaws in the functional specification become visible. If writing integration tests using the existing specification is problematic, it means that there are flaws in the specification. For example, some functionality of the system is described unclearly or is not described at all.
- Early on, corner cases and potential bottlenecks can be discussed with the team members responsible for testing.
- Easier identification of potential problematic system components that would be difficult to diagnose
- Integration tests are a kind of documentation because the test code describes how the system should work as a whole and facilitates the immersion of new developers into the
- Integration tests can be used in the future for load testing
- It becomes easier to reproduce complex errors when all parts of the system are working without any issues and there are problems in interaction.
ITDD Example Implementation
Let’s consider the following case. You receive a specification on user account registration in a web application. The user should open the registration form, and enter his login, credentials, and password. If successful the user should receive a message about successful registration.
The basic cases to test:
- Correct data entry by the user: successful registration.
- An account with this login already exists: registration error.
- Password policy violation: registration error.
- Invalid credentials format: registration error.
The response of the system in all cases should be in the specifications. If not, the specification is returned to the analyst or Product Owner. In some cases, the implementation is up to the developers.
Entities that participate in testing:
- User interface service
- Business logic service
- Relation or NoSQL database for user data storage
- Cache database if required
- Message queue
Let’s take the first case as an example:
The script opens a browser and ensures that all elements are displayed correctly. Then test code enters test values in the UI fields and submits the data to the service. The successful registration message should be displayed.
After that, the script checks that a new account is created in the database and the cache service, with the specified attributes. And a new message about the created account was sent to the message queue to the particular topic.
Tools for developing an integration test in that case:
- Docker with testcontainers for test infrastructure
- Selenium for a browser interaction
- Database drivers
- Message queue client for verifying message