ST Quiz 1 Notes
ST Quiz 1 Notes
21F3001823
Software Testing October 18, 2024
1 Introduction
1.1 Motivation
• Introduction to Software Testing by Paul Ammann and Jeff Offutt, The Art of Software Testing by
Glenford J. Myers, Software Testing: A Craftsman’s Approach by Paul C. Jorgensen, Agile Testing:
A practical guide for Testers and Agile Teams by Lisa Crispin and Janet Gregory.
• Software is ubiquitous; Such software should be of very high quality, offer good performance in terms of
response time, performance and also have no errors.
• It is no longer feasible to shut down a malfunctioning system in order to restore safety.
• Errors in software can cost lives, huge financial losses, or simply a lot of irritation.
• Testing is the predominantly used technique to find and eliminate errors in software.
• Planning: Includes clearly identifying customer and/or market needs, pursuing a feasibility study and
arriving at an initial set of requirements.
• Requirements definition: Includes documenting detailed requirements of various kinds: System-level,
functional, software, hardware, quality requirements etc. They get approved by appropriate stakeholders.
• Requirements analysis: Includes checking and analyzing requirements to ensure that they are consistent,
complete and match the feasibility study and market needs.
• Design: Identifies all the modules of the software product, details out the internals of each module, the
implementation details and a skeleton of the testing details.
• Architecture: Defines the modules, their connections and other dependencies, the hardware, database and
its access etc.
• Development: The design documents, especially that of low-level design, is used to implement the product.
There are usually coding guidelines to be followed by the developers. Extensive unit testing and debugging
are also done, usually by the developers. Tracking is done by project management team.
• Testing: Involves testing only where the product is thoroughly tested, defects are reported, fixed and
re-tested, until all the functional and quality requirements are met.
• Maintenance: Done post deployment of product. Add new features as desired by the customer/market.
Fix errors, if any, in the software product. Test cases from earlier phases are re-used here, based on need.
• V-model: It is a model that focuses on verification and validation. Follows the traditional SDLC life-cycle:
Requirements, Design, Implementation, Testing, Maintenance.
• Agile model: Agile methodologies are adaptive and focus on fast delivery of features of a software product.
All the SDLC steps are repeated in incremental iterations to deliver a set of features. Extensive customer
interactions, quick delivery and rapid response to change in requirements.
• Other Activities: Project management, includes team management. Project documentation(Traceability
matrix is a document that links each artifacts of development phase to those of other phases). Quality
Inspection.
1
(a) V-Model (b) Agile Model
• Integration Testing: Various components are put together and tested. Components could be only software
or software and hardware components.
• System Testing: Done with full system implementation and the platform on which the system will be
running.
• Acceptance Testing: Done by end customer to ensure that the delivered products meet the committed
requirements.
• Beta Testing: Done in a (so-called) beta version of the software by end users, after release.
• Functional Testing: Done to ensure that the software meets its specified functionality.
• Stress Testing: Done to evaluate how the system behaves under peak/unfavorable conditions.
• Performance Testing: Done to ensure the speed and response time of the system.
• Usability Testing: Done to evaluate the user interface, aesthetics.
• Regression Testing: Done after modifying/upgrading a component, to ensure that the modification is
working correctly, and other components are not damaged by the modification.
• Black-Box Testing: A method of testing that examines the functionalities of a software/system without
looking into its internal design or code.
• White-Box Testing: A method of testing that test the internal structure of the design or code of a
software.
• Test Design: Most critical job in testing. Need to design effective test cases. Apart from specifying the
inputs, this involves defining the expected outputs too. Typically, cannot be automated.
2
• Test Automation: Involves converting the test cases into executable scripts. Need to specify how to reach
deep parts of the code using just inputs, Observability and Controllability.
• Test Execution: Involves running the test on the software and recording the results. Can be fully
automated.
• Test Evaluation: Involves evaluating the results of testing, reporting identified errors. A difficult problem
is to isolate faults, especially in large software and during integration testing.
• Testing goals: Organizations tend to work with one or more of the following levels
Level 0: There is no difference between testing and debugging.
Level 1: The purpose of testing is to show correctness.
Level 2: The purpose of testing is to show that software doesn’t work.
Level 3: The purpose of testing is not to prove anything specific, but to reduce the risk of using the
software.
Level 4: Testing is a mental discipline that helps all IT professionals develop higher quality software.
• Controllability: Controllability is about how easy it is to provide inputs to the software module under
test, in terms of reaching the module and running the test cases on the module under test.
• Observability: Observability is about how easy it is to observe the software module under test and check
if the module behaves as expected.
2 Graphs
2.1 Basics
• A graph is a tuple G = (V, E) where V is a set of nodes/vertices, and E ⊆ (V × V ) is a set of edges.
• Graphs can be directed or undirected.
u v p r
y
w x q
• There are designated special vertices like initial and final vertices. These vertices indicate beginning and
end of a property that the graph is modeling.
• Typically, there is only one initial vertex, but there could be several final vertices.
u v
y
w x
• Most of these graphs will have labels associated with vertices and edges. Labels or annotations could be
details about the artifact that the graphs are modelling. Tests are intended to cover the graph in some way.
3
if(x<y){
y = 0;
x = x+1; x<y x>=y
}else{
x = y+1; y = 0
x = y+1
} x = x+1
z = x+1;
z = x+1
• An edge e = (u, v) is reachable if there is a path that goes to vertex u and then goes to vertex v.
• A test path is a path that starts in an initial vertex and ends in a final vertex. These represent execution
of test cases.
• Some test paths can be executed by many test cases: Feasible paths.
• Some test paths cannot be executed by any test case: Infeasible paths.
• A test path p visits a vertex v if v occurs in path p. A test path p visits an edge e if e occurs in the path p.
• A test path p tours a path q if q is a sub-path of p.
• When a test case t executes a path, we call it the test path executed by t, denoted by path(t).
• The set of test paths executed by a set of test cases T is denoted by path(T ).
• Test requirement describes properties of test paths.
• Test Criterion are rules that define test requirements.
• Satisfaction: Given a set T R of test requirements for a criterion C, a set of tests T satisfies C on a graph
iff for every test requirement in t ∈ T R, there is a test path in path(T ) that meets the test requirement t.
• Structural Coverage Criteria: Defined on a graph just in terms of vertices and edges.
• Data Flow Coverage Criteria: Requires a graph to be annotated with references to variables and defines
criteria requirements based on the annotations.
• Adjacency list representation provides a compact way to represent sparse graphs, i.e., graphs for which |E|
is much less than |V |2 . For each u ∈ V , Adj[u] contains all vertices v such that (u, v) ∈ E, i.e., it contains
all edges incident with u. Represented in Θ(|V | + |E|) memory.
• Adjacency matrix representation provides a compact way to represent dense graphs, i.e., graphs for which
|E| is close to |V |2 . This is a |V | × |V | matrix, where aij = 1 if there is an edge going from i to j.
• Breadth First Search: Computes the ”distance” from s to each reachable vertex.
4
Algorithm 1 Breadth First Search
BFS(G)
1: for each vertex u ∈ G, V − {s} do
2: u.color = W HIT E, u.d = ∞, u.π = NIL
3: end for
4: s.color = BLU E, s.d = 0, s.π = NIL
5: Q=ϕ
6: Enqueue(Q, s)
7: while Q ̸= ϕ do
8: u = Dequeue(Q)
9: for each v ∈ G.Adj[u] do
10: if v.color == W HIT E then
11: v.color = BLU E
12: v.d = u.d + 1
13: v.π = u
14: Enqueue(Q, v)
15: end if
16: end for
17: u.color = BLACK
18: end while
DFS-Visit(G, u)
11: time = time + 1
12: u.d = time
13: u.color = GRAY
14: for each v ∈ G.Adj[u] do
15: if v.color == W HIT E then
16: v.π = u
17: DFS-Visit(G, v)
18: end if
19: end for
20: u.color = BLACK
21: time = time + 1
22: u.f = time
5
• Complete path coverage: T R contains all paths in G. Unfortunately, this can be an infeasible test
requirement, due to loops.
• Specified path coverage: T R contains a set S of paths, where S is specified by the user/tester.
• A path from ni to nj is simple if no node appears more than once, except possible the first and last node.
• A prime path is a simple path that does not appear as a proper sub-path of any other simple path.
• Prime path coverage: T R contains each prime path in G. Ensures that loops are skipped as well as
executed. It subsumes node and edge coverage.
• Tour with side trips: A test path p tours a sub-path q with side trips iff every edge q is also in p in the
same order. the tour can include a side trip, as long as it comes back to the same node.
• Tours with detours: A test path p tours a sub-path q with detours iff every node in q is also in p in the
same order. The tour can include a detour from node n as long as it comes back to the prime path at a
successor of n.
• Best Effort Touring: Satisfy as many test requirements as possible without sidetrips. Allow sidetrips to
try to satisfy remaining test requirements.
• Round trip path: A prime path that starts and ends at the same node.
• Simple round trip coverage: T R contains at least one round trip path for each reachable node in G
that begins and ends in a round trip path.
• Complete round trip coverage: T R contains all round trip paths for each reachable node in G.
• T R for edge-pair coverage is all paths of length two in a given graph. Need to include paths that involve
self-loops too.
6
• Prime Path Algorithm
• To enumerate test paths for prime path coverage: Start with the longest prime paths and extend each of
them to the initial and the final nodes in the graph.
• Basic Block: A sequence of statements such that if the first statement is executed, all statements will be
(no branches).
• Edges: Transfer of control from one statement to the next.
• CFGs are often annotated with extra information to model data, this includes branch predicates, Definitions
and/or uses.
x = 0; x = 0;
while(x<y){ 1
y = f(x,y);
if(y == 0){
break; 2
}else if(y<0){ x<y; x>=y;
y = y*2; y = f(x,y); 3
continue; 7 print(y);
y>0; y == 0;
}
y = y*2; y<0;
x = x+1;
continue; 5 4 break;
} 6
print(y);
2 x = x+1;
(a) While loop with break and continue (b) A Control Flow Graph
7
2.6 Data Flow in Graphs
• Graph models of programs can be tested adequately by including values of variables(data values) as a part
of the model.
• Data values are created at some point in the program and use later. They can be used several times.
• A definition (def ) is a location where a value of a variable is stored into memory.
• Let V be the set of variables that are associated with the program artifact being modelled as a graph.
The subset of V that each node n (edge e) defines is called def (n)(def (e)).
The subset of V that each node n (edge e) uses is called use(n)(use(e)).
• A def of a variable may or may not reach a particular use.
• A path from li to lj is def-clear with respect to variable v if v is not given another value on any of the
nodes or edges in the path.
• If there is a def-clear path from li to lj with respect to v, the def of v at li reaches the use at lj .
• A du-path with respect to a variable v is a simple path that is def-clear from a def of v to a use of v.
• du(ni , nj , v): The set of du-paths from ni to nj for variable v.
• Data flow coverage criteria will be defined as sets of du-paths. Such du-paths will be grouped to define the
data flow coverage criteria.
• The def-path set du(ni , v) is the set of du-paths with respect to variable v that start at node ni .
• A def-pair set, du(ni , nj , v) is the set of du-paths with respect to variable v that start at node ni and end
at node nj .
• A test path p is said to du tour a sub-path d with respect to v if p tours d and the portion of p to which d
corresponds is def-clear with respect to v.
• We can allow def-clear side trips with respect to v while touring a du-path, if needed.
• We assume every use is preceded by a def, every def reaches at least one use, and for every node with
multiple out-going edges, at least one variable is used on each out edge, and the same variables are used on
each out edge.
• Subsumption: ○→
3 ○→
2 ○
1
• Prime path coverage subsumes all-du-paths coverage.
8
3 Integration Testing
3.1 Introduction
• Software design basically dictates how the software is organized into modules.
• Modules interact with each other using well-defined interfaces.
• Integration testing involves testing if the modules that have been put together as per design meet their
functionalities and if the interfaces are correct.
• Begins after unit testing, each module has been unit tested.
• Procedure call interface: A procedure/method in one module calls a procedure/method in another
module. Control can be passed in both directions.
• Shared memory interface: A block of memory is shared between two modules. Data is written to/read
from the memory block by the modules. The memory block itself can be created by a third module.
• Message-passing interface: One module prepares a message of a particular type and send it to another
module through this interface. Client-server systems and web-based systems use such interfaces.
• Empirical studies account for up to quarter of all the errors in a system to be interface errors.
• Integration testing need not wait until all the modules of a system are coded and unit tested.
• When testing incomplete portions of software, we need extra software components, sometimes called
scaffolding.
• Test stub is a skeletal or special purpose implementation of a software module, used to develop or test a
component that calls the stub or otherwise depends on it.
• Test driver is a software component or test tool that replaces a component that tales care of the control
and/or the calling of a software component.
• There are five approaches to do integration testing: Incremental, Top-down, Bottom-up, Sandwich, and Big
Bang.
• Incremental approach: Integration testing is conducted in an incremental manner. The complete
system is built incrementally, cycle by cycle, until the entire system is operational. Each cycle is tested by
integrating the corresponding modules, errors are fixed before the testing of next cycle begins.
• Top-down approach to integration testing: Works well for systems with hierarchical design.
• In hierarchical design, there is a first top-level module, which is decomposed into some second-level modules,
some of which, are in turn, decomposed into third-level modules and so on. Terminal modules are those
that are not decomposed and can occur at any level. Module hierarchy is the reference document.
• It could be the case that A and B are ready but C and D are not, so we can develop stubs for C and D for
testing interface between A and B. We keep doing this level by level.
• Bottom-up approach: Now we basically start with the lowest level modules and write test drivers to test
integration.
• Basic difference between top-down and bottom-up is that top-down uses only test stubs and bottom-up
uses test drivers.
• Sandwich approach tests a system by using a mix of top-down and bottom-up testing.
• Big Bang Approach: All individually tested modules are put together to construct the entire system
which is tested as a whole.
9
3.2 Design Integration Testing
• Graph models for integration testing are called Call graphs.
• For graph models, nodes now become modules/test stubs/test drivers and edges become interfaces.
• Structural coverage criteria: Deals with calls over interfaces.
• Data flow coverage criteria: Deals with exchange of data over interfaces.
• Shared data coupling: Two units access the same data through global or shared variables.
• External device coupling: Two units access an external object like a file.
• Message-passing interfaces: Two units communicate by sending and/or receiving messages over buffer-
s/channels.
• Since focus is on testing interfaces, we consider the last definitions of variables before calls to and returns
from the called units and the first uses inside the modules and after calls.
• Last-def : The set of nodes that define a variable x and has a def-clear path from the node through a call
site to a use in the other module. Can be in either direction.
• First-use: The set of nodes that have uses of a variable y and for which there is a def-clear and use-clear
path from the call site to the nodes.
• A coupling du-path is from a last-def to a first-use.
• All-coupling-def coverage: A path is to be executed from every last-def to at least one first-use.
• Only variables that are used or defined in the callee are considered for du-pairs and criteria.
• Transitive du-pairs (A calls B, B calls C and there is a variable defined in A and used in C) is not
supported in this analysis.
10
4 Specification Testing
4.1 Sequencing Constraints
• A design specification describes aspects of what behavior a software should exhibit. Behaviour exhibited
by software need not mean the implementation directly. It could be a model of the implementation.
• For testing with graphs, we consider two types of design specifications. Sequencing constraints on
methods/functions, and State behavior descriptions of software.
• Sequencing constraints are rules that impose constraints on the order in which methods may be called.
• Typically encoded as preconditions or other specifications. They may or may not be given as a part of the
specification or design.
• Consider the example of a simple Queue, a precondition can be that at least one element must be on the
queue before removing and a postcondition can be that e is on the end of the queue to enqueue e.
• Simple sequencing constraint: enqueue must be called before dequeue.
• This does not include the requirement that we must have at least as many enqueue calls as dequeue calls.
Need memory which can be captured in the state of the queue as the application code executes.
• Absence of sequencing constraints usually indicates more faults.
• FSMs can model many kinds of systems like embedded software, abstract data types, hardware circuits etc.
• Creating FSM models for design helps in precise modelling and early detection of errors through analysis of
the model.
• Many modelling notations support FSMs: Unified Modeling Language(UML), state tables, Boolean logic
etc.
• FSMs are good for modelling control intensive applications not ideal for modelling data intensive applications.
• FSMs can be annotated with different types of actions: Actions on transitions, Entry actions to nodes,
Exit actions on nodes.
• Actions can express changes to variables or conditions on variables.
• We need to consider values of variables to represent states of FSMs and statements/actions that result in
change of values of variables(states) result in transitions.
11
5 Testing Source Code: Classical Coverage Criteria
• The most common graph model for source code is control flow graph.
• Structural coverage criteria over control flow graphs deal with covering the code in some way or other.
• Data flow graphs augments the control flow with data.
• Code coverage: Statement coverage, branch coverage, decision coverage, Modified Condition Decision
Coverage(MCDC), path coverage etc.
• Node coverage is same as statement coverage, edge coverage is same as branch, and prime path coverage is
the same as loop coverage.
• Cyclomatic complexity: Basis path testing, structural testing. It is a software metric used to indicate
the (structural) complexity of a program.
• Cyclomatic complexity represents the number of linearly independent paths in the control flow graph
of a program.
• Basis path testing deals with testing each linearly independent path in the CFG of the program.
• A linearly independent path of execution in the CFG of a program is a path that does not contain other
paths within it. This is very similar to prime paths, every linearly independent path is a prime path.
• The cyclomatic complexity M = E − N + 2P , where E is the number of edges, N is the number of nodes,
and P is the number of connected components.
• When graph correspond to a single program, M = E − N + 2.
• Another way of measuring cyclomatic complexity is to consider strongly connected components in CFG.
Can be obtained by connecting the final node back to the initial node. Cyclomatic complexity obtained
this way is popularly called as cyclomatic number.
• If it is less than 10 then the code is not too complex.
• Data flow testing: Data flow coverage.
• Decision-to-decision path is a path of execution between two decisions in the CFG.
• A chain is a path in which initial and terminal vertices are distinct. All the interior vertices have both
in-degree and out-degree as 1.
• A maximal chain is a chain that is not a part of any other.
• A DD-path is a set of vertices in the CFG that satisfies one of the following conditions:
1. It consists of a single vertex with in-degree 0(initial vertex).
2. It consists of a single vertex with out-degree 0(terminal vertex).
3. It consists of a single vertex with in-degree ≥ 2 or out-degree ≥ 2(decision vertices).
4. It consists of a single vertex with in-degree and out-degree as 1.
5. It is a maximal chain of length ≥ 1.
12
6 Logic
6.1 Basics
• The fragment of logic that we consider is popularly known as predicate logic or first order logic.
• An atomic proposition is a term that is either true or false.
• Propositional logic deals with combining propositions using logical connectives to form formulas which
are complicated statements.
• Common logical connectives used in proportional logic are
1. ∨ Disjunction
2. ∧ conjunction
3. ¬ negation
4. ⊃ or =⇒ implies
5. ≡ or ⇐⇒ equivalence
• The set ϕ of formulas of propositional logic is the smallest set satisfying the following conditions
• Predicate Coverage: For each p ∈ P , TR contains two requirements: p evaluates to true and p evaluates
to false.
• For a set of predicates associated with branches, predicate coverage is the same as edge coverage.
• Clause Coverage: For each c ∈ C, TR contains two requirements: c evaluates to true and c evaluates to
false.
• Clause coverage does not subsume predicate coverage.
• Combinatorial Coverage: For each p ∈ P , TR contains test requirements for the clauses in Cp to evaluate
to each possible combination of truth values. Commonly called as multiple condition coverage.
• Given a major clause ci in predicate p, we say that c determines p if the minor clauses cj ∈ Cp , j ̸= i,
have values so that changing the truth values of ci changes the truth value of p.
13
• Active Clause Coverage: For each p ∈ P and each major clause ci ∈ Cp , choose minor clauses cj , j ̸= i,
so that ci determines p. TR has requirements for each clause as a major clause. For a predicate with n
clauses, n + 1 distinct test requirements suffice to achieve clause coverage.
• Correlated Active Clause Coverage: The values chosen for minor clauses cj must cause p to be true
for one value of the major clause ci and false for the other. CACC subsumes predicate coverage.
• Restricted Active Clause Coverage: The values chosen for the minor clauses cj must be the same
when ci is true and when it is false.
• Inactive Clause Coverage: For each p ∈ P and each major clause ci ∈ Cp , choose minor clauses cj , j ̸= i
so that ci does not determine p. TR now has four requirements for ci , p is true/false for ci true/false.
• General Inactive Clause Coverage: The values chosen for the minor clauses cj may vary amongst the
four cases.
• Restricted Inactive Clause Coverage: The values chosen for the minor clauses cj must be the same for
same values of p.
• As long as a predicate or a clause is not valid/not a contradiction, we can find test cases to achieve predicate
and clause coverage.
• Need to identify the correct predicates and pass them to a SAT/SMT solver to check if the predicate is
satisfiable.
14