Testing software using automated tools and processes lies at the heart of agile prototyping in software development. Yet, we need to go beyond the concept of testing by looking at different types of testing required to deliver testable software effectively.
- Unit testing - this type of testing automates testing software units that are typically understood as software classes. Testing assumes a given output for a number of inputs passed to a specific method to test software methods in different conditions. Unit testing can test multiple units with one test.
- Integration testing. This type of testing automates the testing of the integration of different software modules, typically executed in a different context and running other technologies. Typically integration testing ensures communication between various services; however, we can also test integration between different dependencies, even external dependencies that are provided with no source code to its internals.
- End to end testing. This type of testing automates end-user activity in the client software that invokes chains of activities between different units, modules and services. The end-to-end testing typically ensures that end-user software provides functionality that is working in a specified manner.
Yet, every type of testing typically can be twisted by a set of antipatterns that invalidate the sense of performing every kind of test. Every time you write complex software first and then provide unit testing simply by grabbing the actual unit output and putting it into the expected unit test output without any other rationale validating the unit test result. Every time one writes an integration test that provides a fixed response to any request from an external module, the sense of testing is invalidated as essentially, we're not even testing if the command passed to the external module was correct or even acceptable in the first place. Every time we test only against the positive end-user path, we only confirm artificial use scenarios without assuming incomplete or incorrect end-user actions.
Therefore, we need to define the expected result of each type of test and what needs to be confirmed by each set of tests. Unit testing must provide evidence demonstrating that each software unit contains methods that operate correctly under a range of acceptable input parameters. Integration testing must provide evidence that different services understand and exchange correct messages in response to various commands and queries using test doubles (fakes - not dummies, stubs, or mocks). End to end testing must provide evidence that different user interactions provide expected software results.
Terminology: Test double - a non-real dependency that one replaces with an object for testing. Fake: contain working implementation of dependencies. Mock - objects that verify the methods called on them by testing code. Stubs - objects that are acting as dependencies returning fixed values or properties. Dummy - objects used only to satisfy parameter expectations to be non-null objects..
- Comments
- Leave a Comment