Understanding Software Faults and Testing
Understanding Software Faults and Testing
5.1.2 Fault
A fault (also called a defect or bug) is the result of an error that appears in the software code or
design. It is an incorrect step, process, or data definition in a computer program. Faults are
caused by human errors but exist within the software itself.
For example, if the programmer writes the statement
total = price * 0.01
instead of
total = price * 1.01
this incorrect formula in the source code is a fault. It does not yet cause visible problems until
the program is executed, but it exists within the software.
5.1.3 Failure
A failure occurs when the software containing a fault is executed and produces an incorrect or
unexpected output.
It is the external behavior of the software that deviates from the expected result.
Continuing the same example, when the program runs and displays the wrong total amount to
the customer, this incorrect result is called a failure.
Example 2:
In a railway ticket booking system, the developer writes wrong logic to calculate the total fare.
● Fault: Incorrect formula in the code (e.g., fare = distance × 5 instead of distance × 10).
● Failure: The user receives an incorrect total fare on the ticket screen.
From these examples, we can understand that faults are the root cause present inside the code,
while failures are the visible symptoms that occur when those faults are executed.
What is Verification?
Verification is the process of checking that software achieves its goal without any bugs. It is the
process to ensure whether the product that is developed is right or not. It verifies whether the
developed product fulfills the requirements that we have. Verification is static
testing. Verification means Are we building the product, right?
What is Validation?
Validation is the process of checking whether the Software Product is up to the mark or in other
words product has high-level requirements. It is the process of checking the validation of the
product i.e. it checks what we are developing is the right product. It is validation of the actual
and expected products. Validation is dynamic testing. Validation means Are we building the right
product?
Verification Validation
Verification refers to the set of Validation refers to the set of activities
activities that ensure software that ensure that the software that has
Definition
correctly implements the specific been built is traceable to customer
function requirements.
It includes checking documents, It includes testing and validating the
Focus
designs, codes, and programs. actual product.
Type of Testing Verification is the Static testing. Validation is Dynamic testing.
It does not include the execution of the
Execution It includes the execution of the code.
code.
Methods used in verification are Methods used in validation are Black
Methods Used reviews, walkthroughs, inspections and Box Testing, White Box
desk-checking. Testing and Non-Functional testing.
It checks whether the software meets
It checks whether the software
Purpose the requirements and expectations of
conforms to specifications or not.
a customer or not.
It can find the Bugs in the early stage of It can only find the bugs that could not
Bug
the development. be found by the verification process.
The goal of verification is application
The goal of validation is an actual
Goal and software architecture and
product.
specification.
Verification is typically performed by
the quality assurance (QA) team, Validation is performed by the testing
focusing on reviewing documents, team, which executes the software in
Responsibility
designs, and code to ensure real environments to ensure it meets
compliance with specified user expectations and requirements.
requirements.
Timing It comes before validation. It comes after verification.
It consists of checking of
Human or It consists of execution of program and
documents/files and is performed by
Computer is performed by computer.
human.
After a valid and completeValidation begins as soon as project
Lifecycle
specification, the verification starts. starts.
Error Focus Verification is for prevention of errors.
Validation is for detection of errors.
Verification is also termed as white boxValidation can be termed as black box
Another
testing or static testing as work product
testing or dynamic testing as work
Terminology
goes through reviews. product is executed.
Verification finds about 50 to 60% of Validation finds about 20 to 30% of the
Performance
the defects. defects.
Validation is based on the fact and is
Verification is based on the opinion of
often stable.
Stability reviewer and may change from person
to person.
● Verification Example: Imagine a team is developing a new mobile banking app. During
the verification phase, they review the requirements and design documents. They check
if all the specified features like fund transfer, account balance check, and transaction
history are included and correctly detailed in the design. They also perform peer reviews
and inspections to ensure the design aligns with the requirements. This step ensures that
the app is being built according to the initial plan and specifications without actually
running the app.
● Validation Example: In the validation phase, the team starts testing the mobile banking
app on actual devices. They check if users can log in, transfer money, and view their
transaction history as intended. Testers perform usability tests to ensure the app is user-
friendly and functional tests to ensure all features work correctly. They might also involve
real users to provide feedback on the app's performance. This phase ensures that the app
works as expected and meets user needs in real-world scenarios.
Differentiating between verification and validation in software testing offers several advantages:
1. Clear Communication: It ensures that team members understand which aspects of the
software development process are focused on checking requirements (verification) and
which are focused on ensuring functionality (validation).
4. Cost Savings: Optimizing resource allocation and focusing efforts on the right testing
activities based on whether they fall under verification or validation helps in managing
costs effectively.
5. Client Satisfaction: Ensuring that software meets or exceeds client and user expectations
by conducting both verification and validation processes rigorously improves overall
software quality and user satisfaction.
White box testing can be done for different purposes. The three main types are:
1. Unit Testing
2. Integration Testing
3. Regression Testing
5.4.3 Comparison of Black Box Testing Vs White Box Testing
Parameters Black Box Testing White Box Testing
Black Box Testing is a way of software
White Box Testing is a way of testing the
testing in which the internal structure or
Definition software in which the tester has
the program or the code is hidden and
knowledge about the internal structure
nothing is known about it.
or the code or the program of the
software.
Black box testing is mainly focused on
White box testing is mainly focused on
Testing testing the functionality of the software,
ensuring that the internal code of the
objectives ensuring that it meets the requirements
software is correct and efficient.
and specifications.
Black box testing uses methods White box testing uses methods
like Equivalence Partitioning, Boundary like Control Flow Testing, Data Flow
Testing methods
Value Analysis, and Error Guessing to Testing and Statement Coverage
create test cases. Testing.
Black box testing does not require any White box testing requires knowledge
knowledge of the internal workings of of programming languages, software
Knowledge level the software, and can be performed by architecture and design patterns.
testers who are not familiar with
programming languages.
Black box testing is generally used for White box testing is used for testing the
Scope testing the software at the functional software at the unit level, integration
level. level and system level.
Implementation of code is not needed Code implementation is necessary for
Implementation
for black box testing. white box testing.
Black Box Testing is mostly done by White Box Testing is mostly done by
Done By
software testers. software developers.
Black Box Testing can be referred to as White Box Testing is the inner or the
Terminology
outer or external software testing. internal software testing.
Black Box Testing is a functional test of White Box Testing is a structural test of
Testing Level
the software. the software.
Black Box testing can be initiated based
Testing White Box testing of software is started
on the requirement specifications
Initiation after a detail design document.
document.
No knowledge of programming is It is mandatory to have knowledge of
Programming
required. programming.
Black Box Testing is the behavior testing White Box Testing is the logic testing of
Testing Focus
of the software. the software.
White Box Testing is generally
Black Box Testing is applicable to the
Applicability applicable to the lower levels of
higher levels of testing of software.
software testing.
Alternative Black Box Testing is also called closed White Box Testing is also called as clear
Names testing. box testing.
Time Black Box Testing is least time White Box Testing is most time
Consumption consuming. consuming.
Suitable for
Black Box Testing is not suitable or White Box Testing is suitable for
Algorithm
preferred for algorithm testing. algorithm testing.
Testing
Data domains along with inner or
Can be done by trial-and-error ways and
Approach internal boundaries can be better
methods.
tested.
Search something on google by using
Example By input to check and verify loops
keywords
It is less exhaustive as compared to It is comparatively more exhaustive
Exhaustiveness
white box testing. than black box testing.
5.5 WHITE BOX TEST COVERAGE – CODE COVERAGE, CONDITION COVERAGE, BRANCH
COVERAGE
Code Coverage is a metric used in Software Testing that quantifies the extent to which the source
code of a program is tested. It measures the percentage of code executed by the test suite,
helping developers identify untested parts of an application.
As we know at last of the development each client wants a quality software product as well and
the developer team is also responsible for delivering a quality software product to the
customer/client. Where this quality refers to the product’s performance, functionalities,
behavior, correctness, reliability, effectiveness, security, and maintainability. Where Code
Coverage metric helps in determining the performance and quality aspects of any software. The
formula to calculate code coverage is
Code Coverage = (Number of lines of code executed) / (Total Number of lines of code in a system
component) * 100
The number of statements that have been successfully executed in the program source code.
The number of decision control structures that have been successfully executed in the program
source code.
3. Function coverage
The number of functions that are called and executed at least once in the source code.
Understanding the different types of code coverage helps in ensuring comprehensive testing of
your software. Here are the main types:
Types of code coverage
1. Statement Coverage
● Definition: Measures whether each line of code is executed.
● Purpose: Ensures that all code statements are tested at least once.
● Example: If a function has ten lines of code, statement coverage ensures each line is
executed during testing.
2. Branch Coverage (Decision Coverage)
● Definition: Measures whether each possible branch (true/false) from each decision point
is executed.
● Purpose: Ensures that all branches of control structures (like if-else statements) are
tested.
● Example: If a program has an if-else statement, both the if and the else branches should
be tested.
3. Function Coverage
● Definition: Measures whether each function or subroutine in the code is called.
● Purpose: Ensures that all functions in the code are invoked during testing.
● Example: In a class with multiple methods, function coverage ensures each method is
called at least once.
4. Condition Coverage (Predicate Coverage)
● Definition: Measures whether each Boolean sub-expression is evaluated to both true and
false.
● Purpose: Ensures that each condition in a decision has been tested for both true and false
outcomes.
● Example: In a compound condition like if (A && B), both A and B should be tested for true
and false values.
5. Path Coverage
● Definition: Measures whether all possible paths through the code are executed.
● Purpose: Ensures that all possible execution paths are tested.
● Example: For a function with multiple nested loops and conditionals, path coverage
would ensure all possible execution routes are tested.
6. Line Coverage
● Definition: Measures the number of executed lines divided by the total number of lines.
● Purpose: Provides a straightforward metric of how much of the codebase is executed.
● Example: If a file has 100 lines and 80 lines are executed during testing, line coverage
would be 80%.
7. Loop Coverage
● Definition: Measures whether loops are executed and how many times.
● Purpose: Ensures that loops are tested with zero, one, and multiple iterations.
● Example: For a loop that processes items in a list, loop coverage ensures the loop is tested
with an empty list, a single-item list, and a multiple-item list.
Each type of code coverage focuses on different aspects of the code, helping to ensure thorough
testing and improving overall software quality.
[Link] Tools for Code Coverage
Below are a few important code coverage tools
● JaCoCo
● Cobertura
● Emma
● Clover
● Codecov
● Coveralls
● Istanbul
● SonarQube
● NCover
● BullseyeCoverage
● Visual Studio Code Coverage
● dotCover
● OpenCover
● gcov
● Testwell CTC++
[Link] Advantages of Using Code Coverage
● It helps in determining the performance and quality aspects of any software.
● It helps in evaluating quantitative measures of code coverage.
● It helps in the easy maintenance of the code base.
● It helps in accessing the quality of the test suite and analyzing how comprehensively a
software is verified.
● It helps in the exposure of bad, dead, and unused code.
● It helps in creating extra test cases to increase coverage.
● It helps in developing the software product faster by increasing its productivity and
efficiency.
● It helps in measuring the efficiency of test implementation.
● It helps in finding new test cases that are uncovered.
[Link] Disadvantages of Using Code Coverage
● Sometimes it fails to cover code completely and correctly.
● It cannot guarantee that all possible values of a feature are tested with the help of code
coverage.
● It fails to ensure how perfectly the code has been covered.
● For some test files, additional mock data is required to execute the test cases.
● Sometimes it is difficult to cover the test cases handling functions.
● Lot of test cases are required to increase the test coverages for complex code.
● A developer must have strong knowledge of writing unit test cases to cover all possible
scenarios in the developed code.
5.5.2 CONDITION COVERAGE
The software condition coverage can be calculated by dividing the total count of conditions
executed with the total count of conditions in the source code, and then multiplied by hundred.
Condition Coverage = (Total count of conditions executed / Total count of conditions in the
source code) * 100
The software condition coverage testing is required to ensure that the program source code is
working properly, and is able to satisfy the given requirements. It is observed that the traditional
testing methodologies sometimes miss particular paths in the code, thereby some of the critical
defects remain undetected. The software condition coverage testing takes care of these
situations by methodically verifying all the conditions inside the decision points. Thus it improves
the overall quality, and performance of the software.
The software condition coverage testing are performed by following the steps listed below −
Step 1 − Determine the decision points or conditional statements in the program source code like
the if, else if, if, switch etc.
Step 2 − Every decision point may consist of more than one condition. These conditions are
evaluated, and split into simpler modules to have an exhaustive testing.
Step 3 − Design test cases to include every possible result of all the conditions namely true, and
false. It helps to cover every branch of code at the time of testing.
Step 4 − Execute the white box test cases, and evaluate the results. A coverage report is
generated to measure the extent of verification of the conditions. It also describes the validated,
and invalidated conditions, thereby it gives an idea if more fine tuning of the test cases are
needed.
The advantages of the software condition coverage testing are listed below −
● The software condition coverage testing guarantees that all the conditions in the code are
checked at least once.
● The software condition coverage testing detects defects from the early stages of the
software development life cycle(SDLC).
● The condition coverage testing improves the quality, maintainability, and reliability of the
software.
● The software condition coverage testing helps in faster troubleshooting of errors in the
code.
● The condition coverage testing gives higher confidence, and trust on the code developed
for the software.
[Link] Example
Let us take an example of the below code snippet to determine the count of the condition
coverage.
Input X, Y, Z, and W
IF (X == 0 || Y == 0)
ELSE IF (Z == 0 && W == 0)
END IF
END
Let us now calculate the condition coverage with the first test case, with the inputs X = 0, Y = 0,
Z = 0, W = 0. With these values, the first condition of the OR operator with the expression X == 0,
holds true. Since the result of the left side of the OR is already true, so the right side of the
expression, Y == 0 of it, will be skipped from evaluation.
So, the condition Y == 0 remained unchecked. Then, the statement 3 will be executed resulting
in printing 100 and the condition IF (Z == 0 && W == 0) in the ELSE part(at the line 4) will not be
executed. Hence, out of a total four conditions, only one of them got executed. The total
condition coverage as per formula:
Condition Coverage = (Total count of conditions executed / Total count of conditions in the
source code) * 100
Let us now calculate the condition coverage with the second test case, with the inputs X = 1, Y =
0, Z = 0, W = 0. With these values, the first condition having the OR operator with the expression
X == 1, holds false. As the result of the left side of the OR is false, so the right side expression Y
== 0 of it, will be evaluated. So this time, the condition Y == 0 is checked. Then, the statement 3
will be executed resulting in printing 100 and the condition IF (Z == 0 && W == 0) in the ELSE
part(at the line 4) will remain unchecked. Hence, out of a total four conditions, two of them got
executed. The total condition coverage as per formula
Condition Coverage = (Total count of conditions executed / Total count of conditions in the
source code) * 100
Let us now calculate the condition coverage with the third test case, with the inputs X = 1, Y = 1,
Z = 0, W = 0. With these values, the first condition having the OR operator with the expression X
== 1, holds false. As the left side of the OR is false, so the right side expression Y == 1 of it, will be
evaluated. Since both sides of the OR operator result in false, so this time, the condition IF (Z ==
0 && W == 0) in the ELSE part(at the line 4) will be executed.
The first condition having the AND operator with the expression Z == 0, holds true. Though the
left side of the AND operator is true, the right side expression W == 0 will also need to be
evaluated. Since both of them are true, then, the statement 5 will be executed resulting in
printing 200. Hence, out of total four conditions, four of them got executed this time. The total
condition coverage as per formula
Condition Coverage = (Total count of conditions executed / Total count of conditions in the source
code) * 100
[Link] Conclusion
This concludes our comprehensive take on the tutorial on Software Condition Coverage Testing.
Weve started with describing what is software condition coverage testing, formula to calculate
the software condition coverage percentage, why is software condition coverage testing
required, how is software condition coverage testing performed, what are the advantages of
software condition coverage testing, and an example to obtain the software condition coverage
percentage. This equips you with in-depth knowledge of Software Condition Coverage Testing. It
is wise to keep practicing what you’ve learned and exploring others relevant to Software Testing
to deepen your understanding and expand your horizons.
Branch coverage in unit testing is a metric that measures the percentage of branches (decision
points) in the source code that have been executed during the testing process. It indicates how
well the test cases navigate through different possible outcomes of conditional statements,
helping evaluate the thoroughness of testing. A high branch coverage means that most decision
paths in the code have been tested, increasing the likelihood of detecting potential defects.
1. Achieving comprehensive branch coverage is important for ensuring the reliability and
effectiveness of unit tests in identifying and addressing code issues.
2. This metric helps identify areas of code that may not have been adequately tested,
increasing the likelihood of detecting potential defects and enhancing the overall
reliability and quality of the software.
The main purpose of the Branch Coverage in Unit testing is that the test cases should cover each
branch statement inside the coding block or functions block. It is also known as decision
coverage.
1. Comprehensive Test Coverage: The primary purpose of Branch Coverage in unit testing
is to ensure test coverage by targeting each branch statement within code blocks or
functions. This is also known as decision coverage. It aims to verify that every possible
branch, including conditional and unconditional statements, has been executed at least
once during testing.
4. Execution of Branch Test Cases: Branch Coverage involves the execution of test cases
specifically designed for branch statements. These test cases are executed, and the
results are analyzed to ensure that each branch has been exercised.
5. Execution with Mock Data: To enhance test scenarios, Branch Coverage may utilize mock
data or additional data sets when executing branch test cases. This ensures a more
thorough examination of the code's decision paths.
Branch Coverage Metrics serve to gauge the effectiveness of test coverage by measuring how
many branches or decision logics within the source code are covered. Typically expressed as a
percentage, the branch coverage percentage is a key indicator of testing thoroughness. The
evaluation formula is automated within testing software, where, for example, covering 7 out of
10 branch statements results in coverage of (7/10) * 100, yielding 70%. This indicates that 3
branch statements remain uncovered.
1. 70-80% Coverage: If the coverage falls between 70% and 80%, it's acceptable, but
improvements may be needed for overall coverage. This range is often flagged in yellow,
signaling a cautionary status.
2. Above 80% Coverage: Achieving coverage above 80% is considered efficient, and it is
typically highlighted in green, indicating a robust test coverage.
3. Below 70% Coverage: If coverage is below 70%, it is not recommended, and efforts
should be made to increase coverage. This is usually highlighted in red, signaling
inadequate test coverage that requires attention.
Consider the following simple function that determines whether a person is eligible to vote based
on their age. The function has two conditional statements (if and else) and one unconditional
print statement. Branch coverage in unit testing for this function aims to cover all possible
branches, including both conditional and unconditional statements.
checkAge(int age) {
print("Eligible to Vote")
else
1. Test Case 1 (True Positive): Create a test case to cover the if condition by providing an
age greater than or equal to 18. This scenario represents a True Positive, where the
individual is eligible to vote. This test case covers the if part of the function.
2. Test Case 2 (False Positive): Generate a test case to cover the other condition by
providing an age less than 18. This represents a False Positive scenario, where the
individual is not eligible to vote. This test case covers the other part of the function.
3. Test Case 3 (Print Statement): Design a test case to cover the print statement by
providing mock data for age and verifying that the age is printed correctly. This test case
ensures coverage of the common print statement executed in the function.
There are many tools used for branch coverages. Let's see some of the tools.
2. JCov: An open-source testing tool tailored for the Java programming language, JCov
facilitates testing and analysis of code coverage. It allows developers to gain visibility into
the branches covered by their unit tests in Java applications.
3. JaCoCo: Another open-source code coverage testing tool, JaCoCo, is widely used for both
Kotlin and Java programming environments. It provides detailed insights into code
coverage, including branch coverage, to ensure comprehensive testing.
4. CoCo: This testing tool is utilized to analyze code coverage for the C programming
language. Unlike some others, CoCo is not an open-source tool but serves the purpose of
assessing coverage in C code.
5. Coverlet: An open-source tool designed for the .NET framework, Coverlet enables the
analysis of various coverage metrics, including branch coverage. It is particularly useful
for assessing the thoroughness of unit tests in .NET applications.
[Link] Advantages of Using Branch Coverage
1. Efficiency: Branch coverage provides an efficient metric for assessing how thoroughly unit
tests have explored different decision paths within the code. It ensures that various
branches, including conditional and unconditional statements, are executed, contributing
to a more comprehensive test suite.
2. Knowledge Gaining: Writing test cases for branch coverage requires a deep
understanding of the code, promoting knowledge acquisition. This learning process
enhances developers' familiarity with the codebase and its decision logic.
1. Requires Learning: Utilizing branch coverage in unit testing demands coding knowledge
to write effective test cases. This could pose a challenge, particularly for beginners or
individuals with limited programming experience.
2. Additional Mock Data Needed: In some cases, creating mock data becomes necessary to
execute test cases effectively. This may lead to the addition of dummy files or data in the
source code folder, potentially impacting the cleanliness of the codebase.
3. Uncovered Branches: Despite efforts, it may be challenging to cover all branches in the
code. Certain branches, especially those involving complex logic or exceptional scenarios,
might remain uncovered, limiting the overall effectiveness of branch coverage.
Continuous refinement of test cases is essential to address such challenges.
Note : Short Hint for white box test coverage – code coverage, condition coverage, branch
coverage
1. Code Coverage (Statement Coverage)
Definition:
Code coverage measures the percentage of executable statements in the code that have been
executed by the test cases.
Formula:
Code Coverage = (Number of lines of code executed)/(Total Number of lines of code in a system
component) * 100
Example:
if (a > 5)
b = b + 1;
c = c + 1;
● Test Case 1: a = 6
→ Executes both statements → 100% coverage
● Test Case 2: a = 4
→ Skips b = b + 1; → only 1 of 2 statements executed → 50% coverage
Statement Coverage ensures all code lines are executed at least once.
3. Condition Coverage
Definition:
Condition Coverage checks that each Boolean sub-expression in a decision has been evaluated
both True and False, at least once.
Condition Coverage (%) = (Number of executed conditions / Total number of conditions) * 100
Example:
if (A > 5 && B < 10)
printf("Valid");
To achieve Condition Coverage, you need:
Test Case A>5 B<10 Output
1 T T Valid
2 F T Not valid
3 T F Not valid
Each condition (A>5, B<10) is True and False at least once.
Condition Coverage is stronger than Branch Coverage because it tests each part of the condition
separately.
Comparison Summary
Coverage Type Focus Ensures Example
Code/Statement
Every executable statement Each line executed once Covers all lines
Coverage
Branch Coverage Decision outcomes True/False of each branch Covers all if/else
Each condition tested for
Condition Coverage Boolean expressions Covers each sub-condition
T/F
In equivalence partitioning, equivalence classes are evaluated for given input conditions.
Whenever any input is given, then type of input condition is checked, then for this input
conditions, Equivalence class represents or describes set of valid or invalid states.
5.6.1 Guidelines for Equivalence Partitioning:
● If the range condition is given as an input, then one valid and two invalid equivalence
classes are defined.
If input is a Range
→ Create 1 Valid class, 2 Invalid classes
Example: 1–10
o Valid: 1–10
o Invalid: <1
o Invalid: >10
● If a specific value is given as input, then one valid and two invalid equivalence classes are
defined.
If input requires a Specific Value
→ Create 1 Valid, 2 Invalid classes
Example: Value must be exactly 5
o Valid: 5
o Invalid: <5
o Invalid: >5
● If a member of set is given as an input, then one valid and one invalid equivalence class is
defined.
If input is from a Set / List
→ 1 Valid, 1 Invalid class
● Valid: Any member of the set
● Invalid: Any value not in the set
● If Boolean no. is given as an input condition, then one valid and one invalid equivalence
class is defined.
If input is Boolean (True/False)
→ 1 Valid, 1 Invalid class
● Valid: True or False
● Invalid: Any other input (e.g., “yes”, 1, null)
[Link]-1:
Let us consider an example of any college admission process. There is a college that gives
admissions to students based upon their percentage.
Consider percentage field that will accept percentage only between 50 to 90 %, more and even
less than not be accepted, and application will redirect user to an error page. If percentage
entered by user is less than 50 %or more than 90 %, that equivalence partitioning method will
show an invalid percentage. If percentage entered is between 50 to 90 %, then equivalence
partitioning method will show valid percentage.
5.6.3. Example 2:
Let us consider an example of an online shopping site. In this site, each of products has a specific
product ID and product name. We can search for product either by using name of product or by
product ID. Here, we consider search field that accepts only valid product ID or product name.
Let us consider a set of products with product IDs and users wants to search for Mobiles. Below
is a table of some products with their product Id.
Product Product ID
Mobiles 45
Laptops 54
Pen Drives 67
Keyboard 76
Headphones 34
If the product ID entered by user is invalid then application will redirect customer or user to error
page. If product ID entered by user is valid i.e. 45 for mobile, then equivalence partitioning
method will show a valid product ID.
[Link]-3:
Let us consider an example of software application. There is function of software application that
accepts only particular number of digits, not even greater or less than that particular number.
Consider an OTP number that contains only 6-digit number, greater and even less than six digits
will not be accepted, and the application will redirect customer or user to error page. If password
entered by user is less or more than six characters, that equivalence partitioning method will
show an invalid OTP. If password entered is exactly six characters, then equivalence partitioning
method will show valid OTP.
5.7 BOUNDARY VALUE ANALYSIS
Functional testing is a type of software testing in which the system is tested against the functional
requirements of the system. It is conducted to ensure that the requirements are properly
satisfied by the application. Functional testing verifies that each function of the software
application works in conformance with the requirement and specification. Boundary Value
Analysis (BVA) is one of the functional testings.
5.7.1 Boundary Value Analysis
Boundary Value Analysis is based on testing the boundary values of valid and invalid partitions.
The behavior at the edge of the equivalence partition is more likely to be incorrect than the
behavior within the partition, so boundaries are an area where testing is likely to yield defects.
It checks for the input values near the boundary that have a higher chance of error. Every
partition has its maximum and minimum values and these maximum and minimum values are
the boundary values of a partition.
In simple terms boundary value Analysis is like testing the edge cases of our software where most
of the time it will get broke so it is important to do BVA before deploying the code. There are
many other test that are done if you wish to learn them all then you can join our complete
software testing course
Note:
● A boundary value for a valid partition is a valid boundary value.
● A boundary value for an invalid partition is an invalid boundary value.
● For each variable we check-
o Minimum value.
o Just above the minimum.
o Nominal Value.
o Just below Max value.
o Max value.
Valid Test cases: Valid test cases for the above can be any value entered greater than 17 and less
than 57.
● Enter the value- 18.
● Enter the value- 19.
● Enter the value- 37.
● Enter the value- 55.
● Enter the value- 56.
Invalid Testcases: When any value less than 18 and greater than 56 is entered.
● Enter the value- 17.
● Enter the value- 57.
5.7.2 Single Fault Assumption: When more than one variable for the same application is checked
then one can use a single fault assumption. Holding all but one variable to the extreme value and
allowing the remaining variable to take the extreme value.
For n variable to be checked:
Maximum of 4n+1 test cases
Taking Day as Single Fault Assumption i.e. Day will be having values varying from 1 to 31 and
others will have nominal values.
Taking Month as Single Fault Assumption i.e. Month will be having values varying from 1 to 12
and others will have nominal values.
4 × 3 + 1 =13
The focus of BVA: BVA focuses on the input variable of the function. Let's define two variables
X1 and X2, where X1 lies between a and b and X2 lies between c and d.
The idea and motivation behind BVA are that errors tend to occur near the extremes of the
variables. The defect on the boundary value can be the result of countless possibilities.
5.7.3 Typing of Languages: BVA is not suitable for free-form languages such as COBOL and
FORTRAN, These languages are known as weakly typed languages. This can be useful and can
cause bugs also.
PASCAL, ADA is the strongly typed language that requires all constants or variables defined with
an associated data type.
5.7.4 Limitation of Boundary Value Analysis:
● It works well when the product is under test.
● It cannot consider the nature of the functional dependencies of variables.
● BVA is quite rudimentary.
5.7.5 Equivalence Partitioning
It is a type of black-box testing that can be applied to all levels of software testing . In this
technique, input data are divided into the equivalent partitions that can be used to derive test
cases-
● In this input data are divided into different equivalence data classes.
● It is applied when there is a range of input values.
Example: Below is the example to combine Equivalence Partitioning and Boundary Value.
Consider a field that accepts a minimum of 6 characters and a maximum of 10 characters. Then
the partition of the test cases ranges 0 - 5, 6 - 10, 11 - 14.
Test Scenario Test Description Expected Outcome
1 Enter value 0 to 5 character Not accepted
2 Enter 6 to 10 character Accepted
3 Enter 11 to 14 character Not Accepted
Boundary Value Analysis (BVA) focuses on testing at the boundaries between partitions, while
Equivalence Partitioning (EP) divides input data into equivalent classes to reduce test cases. Both
methods aim to minimize test efforts while maximizing coverage.
Below are some of the differences between BVA and Equivalence Partitioning.
Purpose:
● To confirm that the implemented system meets functional requirements.
● To validate real user interactions with the system.
● To test both main and alternate paths of use cases.
Process:
1. Identify use cases from the Software Requirement Specification (SRS) or UML diagrams.
2. Develop test cases for each scenario and flow (main, alternate, and exceptional).
3. Execute these test cases and record actual outcomes.
4. Compare the results with expected behavior.
5. Document findings for analysis.
Example:
In an Online Shopping System, the use case includes viewing items, selecting products, adding
them to the cart, and making a purchase. The customer then proceeds to checkout, where
payment is made through services such as credit cards or PayPal. Alternate paths could include
“User not authenticated,” “Payment failed,” or “Item out of stock.”
[Link]
A Use Case defines how a user (actor) interacts with the system to achieve a particular goal.
Each use case describes a specific functionality or service that the system provides to its users.
In this Online Shopping System, use cases describe how different types of customers (new,
registered, or web customers) perform activities such as viewing items, registering, making
purchases, and checking out.
Purpose:
● To identify the functional behavior of the system.
● To make sure all user interactions are properly understood and tested.
2. Use Case Model
A Use Case Model shows the interaction between actors and the system using diagrams and
descriptions.
It includes all use cases, actors, and their relationships.
Actors:
1. Web Customer – The main actor who uses the online shopping website.
2. New Customer – A customer who needs to register before purchasing.
3. Registered Customer – A user who already has an account.
4. Authentication Service – Verifies the user’s identity before allowing access.
5. Identity Provider – Manages login and identity details.
6. Credit Payment Service – Handles credit/debit card payments.
7. PayPal – Processes payments through PayPal gateway.
System Boundary:
Subsystem – “Online Shopping”
Everything inside this boundary belongs to the system; actors outside the box interact
with it.
Use Cases (Inside the System):
1. View Items – Allows customers to browse available products.
2. Client Register – Lets new customers create an account.
3. Make Purchase – Handles the process of selecting and buying items.
4. Checkout – Confirms the order and processes the payment.
Relationships:
1. Include Relationship:
a. Make Purchase → includes → View Items and Checkout
(Because purchasing an item always involves viewing and checking out.)
2. Generalization Relationship:
a. New Customer and Registered Customer → both extend Web Customer.
3. Associations:
a. Lines between actors and use cases represent direct interactions.
3. Functional Requirements
Functional requirements define what the system should do based on the use cases.
From the diagram, the main functional requirements are:
1. The system shall allow new customers to register and create accounts.
2. The system shall allow registered customers to log in using authentication services.
3. The system shall allow users to view available items in the online store.
4. The system shall allow users to make purchases by adding items and checking out.
5. The system shall integrate with external payment services like Credit Payment and
PayPal.
6. The system shall validate payments and confirm orders upon successful transaction.
6. Summary
● The Use Case Diagram provides a complete view of the system’s interactions.
● It helps in understanding, designing, and testing functional behavior.
● Each use case connects to functional requirements that specify what the system must
do.
● Parameters define how each use case can be tested step by step.
Advantages:
● Ensures user requirements are met accurately.
● Covers end-to-end system functionality.
● Helps detect missing workflows or logic errors early.
2. PERFORMANCE TESTING
Objective: To measure how well the system performs in terms of response time, throughput,
and resource utilization under various conditions.
Key Aspects:
● Response Time: Time taken by the system to respond to a request.
● Throughput: Number of transactions or requests processed in a given time period.
● Concurrency: Number of simultaneous users or processes the system can handle.
● Resource Utilization: CPU, memory, disk, and network usage during operation.
Approach:
1. Identify Performance Metrics: Determine the performance metrics you need to
measure, such as response time, throughput, or latency.
2. Create Performance Test Cases: Design test cases that include typical and peak load
scenarios.
3. Execute Tests: Use performance testing tools to simulate different loads and measure
system performance.
4. Monitor and Measure: Monitor system performance metrics during the tests and
record the results.
5. Analyze Results: Compare the results against the performance requirements or
benchmarks to assess if the system meets the expected performance criteria.
Tools: Apache JMeter, LoadRunner, NeoLoad, Performance Center.
3. EFFICIENCY TESTING
Objective: To evaluate how effectively the system uses resources, including its capacity to
perform tasks with minimal overhead.
Key Aspects:
● Resource Usage: Assess how efficiently the system uses CPU, memory, and other
resources.
● Response Time vs. Resource Utilization: Evaluate how changes in resource usage affect
response time and overall performance.
● Scalability: Test how efficiently the system scales with increased load or data volume.
Approach:
1. Define Efficiency Metrics: Identify key metrics for efficiency, such as resource usage per
transaction or operation.
2. Set Baselines: Establish performance baselines for resource usage under normal
operating conditions.
3. Conduct Tests: Run tests to observe how efficiently the system performs tasks under
varying loads.
4. Optimize: Identify any inefficiencies or bottlenecks and make recommendations for
optimization based on test results.
5. Validate Improvements: Re-test the system after optimization to ensure that efficiency
improvements are effective.
Tools: Profilers (e.g., VisualVM, YourKit), APM tools (e.g., New Relic, Dynatrace).
5.13 UNIT TESTING, INTEGRATION TESTING, SYSTEM TESTING AND ACCEPTANCE TESTING.
Software Testing is an important part of the Software Development Life Cycle which is help to
verify the product is working as expected or not. In SDLC, we used different levels of testing to
find bugs and errors. Here we are learning those Levels of Testing in detail.
Table of Content
● What Are the Levels of Software Testing?
● 1. Unit Testing
● 2. Integration Testing
● 3. System testing
● 4. Acceptance Testing
What Are the Levels of Software Testing?
Software Testing is essential to verify an application is working properly or not. To achieve this,
testing can be done through various stages of development from each component to all
system. Those "stages", called Levels of Testing, help to make sure all components of system
are working properly.
Learn more: Software Development Life Cycle
Likely Levels of Testing divided into four main levels, which are as follows:
Levels of Testing
1. Unit Testing
Unit Testing is the first step in testing your software. It focuses on checking individual
components or functions of the application to make sure they work correctly on their own. The
goal here is to catch any issues early before those small components are integrated with the rest
of the system.
Unit tests help developers spot bugs early in the development process, making it easier and
quicker to fix them. It's the first layer of defense to verify that each part of the application
performs as expected.
Mainly features are:
● Testing individual functions or components.
● Ensuring correct behavior at the smallest level.
● Catching errors early.
2. Integration Testing
After unit testing, Integration Testing takes over. This level checks how different modules or
components of the software work together. It's important because even if individual parts work
perfectly, they might face issues when interacting with one another.
Integration testing ensures that data flows correctly between modules and that they
communicate seamlessly. It helps catch problems that might arise when different parts of the
system interact.
3. System testing
System Testing is when you test the software as a system. This stage checks whether the entire
system functions as expected in a real-world environment. It includes both functional and non-
functional tests to ensure that the software meets customer needs.
● Full end-to-end testing of the software.
● Verifying both functional and non-functional requirements.
● Testing the software's behavior in real-world conditions.
4. Acceptance Testing
Acceptance Testing, also known as User Acceptance Testing (UAT), is the final test before
releasing the software to the end-users. In this phase, the customer or end-users verify if the
software meets their needs and expectations.
UAT is crucial because it verify the software is ready for production. It’s the last chance to catch
any overlooked issues before deployment. If the software passes this stage, the customer gives
the green light for release.
● Validating the software against business requirements.
● Ensuring the software meets customer expectations.
● Getting final approval from the customer.
Testing Principles
While performing the software testing, following Testing Principles must be applied by every
software engineer:
1. The requirements of customers should be traceable and identified by all different tests.
2. Planning of tests that how tests will be conducted should be done long before the
beginning of the test.
3. The Pareto principle can be applied to software testing- 80% of all errors identified during
testing will likely be traceable to 20% of all program modules.
4. Testing should begin “in the small” and progress toward testing “in the large”.
5. Exhaustive testing which simply means to test all the possible combinations of data is not
possible.
6. Testing conducted should be most effective and for this purpose, an independent third
party is required.
In these multiple tests are written for a single function to cover different possible scenarios and
these are called test cases. While it is ideal to cover all expected behaviors, it is not always
necessary to test every scenario.
Unit tests should run one by one, it means that they do not depend on other system parts like
databases or networks. Instead, data stubs can be used to simulate these dependencies.
Writing unit tests is easiest for simple, self-contained code blocks.
Types of Unit Testing
Unit testing can be performed manually or automatically:
1. Manual unit testing
Manual Testing is like checking each part of a project by hand, without using any special tools.
People, like developers, do each step of the testing themselves. But manual unit testing isn't
used much because there are better ways to do it and it has some problems:
● It costs more because workers have to be paid for the time they spend testing,
especially if they're not permanent staff.
● It takes a lot of time because tests have to be done every time the code changes.
● It is hard to find and fix problems because it is tricky to test each part separately.
● Developers often do manual testing themselves to see if their code works correctly.
Types of Unit Testing
2. Automated unit testing
Automation Unit Testing is a way of checking if software works correctly without needing lots of
human effort. We use special tools made by people to run these tests automatically. These are
part of the process of building the software. Here's how it works:
● Developers write a small piece of code to test a function in the software. This code is
like a little experiment to see if everything works as it should.
● Before the software is finished and sent out to users, these test codes are taken out.
They're only there to make sure everything is working properly during development.
● Automated testing can help us check each part of the software on its own. This helps us
find out if one part depends too much on another. It's like putting each piece of a puzzle
under a magnifying glass to see if they fit together just right.
● We usually use special tools or frameworks to do this testing automatically. These tools
can tell us if any of our code doesn't pass the tests we set up.
● The tests we write should be really small and focus on one specific thing at a time. They
should also run on the computer's memory and not need internet connection.
So, automated unit testing is like having a helper that checks our work as we build software,
making sure everything is in its right place and works as expected.
Workflow of Unit Testing
The unit testing workflow includes the following step-by-step process:
Workflow of Unit Testing
System Testing
System Testing Process
System Testing is performed in the following steps:
● Test Environment Setup: Create testing environment for the better-quality testing.
● Create Test Case: Generate test case for the testing process.
● Create Test Data: Generate the data that is to be tested.
● Execute Test Case: After the generation of the test case and the test data, test cases are
executed.
● Defect Reporting: Defects in the system are detected.
● Regression Testing: It is carried out to test the side effects of the testing process.
● Log Defects: Defects are fixed in this step.
● Retest: If the test is not successful then again test is performed.
Acceptance Testing is the last phase of software testing performed after System Testing and
before making the system available for actual use.
Test coverage impacts the performance and security of a software product by ensuring that all parts of the software are exercised during testing, which can identify potential bottlenecks and vulnerabilities. Comprehensive test coverage involves metrics like code coverage, branch coverage, and condition coverage, which help identify untested parts of the application that could degrade performance or be exploited by security threats. By ensuring that all code paths, decision outcomes, and conditions are thoroughly tested, developers can detect and rectify performance issues and security vulnerabilities early. This not only enhances the application's efficiency but also fortifies its security posture, ultimately leading to a more robust and reliable product .
Different types of code coverage such as statement coverage, branch coverage, and condition coverage contribute to software reliability and quality assurance by ensuring comprehensive testing of the software. Statement coverage measures whether each line of code is executed, ensuring that all code statements are tested at least once, which helps identify unexecuted parts of the code. Branch coverage verifies that each possible branch from decision points (like if-else statements) is executed, improving the thoroughness of testing by ensuring all different possible paths are checked. Condition coverage checks that all Boolean expressions in the code have been tested both true and false, which can uncover potential logical errors that branch coverage alone may miss. Together, these types of coverage help in identifying untested code paths and logical errors, enhancing the software's performance, reliability, and quality .
Condition coverage and branch coverage differ in their testing approach by the level of granularity they provide when testing conditions in the code. Branch coverage, also known as decision coverage, ensures that each possible branch (true/false outcome) from decision points has been executed. This helps with thorough examination of control structures to catch potential defects. However, it doesn't guarantee that all logical conditions in those branches are tested. On the other hand, condition coverage requires every individual Boolean expression in a decision point to be evaluated both true and false, which can uncover errors that branch coverage might miss. While branch coverage focuses on executing paths, condition coverage focuses on logical correctness, often leading to higher fault detection and improving software quality .
System testing complements unit and integration testing by verifying that the entire system functions as expected in a real-world environment, after individual components and module interactions have been tested. Unit testing ensures that individual application components perform correctly, while integration testing checks that these components work together properly. System testing goes a step further by validating the entire system against functional and non-functional requirements, such as performance and security, which are not fully covered by unit or integration tests. This holistic approach helps detect errors that may not be visible when testing components individually, ensuring that the software satisfies the end-user requirements, meets business needs, and functions well under realistic conditions .
Acceptance testing is crucial in the software testing life cycle because it is the final step before the product is released to the end-users. It ensures that the software meets the user's needs and expectations according to business requirements. The key roles of acceptance testing include validating the software against business requirements, ensuring that the system is ready for deployment by identifying any remaining issues, and gaining user approval before releasing the product. This testing phase helps prevent the release of a product that does not meet customer standards, thereby reducing risks and increasing user satisfaction .
It is essential for developers to have a deep understanding of code when utilizing branch coverage in testing because it requires thorough insight into the logic and control flow of the code to ensure comprehensive test cases that exercise all decision branches. This understanding is necessary to create effective test scenarios that cover every possible path through the code, which is crucial for identifying defects that could go unnoticed with superficial testing. A lack of deep understanding may lead to inadequate test cases that fail to test certain branches, leaving parts of the code unverified and potentially defect-prone. Additionally, a profound comprehension of the codebase promotes knowledge acquisition, enabling developers to write more precise tests and improve code quality .
The main types of functional testing in system testing include functional requirement validation, regression testing, and usability testing. Functional requirement validation checks if all features work as expected and meet defined requirements. This ensures the software functionality aligns with what users need. Regression testing is performed to confirm that new code or changes don't negatively impact existing functionality. This prevents the introduction of defects into the already tested parts of the system. Usability testing evaluates how user-friendly and accessible the software is, ensuring it provides a satisfactory user experience. Together, these functional tests verify the software against its intended purpose and improve its overall quality by ensuring each function meets the requirements and that the system operates smoothly in real conditions .
A well-defined test plan and early testing influence the effectiveness of system testing by establishing a clear roadmap that outlines the scope, objectives, resources, and schedule for testing activities, thus ensuring comprehensive coverage and resource allocation. Early testing enables the detection and resolution of defects sooner in the development cycle, which reduces the amount of rework needed and mitigates the risk of defects propagating into later stages. Together, they streamline the testing process, increase efficiency, and improve communication between development and testing teams, ultimately leading to more reliable system testing outcomes and a higher quality product .
Achieving high branch coverage in unit testing presents challenges such as the need for a comprehensive understanding of the code to create effective test cases, which can be difficult for beginners or those with limited programming experience. Additionally, creating mock data might be necessary, possibly leading to clutter in the codebase with dummy files. Despite efforts, certain complex or exceptional branches might remain uncovered, limiting the effectiveness of branch coverage. These challenges necessitate continuous refinement of test cases to improve coverage and address uncovered branches, which can be resource-intensive and time-consuming .