Perhaps a disclaimer first, I haven’t found this in textbook, although I wouldn’t be surprised if it were. It’s actually an explanation I used on a job to explain how splitting responsibilities would help them in their DTAP environment. It’s a loosely defined way of looking at some responsibilities of some facets with respect to testing and deployment.

Let’s start with defining four characteristics of an average application. We’ll start with what the user sees, presentation. This is the interface that exposes the system to the user. It does this by exposing the logic within the application to the user. The logic is the technical implementation of the functionality exposed to the presentation. Exposing only logic is generally not what the user wants, it’d be a very boring application. We want the logic to also influence state. The state describes the current state the system is in. So far we have an application that use a presentation to expose logic, and logic that influences state. Although in general a fine application, these days, systems talk to one another through bit of integration. This then defines the last characteristic, integration. The application logic should be responsible of what is to be integrated and what not.

Presentation

As stated, presentation is the interface users see. Most specifications for applications I help build have a functional design that tends to limit it’s scope to only what the user sees. This is actually the most important bit to key users. It specifies the colors some things have to be as well as the layout it is in. This is very hard to automate testing for, as testing tends to be complex and offer fewer advantages than elsewhere. Also, presentation is something you want to keep the same as much as possible, it should not require any significant modifications or configuration on any of the DTAP environments.

Logic

This is essentially the heart of the application, it defines what functionality is exposed to the outside world. This logic should be tested thoroughly, it should be easy to automate testing and it should not require any significant modification or configuration to run on any of the DTAP environments. It’s connected to everything and it’s contracts should be defined early. Anything the logic depends on should be easy to mock.

State

The state describes the current situation of the system. Backups should be made often and a decent (reproducible) test state should be defined. This test state should be reproduced on development and testing. Preferably, automated testing should be made to use this test state. Any state should actually be completely unaware of being in any specific environment. When hunting for bugs, these bugs generally occur in a specific state. As such, reproducing the current production state in acceptance is the best way to find issues.

Integration

Integration basically connectivity with any other system. When building any kind of integration, it’s important to specify in high detail the behavior of the other system you are integrating with. This you will want to use to make proper mocks for the development and test environments. The actual integration code should be the same on acceptance and production environments, with only configuration changes. Also, here, the integration code should not be aware of the actual environment it is in.

Test

Let’s look at two kinds of tests, automated unit tests and acceptance tests. If we draw a diagram of the various characteristics, we should put logic in the center and draw integration, state and presentation around it. We want to start test automation in the core and work our way outward. Testing logic thoroughly before putting any tests anywhere else. Acceptance tests should start on the outside and test inwards, firstly testing whether everything works, and then working inward to test that what it does, it does properly.

These rules are what I try to apply to projects I’m on, since it’s not extremely technical, it allows me to bridge it between developers and others. It forms the basis of what I design and what I try to instruct others to do. However you tier anything, whatever patterns you apply, these loosely defined rules should make both testing, bug reproduction and deployment relatively structured.