This post originated from an RSS feed registered with Agile Buzz
by Martin Fowler.
Original Post: Bliki: TestPyramid
Feed Title: Martin Fowler's Bliki
Feed URL: http://martinfowler.com/feed.atom
Feed Description: A cross between a blog and wiki of my partly-formed ideas on software development
The test pyramid is a concept developed by Mike Cohn, described
in his book Succeeding with
Agile. It's essential point is that you should have many more
low-level unit tests than high level end-to-end tests running
through a GUI.
For much of my career test automation meant tests that drove an
application through its user-interface. Such tools would often
provide the facility to record an interaction with the application
and then allow you to play back that interaction, checking that the
application returned the same results. Such an approach works well
initially. It's easy to record tests, and the tests can be recorded
by people with no knowledge of programming.
But this kind of approach quickly runs into trouble, becoming an
ice-cream cone. Testing
through the UI like this is slow, increasing build times. Often it
requires installed licences for the test automation software, which
means it can only be done on particular machines. Usually these cannot
easily be run in a "headless" mode, monitored by scripts to put in a
proper deployment pipeline.
Most importantly such tests are very brittle. An enhancement to
the system can easily end up breaking lots of such tests, which then
have to be re-recorded. You can reduce this problem by abandoning
record-playback tools, but that makes the tests harder to write.
[1] Even with good practices on
writing them, end-to-end tests are more prone to non-determinism problems,
which can undermine trust in them. In short, tests that run end-to-end through the UI are:
brittle, expensive to write, and time consuming to run. So the
pyramid argues that you should do much more automated testing
through unit tests than you should through traditional GUI based
testing.
The pyramid also argues for an intermediate layer of tests that
act through a service layer of an application, what I refer to as
SubcutaneousTests. These can provide many of the
advantages of end-to-end tests but avoid many of the complexities of
dealing with UI frameworks. In web applications this would correspond
to testing through an API layer while the top UI part of the pyramid
would correspond to tests using something like Selenium or Sahi..
The test pyramid comes up a lot in Agile testing circles and
while its core message is sound, there is much more to say
about building a well-balanced test portfolio. In particular a
common problem is that teams conflate the concepts of end-to-end
tests, UI tests, and customer facing tests. These are all orthogonal
characteristics. For example a rich javascript UI should have most
of its UI behavior tested with javascript unit tests using something
like Jasmine. A
complex set of business rules could have tests captured in a
customer-facing form, but run just on the relevant module much as
unit tests are.
In particular I always argue that high-level tests are there as a
second line of test defense. If you get a failure in a high level
test, not just do you have a bug in your functional code, you also
have a missing unit test. Thus whenever you fix a failing end-to-end
test, you should be adding unit tests too.
1:
Record-playback tools are almost always a bad idea for any kind
of automation, since they resist changeability and obstruct
useful abstractions. They are only worth having as a tool to
generate fragments of scripts which you can then edit as a
proper programming language, in the manner of Twist
or Emacs.