0% found this document useful (0 votes)
8 views38 pages

EXPERIMENT

The document outlines six experiments focused on testing techniques for determining the maximum of three numbers and classifying triangles based on user input. Each experiment employs different testing methods, including Boundary Value Analysis, Robust Approach, Worst Value Analysis, Robust Worst Case Testing, Equivalence Class Testing, and Decision Table Testing, to generate test cases and validate program functionality. The source code for each experiment is provided along with conclusions summarizing the testing performed.

Uploaded by

Parth Sarthi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views38 pages

EXPERIMENT

The document outlines six experiments focused on testing techniques for determining the maximum of three numbers and classifying triangles based on user input. Each experiment employs different testing methods, including Boundary Value Analysis, Robust Approach, Worst Value Analysis, Robust Worst Case Testing, Equivalence Class Testing, and Decision Table Testing, to generate test cases and validate program functionality. The source code for each experiment is provided along with conclusions summarizing the testing performed.

Uploaded by

Parth Sarthi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 38

EXPERIMENT-1

AIM: Write a program to find the maximum in three numbers input by the user and generate
test cases for the program using Boundary Value Analysis.
THEORY
Boundary Value Analysis (BVA) is a testing technique that focuses on testing the edges of
input ranges. Errors often occur at these boundaries, so BVA involves checking values just
below, at, and just above each boundary point (e.g., min-1, min, min+1; max-1, max, max+1).
This method helps catch edge-case issues efficiently.
SOURCE CODE
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<vector<long int>> range(3,vector<long int>(0,0));
for(int i=1;i<=3;i++)
{
cout<<"Enter Min Range of Variable "<<i<<" :"<<endl;
long int minV, maxV, nom;
cin>>minV;
range[i-1].push_back(minV);
range[i-1].push_back(minV+1);
cout<<"Enter Max Range of Variable "<<i<<" :"<<endl;
cin>>maxV;
nom=minV+ (maxV-minV)/2;
range[i-1].push_back(nom);
range[i-1].push_back(maxV-1);
range[i-1].push_back(maxV);
}
cout<<endl<<"TC X Y Z Expected O/P"<<endl; for(int
i=0;i<5;i++)
cout<<i+1<<" "<<range[0][i]<<"
"<<range[1][2]<<" "<<range[2][2]<<"
"<<max(max(range[0][i],range[1][2]),range[2][2])<<endl
; for(int i=0,count=6;i<5;i++)
if(i!=2)
cout<<count++<<" "<<range[0][2]<<"
"<<range[1][i]<<" "<<range[2][2]<<"
"<<max(max(range[0][2],range[1][i]),range[2][2])<<endl
; for(int i=0,count=10;i<5;i++)
if(i!=2)
cout<<count++<<" "<<range[0][2]<<"
"<<range[1][2]<<" "<<range[2][i]<<"
"<<max(max(range[0][2],range[1][2]),range[2][i])<<endl
; return 0;
}

OUTPUT

