⬆️ ⬇️

Types of software testing (in pictures)



In the book Growing Object-Oriented Software, Guided by Tests , we described various types of tests that we use when designing software and showed how well they combine with the architectural style of Ports and Adapters ( Ports and Adapters by Alistair Cockburn ).



In Ports and Adapters, the central place of the application is taken by the domain model, which has no points of contact with any parts of the infrastructure, be it a database, a queue, a UI, etc. But the model contains interfaces that define its relationship with the outside world in terms of a domain. Cockburn calls these interfaces ports. These interfaces are implemented in the appropriate objects that interact with the outside world - Cockburn called them adapters. In distributed systems, different processes, each with its own domain model, interact with each other using ports and adapters.



In the diagram above, a large circle is a process, small (inside it) objects. The domain is located at the center of the process. Infrastructure modules (in the figure, these are signed sectors), through which the process interacts with the outside world, cling around the domain “circle”. Adapter modules that display domain concepts for technical implementations are in between.



Below I will try to explain how the different levels of testing fit into the Ports and Adapters.



Unit Tests





Unit tests test individual objects, or their small groups within a single process. For example, with Test-Driven Development, we write unit tests, the results of which affect the test code - we edit it when it does not pass any test cases.



Integration tests





The term "integration tests" can be applied to many types of testing. In our book, we used it to designate tests for some kind of abstraction from our code, which is implemented using third-party packages. Here we want to make sure that our implementation of abstraction is correctly integrated with third-party code: to make sure that we have not made wrong assumptions about how it works and simply does not stumble over some unrecorded errors. However, we cannot take and correct the errors found by these tests, because we do not have access to the tested (third-party) code.



Acceptance tests





Acceptance tests are user-oriented tests, they test the domain logic of the entire sister, and demonstrate that it really works as expected.



Ports and Adapters allow you to run acceptance tests directly for the domain layer, because it is completely isolated from the technical infrastructure and the real world. Acceptance tests can interact with the model through port interfaces. Such tests will be damn fast. They are also easily isolated from each other, because they do not save the state of the model (in the database or the queue, for example).



Acceptance tests for a distributed system can initialize the domains of different processes in shared memory and refer to each other using interface implementations of their ports, which will allow each specific test not to go beyond the limits of its process.



System tests





System tests, testing the system as a whole, controlling it through open ports. They also test the build, deployment, and system boot. Writing system tests in the early stages of development ensures that the system will always be ready for deployment as it develops.



However, such tests are wildly braking + real-world conditions in which they run (concurrency, asynchrony, the need to save data) make it extremely difficult to write readable tests that are isolated from each other.



')

Source: https://habr.com/ru/post/351756/



All Articles