Single Responsibility Testing

Parshotam Toora
The Telegraph Engineering
2 min readSep 1, 2017

Beyond The Pyramid Model To Microservices Testing

So What’s The Problem?

The Pyramid testing model was great for coupled web MVC applications. However in the Microservices era, following this approach conflates layers of testing which have different motivations, thus creating gaps, and it conflates components of architecture which have different responsibilities, thus creating inefficient test strategies, so it does not support ‘fail fast fail true’.

n.b. Unit tests are cool; they give confidence in code robustness, they support Test Driven Development, and they ‘fail fast’. However their focus is to verify the technical design of potentially reusable components, and to support collaborative working. They don’t fully demonstrate that the application meets the business requirement because they don’t adequately test the orchestration and collaboration between units from a business behavioural perspective.

How Do We Approach An Alternative?

Our key requirements:

  1. Fails Fast — fail at the earliest point in the lifecycle
  2. Fail True — failures should be due to issues in the application under test and not a third party (single responsibility in test design)
  3. Fail Smart — fewest tests with maximum coverage (lean software development lifecycle)

Approach the testing from the three aspects of architecture:

  1. Functionality
  2. Integration (direct API calls, messaging, and data passed between APIs)
  3. State (persisted data)

Single Responsibility Approach

The different layers of an application should be treated as independent applications rather than part of a single ‘pyramid’. All dependent layers should be stubbed out to focus testing on the application under test. This approach will address each ‘layer’ of the traditional system as a stand-alone application following the archetype illustration (==>) where the app has the following aspects:

  • functions/endpoints and contracts
  • Local (domain) state
  • Third party client(s)
  • Third party consumer(s)
  • Upstream/downstream flows with system state

Following this approach will result in a comprehensive and efficient test strategy. The key thing is to identify the smallest functional application and its integrations and state transitions.

N.B. The UI ‘layer’ can be treated as an independent application as easily as a REST service. Single Page Applications are already moving in this direction with Component abstraction (e.g. in React and Angular) analogous to service endpoints.

Resulting Test Streams

Thank you for reading this blog, all feedback is welcome.

For further blogs from the Telegraph: http://engineering.telegraph.co.uk

-_-

--

--