CONCLUSION
The Boundary Value Analysis was performed by generating Test cases based on the
ranges of the values entered by the user.
EXPERIMENT-2
AIM: Write a program to find the maximum in three numbers input by the user and generate
test cases for the program using Robust Approach.
THEORY
The robust approach in testing expands Boundary Value Analysis (BVA) by including not
only valid boundary values but also invalid or out-of-bound values (e.g., values slightly
below the minimum or above the maximum). This method tests how the system handles
unexpected inputs, aiming for more thorough error detection and improved reliability.
SOURCE CODE
#include<iostream>
#include<vector>
using namespace std;
void Robust(vector<vector<long int> >& range)
{
cout<<"\n\n\t ROBUST CASE TESTING\n";
cout<<endl<<"TC\tX\tY\tZ\tExpected
Output\n"<<endl; for(int i=0;i<7;i++)
cout<<i+1<<"\t"<<range[0][i]<<"\t"<<range[1][2]<<"\t"<<rang
e[
2][2]<<"\t\t"<<max(max(range[0][i],range[1][2]),range[2][2]
)< <endl;
for(int i=0,count=8;i<7;i++)
if(i!=2)
cout<<count++<<"\t"<<range[0][2]<<"\t"<<range[1][i]<<"\t"<<
ra
nge[2][2]<<"\t\t"<<max(max(range[0][2],range[1][i]),range[2
][ 2])<<endl;
for(int i=0,count=14;i<7;i++)
if(i!=2)
cout<<count++<<"\t"<<range[0][2]<<"\t"<<range[1][2]<<"\t"<<
ra
nge[2][i]<<"\t\t"<<max(max(range[0][2],range[1][2]),range[2
][ i])<<endl;
}
int main()
{
int n=3;
vector< vector<long int> >
range2(n,vector<long int>(0,0)); // for Robust
for(int i=1;i<=3;i++)
{
cout<<"Enter Min Range of Variable "<<i<<"
:"; long int minV, maxV, nom;
cin>>minV;
range2[i-1].push_back(minV-1);
range2[i-1].push_back(minV);
range2[i-1].push_back(minV+1);
cout<<"Enter Max Range of Variable "<<i<<"
:"; cin>>maxV;
nom=minV+ (maxV-minV)/2;
range2[i-1].push_back(nom);
range2[i-1].push_back(maxV-1);
range2[i-1].push_back(maxV);
range2[i-1].push_back(maxV+1);
}
int x,y,z;
cout<<"\nEnter the three variables:";
cin>>x>>y>>z;
cout<<"The max is: "<<max(max(x,y),z)<<endl;
Robust(range2);
return 0;
}
OUTPUT
CONCLUSION
Robustness Testing was performed by generating Test cases based on the ranges of the values
entered by the user.
EXPERIMENT-3
AIM: Write a program to find the maximum in three number input by the user and generate
test cases for the program using Worst Value Analysis.
THEORY:
Worst Boundary Value Analysis (WBVA) tests all combinations of minimum and maximum
boundary values across multiple inputs simultaneously. It’s used to capture complex edge
cases involving interactions between boundaries of different inputs, providing thorough test
coverage.
SOURCE CODE
#include<iostream>
#include<vector>
using namespace std;
void Worst(vector<vector<long int> >& range)
{
cout<<"\n\n\t WORST CASE TESTING\n";
cout<<endl<<"TC\t\tX\t\tY\t\tZ\tExpected
Output\n"<<endl;
int count=1;
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
for(int k=0;k<5;k++)
{
cout<<count++<<"\t\t"<<range[0][i]<<"\t\t"<<range[1][j]
<<"\t\
t"<<range[2][k]<<"\t\t"<<max(max(range[0][i],range[1][j
]),ran ge[2][k])<<endl;
}
}
}
}
int main()
{
int n=3;
vector< vector<long int> >
range(n,vector<long int>(0,0)); // for BVA
for(int i=1;i<=3;i++)
{
cout<<"Enter Min Range of Variable
"<<i<<" :"; long int minV, maxV, nom;
cin>>minV;
range[i-1].push_back(minV);
range[i-1].push_back(minV+1);
cout<<"Enter Max Range of Variable
"<<i<<" :"; cin>>maxV;
nom=minV+ (maxV-minV)/2;
range[i-1].push_back(nom);
range[i-1].push_back(maxV-1);
range[i-1].push_back(maxV);
}
cout<<"Input the 3 variables:";
int x,y,z;
cin>>x>>y>>z;
cout<<"Maximum of the 3
is:"<<max(x,max(y,z))<<endl; Worst(range);
return 0;
}

OUTPUT
CONCLUSION:
Worst Case Testing was performed by generating Test cases based on the ranges of the values
entered by the user.
EXPERIMENT-4
AIM: Write a program to generate test cases for Robust Worst Case Testing.
THEORY:
Robust Worst Case testing combines Worst Boundary Value Analysis with the robust
approach. It tests all combinations of valid boundary values (minimum, maximum) and out-
of-bound values for multiple inputs simultaneously. This approach covers extreme edge
cases, checking how the system handles both boundary interactions and invalid inputs,
offering maximum coverage.

SOURCE CODE
#include<iostream>
#include<vector>
using namespace std;
void Worst(vector<vector<long int> >& range)
{
cout<<"\n\n\t WORST CASE TESTING\n";
cout<<endl<<"TC\t\tX\t\tY\t\tZ\tExpected
Output\n"<<endl;
int count=1;
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
for(int k=0;k<5;k++)
{
cout<<count++<<"\t\t"<<range[0][i]<<"\t\t"<<range[1][j]<<"\
t\t"<<rang
e[2][k]<<"\t\t"<<max(max(range[0][i],range[1][j]),range[2][
k])<<endl; }
}
}
}
int main()
{
int n=3;
vector< vector<long int> > range(n,vector<long
int>(0,0)); // for BVA
for(int i=1;i<=3;i++)
{
cout<<"Enter Min Range of Variable "<<i<<" :";
long int minV, maxV, nom;
cin>>minV;
range[i-1].push_back(minV);
range[i-1].push_back(minV+1);
cout<<"Enter Max Range of Variable "<<i<<" :";
cin>>maxV;
nom=minV+ (maxV-minV)/2;
range[i-1].push_back(nom);
range[i-1].push_back(maxV-1);
range[i-1].push_back(maxV);
}
cout<<"Input the 3 variables:";
int x,y,z;
cin>>x>>y>>z;
cout<<"Maximum of the 3
is:"<<max(x,max(y,z))<<endl; Worst(range);
return 0;}

