As I often find myself drawing this overview of a test automation architecture, I’ve finally decided to write a short blog post about it. The architecture itself isn’t either new or very innovative, but nevertheless I find that it still is very useful, and provides a baseline for more recent implementations of test automation, like e.g. SpecFlow or similar technologies.

The purpose of having an architecture for your test automation code is to:

  • Ensure good development practices is used in automation code (remember, your automation code must have same quality as production code)
  • Increase maintainability of test automation code

The architecture diagram is shown below, with a traditional architecture for production code shown on the right (I'll get back to the purpose of this).


Test Cases

  • Implementation of e.g. test cases or other
  • This layer should be implemented using declarative programming style, meaning what should be accomplished and not how it’s actual done. I.e. should not include references to actual implementation of system under test, e.g. UI buttons or other more low-level ways of accessing the system

Test Actions

  • Contains all the “building blocks” used in the actual tests.
  • Also somewhat declarative, depending on system and complexity.

Test Infrastructure

  • Imperative (i.e. the actual implementation / "how")
  • The actual ways the system under test is accessed
  • Type-safe representation of UI, e.g. using Microsoft CodedUI UIMaps or similar methods
  • Protocols, e.g. HTTP or other low-level ways of accessing the system
  • Whenever possible, auto-generate code in this layer, e.g. if it’s possible to generate the UIMaps as part of your build process, so you don’t have to maintain these manually.
  • Depending on system, the infrastructure layer exposes either the actual implementations (e.g. UIMaps) or wrapped interfaces, e.g. if there is a need to change actual 3rd party technologies used.

System Under Test

  • No code goes into this layer, but is included in order to show what it is we’re testing (and I find it similar to the database layer in the right hand side of the diagram)

The right hand side of the diagram is included to show test automation code compares to any other traditional software architecture, again in order to emphasize that automation code should be treated as any other code in your system, by using same software development practices that is used for the production code. Another point though is that we should be aware of the added amount of code for automation capabilities. In a typical setup we can easily double the number of layers (e.g. adding 3 layers of automation code on top of 3 layers of production code). The point is of course not to avoid automation, but to have the right level of automation by accessing lower levels of the system whenever possible. And also see if you can auto-generate any of the test automation code like UIMaps or other interfaces for accessing the system under test. If possible generate this as part of your build process.