Monday, July 5, 2010

Testing, types, kinds, and flavours

Building on anatomy of a test, I would like to follow up with a few points of note. These points are not based on any academic theory, principle, or practice. Instead, they are based mostly on anecdotal experience - so do not take this as "law", but rather a practical framework for communicating expectations about "testing" in general.

Preface aside, these points may be separated into three independent aspects,
  • Types,
  • Kinds, and
  • Environments,

Types

There are three main types of tests; unit tests, integration tests, and system tests. What differentiates one type of test from another is scope.

A unit test evaluates functional behaviour of a single component - all dependencies are stubbed or appropriately mocked. An integration test evaluates functional integration of two or more components - dependencies outside of a chosen scope are stubbed or mocked. A system test is a special case of an integration test, it evaluates functional behaviour of all components - no dependency is stubbed or mocked.

Kinds

Every test is carried out in one of two fashions, a test is either manual or automated. Admittedly, such a small set hardly warrants discussion, but it is important to recognize this distinction. Even if, as developers, we deal primarily in automated tests it may sometimes fall to us to provide a manual test plan for person-in-seat testers.

In terms of resources required, execution times, and result variance, manual tests may differ significantly from an automated equivalent. As such, it is important to understand these differences, and communicate appropriate expectations regarding the work required by that kind of test.

Environments

Last and not least is the environment in which a test executes. The shape of data used as input may impact veracity and performance* of a test, which is why it is important to implement and maintain different testing stages thoughout a development cycle.

The point and purpose of each stage is twofold. First, each distinct stage we implement should progress from development-ready quality to production-ready quality. Second, each stage isolates itself from the other - and we do not promote code if it does not pass muster.

As an example, we may have several development environments (one for each developer!), a single build environment, a Quality Assurance (QA) environment, a System Integration Test (SIT) environment, a User Acceptance Test (UAT) environment, and a Preproduction Test (PreProd or PPT) environment.

This is certainly not exhaustive, just some of the common stages I have seen in my work.

Perhaps we noticed that one environment is conspicuously absent? That would be Production (Prod). We do not typically test in Prod. In fact, never test in Prod. PreProd is an exact mirror, from hardware to data to security infrastructure. Furthermore, the only distinction between PreProd and Prod is that PreProd is not Prod. This speaks most importantly to the second point and purpose above, isolation. Heaven forbid anything goes wrong at this stage, but if it does then Prod is safe and we dodge the million dollar liability suit/bullet.

Further reading

Wikipedia on testing.




* = hm, some may be confused by my citing "performance" here. Generally speaking, performance testing is treated distinctly from functional testing and we do not mix the two. However, from a perspective of "testing", each sets expectations, invokes a process, and evaluates outcomes to expectations, and so performance is as valid a quality as a functional outcome in this context.