OUTPUT
CONCLUSION
Robust Worst Case Testing was performed by generating Test cases based on the ranges of
the values entered by the user
EXPERIMENT-5

AIM: write the program to find the type of the triangle on the basis of the side input by the
user and generate test cases to test a program using equivalence class testing.

THEORY:

Equivalence Class Testing is a software testing technique that involves dividing all possible
inputs into distinct groups, or equivalence classes, where each group is expected to produce
the same behaviour. These classes are categorized into valid (inputs that meet the system’s
requirements) and invalid (inputs that violate the requirements). Instead of testing all possible
inputs, a representative value is chosen from each class to test the system's behaviour, thereby
reducing the number of test cases while ensuring comprehensive coverage. This method
enhances efficiency by focusing on testing only one input from each class, assuming all other
values within the class will behave similarly.

SOURCE CODE
#include <iostream>
#include <string>

using namespace std;

string classifyTriangle(int a, int b, int c) {


if (a + b <= c || a + c <= b || b + c <= a || a <= 0 || b <= 0 || c <= 0) {
return "Invalid triangle";
} else if (a == b && b == c) {
return "Equilateral triangle";
} else if (a == b || b == c || a == c) {
return "Isosceles triangle";
} else {
return "Scalene triangle";
}

void generateTestCases(int range) {

if (range < 1) {
cout << "Range must be greater than 0." << endl;
return;
}

cout << "Generated Test Cases:" << endl;

int a = range, b = range, c = range;


cout << "Equilateral: classifyTriangle(" << a << ", " << b << ", " << c << ") = "
<< classifyTriangle(a, b, c) << endl;

a = range; b = range; c = range - 1;


cout << "Isosceles: classifyTriangle(" << a << ", " << b << ", " << c << ") = "
<< classifyTriangle(a, b, c) << endl;

a = range - 2; b = range - 1; c = range;


cout << "Scalene: classifyTriangle(" << a << ", " << b << ", " << c << ") = "
<< classifyTriangle(a, b, c) << endl;

a = 1; b = 2; c = range + 1; // Ensures a + b <= c for invalid case


cout << "Invalid: classifyTriangle(" << a << ", " << b << ", " << c << ") = "
<< classifyTriangle(a, b, c) << endl;
}

int main() {
int range;
cout << "Enter the range for side lengths: ";
cin >> range;

generateTestCases(range);

return 0;
}

OUTPUT

CONCLUSION
Equivalence Class Testing was performed by generating test cases based on the
ranges of the values entered by the user
EXPERIMENT-6
AIM: Write a program to generate test cases (for types of triangle) using Decision Table
Testing.

THEORY:
An output may be dependent on many input conditions and decision tables give a
pictorial view of various combinations of input conditions. There are four portions of the
decision table the decision table provides a set of conditions and their corresponding
actions.
The four parts of the decision table are given as:
1. Condition Stubs
All the conditions are represented in this upper left section of the decision table.
These conditions are used to determine a particular action or set of actions.
2. Condition Entries
In the condition entries portion of the decision table, we have a number of
columns and each column represent a rule. Values entered in this upper right
portion of the table are known as inputs.
3. Action Stubs
All possible actions are listed in this lower left portion of the decision table.
4. Action Entries
Each entry in the action entries portion has some associated action or set of
actions in this lower right portion of the table. These values are known as outputs
and are dependent upon the functionality of the program.

SOURCE CODE
#include <iostream>
#include<vector>
using namespace std;
vector<vector<int> >sides(7,vector<int>(3,0));
int a, b, c;
string result(int a, int b, int c, vector<vector<int>
>arr) { string ans = "Not a Triangle";
if (a < arr[0][0] || a > arr[0][1] || b < arr[1][0] ||
b > arr[1][1] || c < arr[2][0] || c > arr[2][1]) {
ans = "Input values are out of range";
}
else if (a < b + c && b < a + c && c < a +
b) { if (a == b && b == c) {
ans = "Equilateral Triangle";
}
else if (a == b || b == c || a == c) {
ans = "Isosceles Triangle";
}
else {
ans = "Scalene Triangle";
}
}
return ans;
}
string Build_DT() {
cout<<"\nDECISION TABLE FOR TRIANGLE CLASSIFICATION
PROBLEM"<<endl;
string str = "
--------------------------------------------------------------
--\n"; str = str + " Decisions | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10| 11|\n";
str = str + "
--------------------------------------------------------------
--\n"; str = str + " C1: a < b + c? | F | T | T | T | T | T |
T | T | T | T | T |\n";
str = str + " C2: b < a + c? | - | F | T | T | T | T | T | T
| T | T | T |\n";
str = str + " C3: c < a + b? | - | - | F | T | T | T | T | T
| T | T | T |\n";
str = str + " C4: a = b ? | - | - | - | T | F | T | F | T | T
| F | F |\n";
str = str + " C5: a = c ? | - | - | - | T | F | F | T | T | F
| T | F |\n";
str = str + " C6: b = c ? | - | - | - | T | T | F | F | F | T
| T | F |\n";
str = str + "
--------------------------------------------------------------
--\n"; str = str + " Rule count |32 |16 | 8 | 1 | 1 | 1 | 1 |
1 | 1 | 1 | 1 |\n";
str = str + "
----------------------------------------------------------------
\n";
str = str + " A1: Not a triangle | X | X | X | | | | | | |
| |\n";
str = str + " A2: Scalene | | | | | | | | | | | X |\n";
str = str + " A3: Isosceles | | | | | X | X | X | | | |
|\n";
str = str + " A4: Equilateral | | | | X | | | | | | | |\n";
str = str + " A5: Impossible | | | | | | | | X | X | X |
|\n";
return str;
}
int not_triangle(int ind, vector<vector<int> >arr) {
a = arr[0][1];
b = arr[1][2];
c = arr[2][2];
while (a < (b + c)) {
b = b / 2;
c = c / 2;
}
sides[0][0] = a;
sides[0][1] = b;
sides[0][2] = c;
ind++;
a = arr[0][2];
b = arr[1][1];
c = arr[2][2];
while (b < (a + c)) {
a = a / 2;
c = c / 2;
}
sides[1][0] = a;
sides[1][1] = b;
sides[1][2] = c;
ind++;
a = arr[0][2];
b = arr[1][2];
c = arr[2][1];
while (c < (a + b)) {
a = a / 2;
b = b / 2;
}
sides[2][0] = a;
sides[2][1] = b;
sides[2][2] = c;
ind++;
return ind;
}
int Equilateral(int ind, vector<vector<int>
>arr) { a = arr[0][3];
b = arr[1][3];
c = arr[2][3];
int min_max = arr[0][0], max_min = arr[0][1],
nominal_val; for (int i = 0; i < 3; i++) {
if (min_max > arr[i][0])
min_max = arr[i][0];
if (max_min > arr[i][1])
max_min = arr[i][1];
}
nominal_val = (min_max + max_min) / 2;
sides[ind][0] = nominal_val;
sides[ind][1] = nominal_val;
sides[ind][2] = nominal_val;
ind++;
return ind;
}
int Isosceles(int ind, vector<vector<int>
>arr) { a = arr[0][3];
b = arr[1][3];
c = arr[2][3];
int min_max = arr[0][0], max_min = arr[0][1],
nominal_val; for (int i = 0; i < 3; i++) {
if (min_max > arr[i][0])
min_max = arr[i][0];
if (max_min > arr[i][1])
max_min = arr[i][1];
}
nominal_val = (min_max + max_min) / 2;
sides[ind][0] = arr[0][0];
sides[ind][1] = nominal_val;
sides[ind][2] = nominal_val;
ind++;
sides[ind][0] = nominal_val;
sides[ind][1] = arr[1][0];
sides[ind][2] = nominal_val;
ind++;
sides[ind][0] = nominal_val;
sides[ind][1] = nominal_val;
sides[ind][2] = arr[2][0];
ind++;
return ind;
}
int impossible(int ind) {
for (int i = 0; i < 3; i++) {
cout << ind + i << "\t?\t?\t?\tImpossible" << endl;
}
ind = ind + 3;
return ind;
}
int main() {
vector<vector<int> >arr(3,vector<int>(3,0));
cout<< "Enter the sides of the Triangle:"<<endl;
for (int i = 0; i < 3; i++) {
cout<<"Enter min and max values of side "<<i + 1<<": ";
cin>>arr[i][0]>>arr[i][1];
arr[i][2] = (arr[i][0] + arr[i][1]) / 2;
arr[i][3] = arr[i][1] - arr[i][0];
}
cout << Build_DT() << endl;
cout<<"DECISION TABLE - TEST CASES"<<endl;
cout << "S.No\ta\tb\tc\tExpected Output" <<
endl; int ind = 0;
ind = not_triangle(ind, arr);
ind = Equilateral(ind, arr);
ind = Isosceles(ind, arr);
ind = 1;
for (int i = 0; i < 7; i++) {
a = sides[i][0];
b = sides[i][1];
c = sides[i][2];
cout << ind << "\t" << a << "\t" << b << "\t" << c << "\t" <<
result(a, b, c, arr) << endl;
ind++;
}
ind = impossible(ind);
cout << ind << "\t" << arr[0][1] - 1 << "\t" << arr[1][2] <<
"\t" << arr[2][2] + 2 << "\t" << result(arr[0][1] - 1,
arr[1][2], arr[2][2] + 2, arr) << endl;
return 0;
}

OUTPUT
CONCLUSION
Decision Table Testing for Triangle Classification Program was successfully implemented.
EXPERIMENT-7
AIM: Write a program to find Cyclomatic complexity of a program (triangle classification).

THEORY:

Cyclomatic Complexity is the number of independent paths through a


program. To calculate cyclomatic complexity.
(V(G) = e – n + 2P
where V(G) = Cyclomatic complexity
G: program graph
n: number of nodes
e: number of edges
P: number of connected components

SOURCE CODE:

#include<iostream>
#include<string>
using namespace std;
int main()
{
string str=
"#include<stdio.h>;\n#include<conio.h>;\n#include<math.h>;\n1.
void main() //Main Begins\n2. {\n3. double a,b,c;\n4. double
a1,a2,a3;\n5. int valid=0;\n6. clrscr();\n7. printf(&quot;Enter
first side of the triangle:&quot;); /*Enter the sides of
Triangle*/\n8. scanf(&quot;%lf&quot;,&amp;a);\n9.
printf(&quot;Enter second side of the triangle:&quot;);\n10.
scanf(&quot;%lf&quot;,&amp;b);\n11. printf(&quot;Enter third
side of the triangle:&quot;);\n12.
scanf(&quot;%lf&quot;,&amp;c);\n/*Checks whether a triangle is
valid or not*/\n13.
if(a&gt;0&amp;&amp;a&lt;=100&amp;&amp;b&gt;0&amp;&amp;b&lt;=100&
amp;& amp;c&gt;0&amp;&am
p;c&lt;=100) {\n14.
if((a+b)&gt;c&amp;&amp;(b+c)&gt;a&amp;&amp;(c+a)&gt;b) {\n15.
valid=1;\n16. }\n17. else {\n18. valid=-1;\n19. }\n20. }\n21.
if(valid==1) {\n22. a1=(a*a+b*b)/(c*c);\n23.
a2=(b*b+c*c)/(a*a);\n24. a3=(c*c+a*a)/(b*b);\n25.
if(a1&lt;1||a2&lt;1||a3&lt;1) {\n26. printf(&quot;Obtuse angled
triangle&quot;);\n27. }\n28. else if(a1==1||a2==1||a3==1) {\n29.
printf(&quot;Right angled triangle&quot;);\n30. }\n31. else
{\n32. printf(&quot;Acute angled triangle&quot;);\n33. }\n34.
}\n35. else if(valid==-1) {\n36. printf(&quot;\nInvalid
Triangle&quot;);\n37. }\n38. else {\n39. printf(&quot;\nInput
Values are Out of Range&quot;);\n40. }\n41. getch();\n42. }
//Main Ends";
int e=0;
int p=1;
int n=0;
for(int i=0;i<str.length()-1;i++)
{
if(str[i]=='\n')
{ e++;
n++;
continue;
}
string check="";
check+=str[i];
check+=str[i+1];
if(check=="if")
e++;
}
e--;
cout<<endl<<str<<endl<<"----------------------------------------
----- -----------------\nCyclomatic Complexity
is:"<<(e-n)+2*p<<endl; return 0;
}

OUTPUT:
CONCLUSION:
Cyclomatic complexity program for Triangle Classification Program was successfully
implemented.
EXPERIMENT-8
AIM:
Write a program to input graph matrix and perform DD path testing(triangle
classification).

THEORY:

The Decision to Decision (DD) path graph is an extension of a program graph. It is


widely known as DD path graph. When we enter into the first node of the sequence, we
can exit only from the last node of that sequence. In DD path graph, such nodes which
are in a sequence are combined into a block and are represented by a single node. Hence,
the DD path graph is a directed graph in which nodes are sequences of statements and
edges are control flow amongst the nodes. All programs have an entry and an exit and the
corresponding program graph has a source node and a destination node. Similarly, the
DD path graph also has a source node and a destination node.

SOURCE CODE:
#include<iostream>
#include<vector>
#include<string>
using namespace std;

class Edge {
public:
int wt; // Weight of the edge (not used in this specific case, but defined)
int v; // Destination vertex
Edge(int nb, int w) { // Constructor for Edge class
v = nb;
wt = w;
}
};

// Function to perform DFS and print all paths from source to destination
void dfs_printPaths(vector<vector<Edge*>>& graph, int src, vector<bool>& vis, int
endNode, int& count, string path) {
// If the source is the destination, print the current path
if (src == endNode) {
path += " -> " + to_string(endNode);
cout << "Path " << count++ << ": " << path << endl;
return;
}

vis[src] = true; // Mark the current node as visited


for (Edge* e : graph[src]) {
if (!vis[e->v]) {
// Explore the next node recursively
dfs_printPaths(graph, e->v, vis, endNode, count, path + " -> " + to_string(src));
}
}
vis[src] = false;
}

void display_graph(vector<vector<Edge*>>& graph) {


int n = graph.size();
cout << "\nGraph in Edge Representation is:\n";
for (int i = 0; i < n; i++) {
cout << "Vertex " << i << " -> ";
for (Edge* e : graph[i]) {
cout << "(" << e->v << ", " << e->wt << "), ";
}
cout << endl;
}
}

// Main function
int main() {
cout << "\n-------------------------------------------------------------\n";
cout << "\t\tDD Path Testing\n";
cout << "\n-------------------------------------------------------------\n";

cout << "Enter the number of Decision nodes (Size of Matrix): ";
int n;
cin >> n;

cout << "Please input the graph matrix (adjacency matrix):\n";


vector<vector<int>> mat(n, vector<int>(n, 0));

// Input the adjacency matrix representing the graph


for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> mat[i][j];
}
}

