In the first part of our Functional Testing article, we explored key techniques such as Equivalence Partitioning, Boundary Value Analysis, and Category Partitioning which are crucial for evaluating a system's compliance with specified requirements. In the next section, we will delve deeper into another important aspect of functional testing, called Cause Effect Graphing.
This technique focuses on identifying and modelling the relationships between the inputs and outputs of a program, as well as the logical connections between them. We will also discuss the benefits of using this method and provide examples of its application in functional testing.
It is a visual representation of the logical relationship between causes and effects, expressible as a Boolean expression.
Cause = any condition in the specification(s) that may affect the response of the program;
Effect = program response to a combination of input conditions;
The effect is not necessarily an output (it can be an error message, a display, a database modification, or even an internal test point).
Types of Cause-Effect relationships
- Implies: if C then Ef
- Not – Implies: if (¬ C) then Ef
- And – Implies: if (C1 && C2) then Ef
- Or – Implies: if (C1 || C2) then Ef
Types of constraints between causes
E (exclusive): either C1 or C2 (at most one of them)
I (inclusive): At least C1 or C2
- O (one and only one): One and only one of C1 and C2
- R (requires) C1 requires C2 (if C1 then C2)
Types of constraints between effects
- M (Masks): Ef1 masks Ef2 (if Ef1 then ¬Ef2)
Example 💻
Let's see a simple example of a Cause-Effect Graph.
A company sells on the web computers (CPU1, CPU2, CPU3), printers (PR1, PR2), monitors (M20, M23, M30) and additional memory (RAM256, RAM512, RAM1G). An order includes between 1 and 4 items, at most one of the 4 categories mentioned. The Graphic Integrate consists of 4 windows (for the 4 product categories) and a window for displaying the items received as a gift.
The M20 and M23 monitors can be bought with any CPU or alone. M30 can only be bought together with CPU3. PR1 is offered as a gift for buying CPU2 or CPU3. Monitors and printers, apart from M30, can be bought separately, without buying the CPU. When buying one CPU1 you get a RAM256 upgrade, and with the purchase of a CPU2 or CPU3 RAM512 upgrade is received. When buying a CPU3 and an M30, receive a RAM1G upgrade and PR2 as a gift.
Extracting the causes:
C1: Purchase of CPU1
C2: Purchase of CPU2
C3: Purchase of CPU3
C4: Purchase of PR1
C5: Purchase of PR2
C6: Purchase of M20
C7: Purchase of M23
C8: Purchase of M30
Getting the effects:
Ef1: RAM256
Ef2: RAM512 and PR1 (can be considered separation effects, but it can unnecessarily complicate the graph)
Ef3: RAM1G and PR2
Ef4: no gift
Decision Table
A decision table is a tool that is commonly used in conjunction with the cause-effect graphing technique in functional testing. It is a tabular representation of all possible inputs and outputs for a specific system or component, based on the causes and effects identified in the cause-effect graph.
Decision tables are useful for identifying any missing combinations of inputs and outputs, and for testing the system or component with a comprehensive set of test cases. The decision table can also be used to organize and document the test cases and results, making it a useful tool for both the testing and development teams.
Input: A cause-and-effect graph having causes C1, …, CP and effects Ef1, …, Efq.
Output: A decision table with N = p + q rows and M columns, where M depends on the relationship between cause and effect.
The procedure for creating a decision table 📋
Initialize no_columns = 0 (empty decision table);
For i = 1 to q;
E = EFI (selects the following effect for processing);
Find the combinations of conditions that produce the effect of;
Let V1, ..., VMI these combinations, MI > 0. Set VK(j), p < j ≤ p+q, to 1 if the EFJ effect occurs as a result of that combination, and to 0 if not;
Update the decision table;
Add columns V1, ..., VMI to the table starting with position No._columns + 1;
no_columns = no_columns + mi;
Example
Creating decision table
Step 1: nr_columns = 0;
Step 2: i = 1;
Step 2.1: e = Ef1;
Step 2.2: Searching the values for C1, C2, C3 such that ¬ (C1 ∧ C2) ∨ C3 = 1;
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 1 |
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
In addition, the constraint C3 implies C1 is applied;
1 | 0 | 1 |
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
Add C4 = 0 and the corresponding values for Ef1 and Ef2;
V1 | 1 | 0 | 1 | 0 | 1 | 0 |
V2 | 1 | 1 | 1 | 0 | 1 | 0 |
V3 | 1 | 0 | 0 | 0 | 1 | 0 |
V4 | 0 | 1 | 0 | 0 | 1 | 0 |
V5 | 0 | 0 | 0 | 0 | 1 | 0 |
Step 2.3: The obtained matrix is transposed and added to the decision table, starting with position nr_columns + 1 = 1;
1 | 2 | 3 | 4 | 5 | |
C1 | 1 | 1 | 1 | 0 | 0 |
C2 | 0 | 1 | 0 | 1 | 0 |
C3 | 1 | 1 | 0 | 0 | 0 |
C4 | 0 | 0 | 0 | 0 | 0 |
Ef1 | 1 | 1 | 1 | 1 | 1 |
Ef2 | 0 | 0 | 0 | 0 | 0 |
Step 2.4: No_columns = 0 + 5 = 5 are updated;
Step 3: i = 2;
Step 3.1: e = Ef2;
Step 3.2: The values of C1, C2, C3, C4 are sought so that (¬ (C1 ∧ C2) ∨ C3) ∧ C4 = 1;
Step 3.3: Using the combinations C2, C2, C3 previous for Ef1, we get:
1 | 0 | 1 | 1 |
1 | 1 | 1 | 1 |
1 | 0 | 0 | 1 |
0 | 1 | 0 | 1 |
0 | 0 | 0 | 1 |
In addition, the constraint that C2 and C4 should not exist simultaneously:
1 | 0 | 1 | 1 |
1 | 0 | 0 | 1 |
0 | 0 | 0 | 1 |
Add the corresponding values for Ef1 and Ef2:
V1 | 1 | 0 | 1 | 1 | 1 | 1 |
V2 | 1 | 0 | 0 | 0 | 1 | 1 |
V3 | 0 | 0 | 0 | 0 | 1 | 1 |
Step 3.4: No_columns = 5 + 3 = 8 are updated;
Generating Test Cases
Each column in the decision table generates at least one case of testing, corresponding to the respective C1, …, Cp combination.
Note: C1, …, Cp are generally expressions that use variables, etc., so several cases can be selected for combination testing.
Problem: Explosion of states due to the combination of causes.
Solution: Limiting the number of test cases using heuristics.
Conclusion
Cause Effect Graphing is a valuable technique for functional testing that enables software developers to understand the relationships between the inputs and outputs of a system or its component. This technique provides a visual representation of the logical relationships between causes and effects, expressed as a Boolean expression.
More examples of this technique can be seen in this repo.