Understanding The Basic Concept Of Structural Testing
Structural testing is a type of software testing which is performed on the internal structure of the coding. That means, it is performed on the statements, values, and groups of the code. It uses some techniques in order to perform structural testing. It is performed by developers who have knowledge of the particular programming language. Let's understand it in detail.
What is Structural Testing?
Structural Testing is a type of software testing. This testing is used to test the internal design of the software or the structure of the coding for the particular software. Structural testing uses white box testing techniques. The structural testing is concentrated on how the system is doing rather than the functionality of the system. Most of the time structural testing is also referred to as 'White Box Testing' and also as open, transparent, or glass testing based on the code.
The testing phase starts after the development phase. The development team is included in the structural testing. It must be noted that the working of structural testing is different from behavioral testing. Structural testing tests the different features of an application based on its type. Similarly, it tests different aspects of the software based on its types. It is mostly implemented to identify the issues and fix them quickly.
Following are some of the techniques performed in the structural testing with some examples and types of structural testing.
Types of Structural Testing
The following are the types of structural testing:
- Mutation Testing
- Data Flow Testing
- Control flow Testing
- Slice-based Testing
1. Mutation Testing
Mutation testing is structural testing that is performed to design new software tests and also evaluate the quality of tests. It is related to the modification of a program in small ways.
It is a structural testing technique, which uses the structure of the code to guide the testing process. Mutation testing has the following three types:
- Value Mutation
- Decision Mutation
- Statement Mutation
Let us understand this using examples.
Value Mutation: It is mutation testing that changes the values of constants to detect errors. Let us see a simple example to understand it. The following is the initial code snippet:
Initial code for value mutation
int a=10;
int b=20;
int c= a*b;
Now let us change the value of constant,
Changed co for value mutation
int a=5;
int b=20;
int c=a*b;
Value of integer 'a' has been changed to 5 and the output is directed to observe if there exist any errors in the code.
Decision Mutation: It is a type of testing that changes the logical or arithmetic operations to detect any errors. Let us understand this using simple coding snippet.
Initial Code for decision mutation
int a=10;
int b=2;
if(a%2==0)
{
printf("hello")
}
Now the condition statement in the if is changed to see if it raises an error
//Changed Code for decision mutation
int a=10;
int b=2;
if(a/b==0)
{
printf("hello")
}
Statement Mutation: A statement mutation either deletes a statement or replaces the statement to check for errors.
//initial code for statement mutation
int a=10;
int b=5;
int c= a*b;
Now the statement(s) of the code is changed to see if it arises any errors.
//Changed code for statement mutation
int a=10;
int b=5;
float x=a/b;
2. Data Flow Testing
Data Flow testing is structural testing it is used to find the test paths of a program according to the values. It is used to analyze the flow of data in the program. These are mainly concerned with
- Statements where variables receive values,
- Where these values are being used or referenced.
The basic idea behind this testing is to reveal the coding errors, mistakes, and improper usage of data such as whether all the data variables are initialized or not and initialized data is priorly used or not. It is used to fill the gaps between path testing and branch testing.
Let us understand this using an example
**1.**read a,b
**2.**if a>b
**3.** c=a-b
**4.**else
**5.** c=b-a
**6.**print(c)
This is the control flow graph of the above example
So now let us see how we use and define the variables
**Variables Defined at node Used at node**
a 1 2,3,5
b 1 2,3,5
c 3,5 6
3. Control Flow Testing
Control flow testing is a type of software testing technique that uses the control flow technique. It is a form of testing that depicts the execution order of the statements. It is used to develop the test cases of the programs. The tester selects a test case from a large portion of the program to test. The whole test cases are represented in the form of a control flow graph with basic blocks as a node, edge, etc. This consists of various nodes such as entry node, exit node, decision node, junction node. The node holds a statement whereas the edge is used to connect or determine the flow of nodes.
We use the following steps in the control flow testing:
- Control Flow Graph Creation: A graph is created from the source code either manually or using the software.
- Coverage Test: A coverage test is defined over the graph and elements of the graph such as nodes, edges, paths, etc.
- Test Case Creation: A set of test cases are created to cover the coverage target for control flow graphs.
- Test Case Execution: The test cases are executed after the creation of test cases.
- Analysis of results: Analysis of results is the phase where we find out if the program consists of any errors or not.
Cyclomatic Complexity: It is a measure of the number of linearly independent paths. It is a software metric used to describe the complexity of a program
It is calculated using the following formula
M= E-N+2P
where E defines the Edge
N is No of nodes and
P is No. of paths
4. Slice-Based Testing
Slicing or program slicing is a technique used in software testing which takes a slice or a group of program statements in a program. It consists of two types which are as follows:
-
Static Slicing: Static slicing is a group of statements that affects the final result of any variable at any point in time. Let us see an example to understand.
The following is a code snippet in python
n=int(input())
if n==0:
print("It is zero")
elif n<0:
print("Negative value")
else:
print("Positive value")
So the output of the code snippet may change with the change of the value of n
-
Dynamic Slicing: The dynamic slice of a program contains all the statements that actually affect the value of a variable at any point for a particular execution of the program. Let us take the following example.
n=int(input())
if n==0:
print("It is zero")
elif n<0:
print("Negative value")
else:
print("Positive value")
For instance, consider value of n as 10,then the following slice of code will get executed:
n=int(input())
else:
print("Positive value")
Techniques used in Structural Testing
The following are the techniques used in structural testing:
- Statement Coverage
- Branch Coverage
- Path Coverage
Statement Coverage: Statement Coverage is a white box testing technique, which involves the execution of all the statements at least once in the source code. It is a metric used to calculate the number of statements that have been executed. It is also used to check the quality of the code and the flow of different paths.
Statement Coverage can be given by:
Statement Coverage= (No of statements executed/Total no of statements in the source code) * 100
The main drawback of this technique is that we cannot test the false condition to it
Let us see an example:
Read A
if A>0
Print “A is positive”
else
Print “B is negative”
Set 1: If A is 4
Total no of statements in the program: 5
The total no of statements executed : 3
Therefore, Statement Coverage= (3/5)*100=60%
So by this technique for every set of instructions statement coverage is calculated
Branch Coverage: Branch Coverage is a testing method, it aims to ensure that each one of the possible branches from each decision point is executed at least once. That is for each branch two conditions true and false are taken. It helps in validating each and every branch in the program
The branch coverage is calculated as follows:
Branch Testing=(No of decision outcomes tested/ Total no of decision outcomes) * 100%
Let us see an example of this.
Read A
Read B
if A + B > 20 THEN
print "A+B is Larger"
end if
if A>5 THEN
print "A Large"
end if
The following is the flow chart of the above statements
To calculate Branch Coverage, one has to find the minimum number of paths such that all the edges are covered.
In the above, there exists no such path. The aim is to cover all possible true/false decisions.
(1) 1A-2C-3D-E-4G-5H
(2) 1A-2B-E-4F
Hence Branch Coverage is 2.
Path Coverage: Path Coverage is a special kind of structural testing technique that assesses every single line of the program. The testers must look at each line of the code in the module.
Following is the formula for path coverage:
Path Coverage=(Number of paths exercised/Total no of paths in the program) * 100
Following is the example to find the path coverage:
Read A
if A>5 then
return 'Yes'
else
return 'No'
In order to cover all the paths, the x should have values less than 5, greater than 5, or equal to 5. However, this method becomes complicated with more complex modules
Structural Testing Tools
Structural testing contains some open-source and commercial tools that have their functionality. The most common tools are
- Cucumber
- JBehave
- Cfix
- JUnit
Let us know about these a little bit.
- Cucumber: It is the most widely used structural testing tool, it delivers an easily understandable testing script. It is used by test engineers to develop test cases for the system
- JBehave: It is a framework for BDD (Behaviour-driven Development). It is purely executing in Java. In this, we can write the user stories. It allows stories to be executed through an Ant task
- CFix: CFix is an XUnit testing framework supported by the C/C++ programming language. In this tool, the unit tests are compiled and linked into a DLL. It supports the development of both user and kernel mode
- JUnit: It is one of the essential tools of structural testing. It is an open-source unit testing framework, which was in Java language.
Advantages of Structural Testing
- Using structural testing all the early defects can be identified easily.
- It is not a time-consuming process.
- It provides easy coding and implementation.
- Structural testing does not require a lot of manual work as it is an automated process.
- It helps in the elimination of dead code.
- Reveals errors in hidden code.
Disadvantages of Structural Testing
- It is expensive with respect to time and money as one has to spend so much time and money on white box testing.
- In-depth knowledge about the programming language is necessary in order to perform structural testing.
- It requires training in the tools used for testing.
- There is a small chance of missing some statements or commands in the code unintentionally.
Summing Up
From the above, we can conclude the following points:
- Structural Testing is performed on the structure of the code, unlike behavioral testing. Behavioral testing focuses on the functionality of the system.
- It is sometimes referred to as white-box testing as it uses white-box techniques to perform testing.
- The techniques used in the structural testing are Statement coverage, Branch coverage, and path coverage.
- Structural testing has four types of testing which are: Mutation testing, data flow testing, control flow testing, and slicing-based testing.
- The tester should have knowledge of the programming language that is being tested, It does not need any manual testing as it is an automated process.
- The code is thoroughly tested by using testing strategies and the defects are observed at the early stages.
- The structural testing helps in the elimination of the dead code.
- Various open-source testing tools are to test, the following are some of the most common tools are CFix, JBehave, JUnit, Cucumber.
You may also like to read:
Comments
Add commentLogin to continue reading
And access exclusive content, personalized recommendations, and career-boosting opportunities.
Swarnaprabha 11 months ago
Unstop Admin 11 months ago