vector<vector<Edge*>> graph(n, vector<Edge*>());

int e = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (mat[i][j] == 1) { // There is an edge from i to j
graph[i].push_back(new Edge(j, 1)); // Add edge to adjacency list
e++; // Increment the edge count
}
}
}

// Display the graph


display_graph(graph);

int P = 1; // The number of connected components (assumed to be 1 for simplicity)


int complexity = e - n + 2 * P; // Cyclomatic Complexity formula

// Print Cyclomatic Complexity


cout << "\nCyclomatic Complexity is: " << complexity << endl;

// Print paths from node 0 to node 4 (example)


vector<bool> vis(n, false); // Visited array to track visited nodes
int count = 1; // Path counter
cout << "\nPaths from node 0 to node 4 are:\n";
dfs_printPaths(graph, 0, vis, 4, count, "");

return 0;
}
INPUT:
42
01000000000000000000000000000000000000
00000010000000000000000000000000000000
00000000000100000000000000000000000000
00000000000000001000000000000000000000
00000000000000000000010000000000000000
00000000000000000000000000100000000000
00000000000000000000000000000001000000
00000000000000000000000000000000000010
00000000000000000000000000000000000000
00010000000000000000000000000000000000
00000000100000000000000000000000000000
00000000000001000000000000000000000000
00000000000000000010000000000000000000
00000000000000000000000100000010000000
00000000000000000000000000001010000000
00000000000000000000000000000000010000
00000000000000000000000000000000000000
00010000000000000000000000000000000000
000001000000000000000000000000
00000000000000000010000000000000000000
00000000000000000000000100000000000000
00000000000000000000000000001000000000
00000000000000000000000000000000010000
00000000100000000000000000000000000000
10000000000000000000000000000000000000
00000100000000000000000000000000000000
00000000001000000000000000000000000000
00000000000000010100000000000000000000
00000000000000000000100000000000000000
00000000000000000000000000000001000000
00000000000000000000000000000010100000
00000000000000000000000000000000000100
00000000000000000000000000000000000000
00000100000000000000000000000000000000
00000001000000000000000000000000000000
00000000000010000000000000000000000000
00000000000000000100000000000000000000
00000000000000000000000000001000000000
00000000000000000000000000010100000000
00000000000000000000000000000000100000
00000000000000000000000000000000000000
00100000000000000000000000000000000000
00001000000000000000000000000000000000
00000000010000000000000000000000000000
00000000000000100000000000000000000000
00000000000000000001000000000000000000
000000000000000000000000

