Test double
A test double is software used in software test automation that satisfies a dependency so that the test need not depend on production code. A test double provides functionality via an interface that the software under test cannot distinguish from production code.
A programmer generally uses a test double to isolate the behavior of the consuming code from the rest of the codebase.
A test double is usually a simplified version of the production code and may include capabilities specific to testing.
Test doubles are used to build test harnesses.
Uses
[edit]A test double may be used to simplify tests, increase speed of execution or allow for deterministic results of an action.
For example, a program that uses a database server is relatively slow and consumes significant system resources, which impedes testing productivity. A test might require data from the database that under normal system activity is regularly changing, so provides non-deterministic outputs for any given query. A test double can provide a static value instead of accessing a real database, thereby both avoiding network or system calls, and changing data.
A test double may also be used to test part of the system that is ready for testing even if its dependencies are not.
For example, in a system with modules Login, Home and User, suppose Login is ready for test, but the other two are not. The consumed functions of Home and User can be implemented as test doubles so that Login can be tested.
Caveats
[edit]While test doubles are often used to facilitate unit testing there are limitation of using test doubles, the key one being that actual database connectivity or other external-access is not proven to work by those tests. To avoid errors that may be missed by this, other tests are needed that instantiate the code with the "real" implementations of the interfaces discussed above. These integration risks are typically covered by integration tests, system tests or system integration tests.
Implementation approaches
[edit]When implementing test doubles, the typical approach involves two key steps:
- Whenever external access is needed in production, an interface should be defined that describes the access available. See the dependency inversion principle for a discussion of the benefits of doing this regardless of TDD.
- The interface should be implemented in two ways, one of which really accesses the external process for use in production, and the other of which is a test double typically a mock or a fake.
This approach enforces a unit-testable separation and drives more modular, testable and reusable code design.[1]
Types
[edit]Test doubles are categorization many ways.
General
[edit]Although not universally accepted, Gerard Meszaros[2] categorizes test doubles as:
- Stub — provides static input
- Mock — verifies output via expectations defined before the test runs
- Spy — supports setting the output of a call before a test runs and verifying input parameters after the test runs
- Fake — a relatively full-function implementation that is better suited to testing than the production version; e.g. an in-memory database instead of a database server
- Dummy value — a value that is required for the tested interface but for which the test case does not depend
While there is no open standard for categories, Martin Fowler used these terms in his article, Mocks Aren't Stubs[3] referring to Meszaros' book. Microsoft also used the same terms and definitions in an article titled, Exploring The Continuum Of Test Doubles.[4]
Service
[edit]For service-oriented architecture (SOA) systems and microservices, testers use test doubles that communicate with the system under test over a network protocol.[5][6] These test doubles are called by different names by the tool vendors. A commonly used term is service virtualization. Other names used include API simulation, API mock,[7] HTTP stub, HTTP mock, over the wire test double[8] .[9]
Verified fake
[edit]A verified fake is a fake object whose behavior has been verified to match that of the real object using a set of tests that run against both the verified fake and the real implementation.[10]
See also
[edit]- Mock object
- Software testing
- Service virtualization
- Comparison of API simulation tools
- List of unit testing frameworks
- Object-oriented programming
- Test-driven development
References
[edit]- ^ Fowler, Martin (1999). Refactoring - Improving the design of existing code. Boston: Addison Wesley Longman, Inc. ISBN 0-201-48567-2.
- ^ Meszaros, Gerard (2007). xUnit Test Patterns: Refactoring Test Code. Addison-Wesley. ISBN 978-0-13-149505-0.
- ^ Fowler, Martin (2007). "Mocks Aren't Stubs". Retrieved 2010-12-29.
- ^ Seemann, Mark (2007). "Exploring The Continuum Of Test Doubles". Retrieved 2010-12-29.
- ^ Clemson, Toby "Testing Strategies in a Microservice Architecture", martinfowler.com, 18 November 2014. Retrieved on 07 December 2017.
- ^ Byars, Brandon. "Testing Microservices with Mountebank", Manning Publications, MEAP began March 2017. ISBN 9781617294778. Retrieved on 07 December 2017.
- ^ Bryant, Daniel "API Mocking Tool WireMock v2 Released with Improved Request Matching and Stub Management", InfoQ, 16 August 2016. Retrieved on 07 December 2017.
- ^ ThoughtWorks "Technology Radar, Tools: Mountebank", ThoughtWorks, November 2015. Retrieved on 07 December 2017.
- ^ Bulaty, Wojciech "Stubbing, Mocking and Service Virtualization Differences for Test and Development Teams", InfoQ, 19 February 2016. Retrieved on 07 December 2017.
- ^ Turner-Trauring, Itamar (2019). "Fast tests for slow services: why you should use verified fakes". Retrieved 2019-01-21.
External links
[edit]Gerard Meszaros:
Martin Fowler:
- TestDouble, 17 January 2006
Open source:
- ELF Spy - Fakes and Spies in C++
- FakeIt - Mocks, Fakes and Spies in C++
- Google Mock - Mocking in C++
- jMock - Test Driven Development with Mocks
- Mockito - Mocking Framework for Java
- unittest.mock - Mocking with Python