Test design techniques for productive testing.
By: Anton Smirnov
Tags: Tips And Tricks, Testing, Manual Testing, Test Design Technique

Photo by Alesia Kazantceva

Test design is the process of transforming general testing objectives into tangible test conditions and test cases.

The test designer should build a process for testing all the most important parts of the software product, using the minimum possible number of checks. In small teams, the work of a test designer often falls on the shoulders of an ordinary tester. in large companies, the functions of testing and test design are usually clearly divided between specialists.

As a result, the testing chain looks like this:

the test analyst analyzes the product, breaks it down into its component parts, prioritizes testing, and creates a logical map of the application;

the test designer starts developing tests based on the information received from the analyst;

the tester performs direct testing based on ready-made test cases.

Test design techniques:

Equivalence Class Testing.

Test data is divided into certain classes of acceptable values. Within each class, running a test with any value of the test data results in an equivalent result. After defining classes, you must run at least one test in each class.

Let’s demonstrate this with a concrete example. Let’s imagine that we are testing a module for HR that determines whether a candidate can be hired depending on their age. The following selection conditions are set:

if you are between 0 and 16 years old, do not hire;

if you are between the ages of 16 and 18 — you can only hire part-time;

if you are between the ages of 18 and 55 — you can hire for full time;

if you are between the ages of 55 and 99 — do not hire.

Is it worth checking each value? It seems more reasonable to test the range of each condition.

This leaves us with only 4 positive test cases instead of the original 100 (0–99), for example:

10 — don’t hire;

17-hire part-time;

40-hire full-time;

80 — do not hire.

Boundary Value Testing.

This technique is based on the fact that one of the weakest points of any software product is the area of boundary values. To begin with, you select ranges of values — usually equivalence classes. Then the range boundaries are defined. On each of the borders created 3 test cases: the first checks the value of the border, the second value is below the third value above the border.

Let’s return to the example we considered in the technique of equivalence classes:

if you are between 0 and 16 years old, do not hire;

if you are between the ages of 16 and 18 — you can only hire part-time;

if you are between the ages of 18 and 55 — you can hire for full time;

if you are between the ages of 55 and 99 — do not hire.

Let’s imagine that the corresponding code looks like this:

If (applicantAge >= 0 && applicantAge <=16)

hireStatus="NO";

If (applicantAge >= 16 && applicantAge <=17)

hireStatus="PART";

If (applicantAge >= 18 && applicantAge <=54)

hireStatus="FULL";

If (applicantAge >= 55 && applicantAge <=99)

hireStatus="NO";

When you first evaluate the boundaries of the requirements ranges, you immediately see an error — the ranges overlap or overlap. In fact, the condition should be written differently:

if you are between 0 and 15 years old, do not hire;

if you are between the ages of 16 and 17 — you can only hire part-time;

if you are between the ages of 18 and 54 — you can hire for full time;

if you are between the ages of 55 and 99 — do not hire.

If (applicantAge >= 0 && applicantAge <=15)

hireStatus="NO";

If (applicantAge >= 16 && applicantAge <=17)

hireStatus="PART";

If (applicantAge >= 18 && applicantAge <=54)

hireStatus="FULL";

If (applicantAge >= 55 && applicantAge <=99)

hireStatus="NO";

Thus, the set of values for which the tests will be compiled will look like this:

{-1, 0, 1}, {15, 16, 17}, {17, 18, 19}, {54, 55, 56}, {98, 99, 100}

Decision Table Testing.

Solution tables are a convenient tool for capturing requirements and describing the functionality of an application. Tables are very convenient for describing the business logic of an application, and they can serve as an excellent basis for creating test cases.

Decision tables describe the application logic based on the system conditions that characterize its States. Each table should describe one state of the system. The solution table template is as follows:

State-Transition Testing.

The system switches to one or another state depending on what operations are performed on it. For clarity, let’s take a classic example of buying tickets:

State (represented as a circle on the diagram) is the state of the application where it is waiting for one or more events. The state remembers the input data received before and shows how the application will respond to the received events. Events can cause a state change and/or trigger actions.

(represented as a circle on the diagram) is the state of the application where it is waiting for one or more events. The state remembers the input data received before and shows how the application will respond to the received events. Events can cause a state change and/or trigger actions. A transition (represented as an arrow on the diagram) is a transformation from one state to another that occurs during an event.

(represented as an arrow on the diagram) is a transformation from one state to another that occurs during an event. An event (represented by a label above the arrow) is something that causes the app to change its state. Events can be received from outside the application, via the interface of the application itself. The application itself can also generate events (for example, the “timer expired” event). When an event occurs, the application can change (or not change) the state and perform (or not perform) the action. Events can have parameters (for example, the “payMoney”, “print/Ticket”).

(represented by a label above the arrow) is something that causes the app to change its state. Events can be received from outside the application, via the interface of the application itself. The application itself can also generate events (for example, the “timer expired” event). When an event occurs, the application can change (or not change) the state and perform (or not perform) the action. Events can have parameters (for example, the “payMoney”, “print/Ticket”). The action (action, represented after “ / “ in the label above the transition) is initiated by changing the state (“print ticket”). Usually, actions create something that is the output/return data of the system. Actions occur during transitions, and States themselves are passive.

(action, represented after “ / “ in the label above the transition) is initiated by changing the state (“print ticket”). Usually, actions create something that is the output/return data of the system. Actions occur during transitions, and States themselves are passive. The entry point is indicated by a black circle.

Pairwise testing.

The pair testing method is based on the following idea: the vast majority of bugs are detected by a test that checks either one parameter or a combination of two. Errors caused by combinations of three or more parameters are usually much less critical.

Let’s say that we have a system that depends on several input parameters. Yes, we can check all possible combinations of these parameters. But even for the case when each of the 10 parameters has only two values (On/Off), we get 210 = 1024 combinations! Using the method of pair testing, we do not test all possible combinations of input parameters but create test sets so that each parameter value is combined at least once with each value of the other tested parameters. Thus, the method significantly reduces the number of tests, and hence the testing time.

But the highlight of the method is not to go through all possible pairs of parameters, but to choose pairs that provide the most effective verification with the minimum number of tests performed.

Exploratory testing.

Exploratory testing is an approach to software testing that is often described as simultaneous learning, test design, and execution. It focuses on the discovery and relies on the guidance of the individual tester to uncover defects that are not easily covered in the scope of other tests.

As the well-known definition says, programming is thinking, not typing. So why do we need test designers? Why spend time on analysis and design if you can use it to perform a lot of additional checks?

The examples above show that using design can significantly reduce the number of tests, as well as focus on the most vulnerable and important parts of the functionality.

What is the point of full test coverage of the authorization form if the payment mechanism for the product in the online store does not work correctly? After all, while the tester checks 100 values with 100 tests, the test designer will figure out how to check 1000 values in 10 tests. Thus, the effort spent on test design will pay off with the quality of test execution.

Gain Access to Expert View — Subscribe to DDI Intel