OUTPUT:
OUTPUT:
DD path testing for Triangle Classification Program was successfully implemented.
EXPERIMENT-9
AIM: Write a program to perform an experiment on Mutation Testing.

THEORY:

Mutation testing is a popular technique to assess the effectiveness of a test suite. We may
have a large number of test cases for any program. We neither have time nor resources to
execute all of them. We may select a few test cases using any testing technique and
prepare a test suite. Mutation testing may help us to assess the effectiveness of a test suite
and may also enhance the test suite, if it is not adequate for a program.
The process of changing a program is known as mutation. This change may be limited to
one, two or very few changes in the program. We prepare a copy of the program under
test and make a change in a statement of the program. This changed version of the
program is known as a mutant of the original program. The behaviour of the mutant may
be different from the original program due to the introduction of a change.
The total number of mutants is equal to the number of killed mutants plus the number of
live mutants. The mutation score measures how sensitive the program is to the changes
and how accurate the test suite is. A mutation score is always between 0 and 1. A higher
value of mutation score indicates the effectiveness of the test suite although effectiveness
also depends on the types of faults that the mutation operators are designed to represent.
The purpose of mutation testing is not only to assess the capability of a test suite but also
to enhance the test suite.

SOURCE CODE:

#include<iostream>
#include<vector>
using namespace std;

int killed = 0;

// Correct function (original code)


int correct(vector<int> testCase) {
int A = testCase[0];
int B = testCase[1];
int C = testCase[2];

if (A > B)
if (A > C)
return A;
else
return C;
else
if (C > B)
return C;
else
return B;

return 0;
}

// Mutant 1: Changes the operator from '>' to '<' in the first comparison
int M1_Code(vector<int> testCase) {
int A = testCase[0];
int B = testCase[1];
int C = testCase[2];

if (A < B) // Changed from 'A > B' to 'A < B'


if (A > C)
return A;
else
return C;
else
if (C > B)
return C;
else
return B;

return 0;
}

// Mutant 2: Changes the comparison condition from 'A > B' to 'A > (B + C)'
int M2_Code(vector<int> testCase) {
int A = testCase[0];
int B = testCase[1];
int C = testCase[2];

if (A > (B + C)) // Changed from 'A > B' to 'A > (B + C)'
if (A > C)
return A;
else
return C;
else
if (C > B)
return C;
else
return B;

return 0;
}

// Mutant 3: Changes the comparison from 'A > B' to 'A < C'
int M3_Code(vector<int> testCase) {
int A = testCase[0];
int B = testCase[1];
int C = testCase[2];

if (A > B)
if (A < C) // Changed from 'A > C' to 'A < C'
return A;
else
return C;
else
if (C > B)
return C;
else
return B;

return 0;
}

// Mutant 4: Changes the comparison condition 'C > B' to 'C = B' (logical error)
int M4_Code(vector<int> testCase) {
int A = testCase[0];
int B = testCase[1];
int C = testCase[2];

if (A > B)
if (A > C)
return A;
else
return C;
else
if (C = B) // Changed from 'C > B' to 'C = B' (logical mistake)
return C;
else
return B;

return 0;
}

// Mutant 5: Returns B instead of the correct value when C > B


int M5_Code(vector<int> testCase) {
int A = testCase[0];
int B = testCase[1];
int C = testCase[2];

if (A > B)
if (A > C)
return A;
else
return C;
else
if (C > B)
return B; // Incorrect: should return C instead of B
else
return B;

return 0;
}

// Function to test Mutant 1


void M1(vector<vector<int>> testCases) {
cout << endl << "---------------------------------------------------\n";
cout << "Mutant 1" << endl;
cout << "\t\tA\tB\tC\tExpected\tActual" << endl;
bool flag = false;
for (int i = 0; i < testCases.size(); i++) {
cout << "Test Case " << i + 1 << " \t"
<< testCases[i][0] << "\t" << testCases[i][1] << "\t" << testCases[i][2] << "\t"
<< correct(testCases[i]) << "\t\t" << M1_Code(testCases[i]) << endl;
if (correct(testCases[i]) != M1_Code(testCases[i]) && flag == false) {
killed++;
flag = true;
}
}
if (flag)
cout << endl << "Mutant Killed";
else
cout << endl << "Mutant not Killed";
}

// Function to test Mutant 2


void M2(vector<vector<int>> testCases) {
cout << endl << "---------------------------------------------------\n";
cout << "Mutant 2" << endl;
cout << "\t\tA\tB\tC\tExpected\tActual" << endl;
bool flag = false;
for (int i = 0; i < testCases.size(); i++) {
cout << "Test Case " << i + 1 << " \t"
<< testCases[i][0] << "\t" << testCases[i][1] << "\t" << testCases[i][2] << "\t"
<< correct(testCases[i]) << "\t\t" << M2_Code(testCases[i]) << endl;
if (correct(testCases[i]) != M2_Code(testCases[i]) && flag == false) {
killed++;
flag = true;
}
}
if (flag)
cout << endl << "Mutant Killed";
else
cout << endl << "Mutant not Killed";
}

// Function to test Mutant 3


void M3(vector<vector<int>> testCases) {
cout << endl << "---------------------------------------------------\n";
cout << "Mutant 3" << endl;
cout << "\t\tA\tB\tC\tExpected\tActual" << endl;
bool flag = false;
for (int i = 0; i < testCases.size(); i++) {
cout << "Test Case " << i + 1 << " \t"
<< testCases[i][0] << "\t" << testCases[i][1] << "\t" << testCases[i][2] << "\t"
<< correct(testCases[i]) << "\t\t" << M3_Code(testCases[i]) << endl;
if (correct(testCases[i]) != M3_Code(testCases[i]) && flag == false) {
killed++;
flag = true;
}
}
if (flag)
cout << endl << "Mutant Killed";
else
cout << endl << "Mutant not Killed";
}

// Function to test Mutant 4


void M4(vector<vector<int>> testCases) {
cout << endl << "---------------------------------------------------\n";
cout << "Mutant 4" << endl;
cout << "\t\tA\tB\tC\tExpected\tActual" << endl;
bool flag = false;
for (int i = 0; i < testCases.size(); i++) {
cout << "Test Case " << i + 1 << " \t"
<< testCases[i][0] << "\t" << testCases[i][1] << "\t" << testCases[i][2] << "\t"
<< correct(testCases[i]) << "\t\t" << M4_Code(testCases[i]) << endl;
if (correct(testCases[i]) != M4_Code(testCases[i]) && flag == false) {
killed++;
flag = true;
}
}
if (flag)
cout << endl << "Mutant Killed";
else
cout << endl << "Mutant not Killed";
}

// Function to test Mutant 5


void M5(vector<vector<int>> testCases) {
cout << endl << "---------------------------------------------------\n";
cout << "Mutant 5" << endl;
cout << "\t\tA\tB\tC\tExpected\tActual" << endl;
bool flag = false;
for (int i = 0; i < testCases.size(); i++) {
cout << "Test Case " << i + 1 << " \t"
<< testCases[i][0] << "\t" << testCases[i][1] << "\t" << testCases[i][2] << "\t"
<< correct(testCases[i]) << "\t\t" << M5_Code(testCases[i]) << endl;
if (correct(testCases[i]) != M5_Code(testCases[i]) && flag == false) {
killed++;
flag = true;
}
}
if (flag)
cout << endl << "Mutant Killed";
else
cout << endl << "Mutant not Killed";
}

int main() {
cout << endl << "---------------------------------------------------\n";
cout << "MUTATION TESTING" << endl;
cout << "Enter number of test cases: ";
int N;
cin >> N;

vector<vector<int>> testCases(N, vector<int>(3, 0));

for (int i = 0; i < N; i++) {


cout << "Enter test case " << i + 1 << " : ";
cin >> testCases[i][0] >> testCases[i][1] >> testCases[i][2];
}

M1(testCases);
M2(testCases);
M3(testCases);
M4(testCases);
M5(testCases);
cout << endl << "---------------------------------------------------\n";
cout << "MUTATION SCORE" << endl;
cout << "Total Mutants: 5" << endl;
cout << "Mutants Killed: " << killed << endl;
cout << "Mutation Score: " << killed / 5.0 << endl;

return 0;
}

INPUT:

OUTPUT:
CONCLUSION

Mutation Testing for Largest of 3 Numbers Program was successfully done

You might also like