0% found this document useful (0 votes)
16 views

SWVV_L17a_Code-based_testing

The document discusses various code-based test generation techniques for software verification and validation, focusing on methods such as random test generation, annotation-based test generation, search-based techniques, and symbolic execution. It highlights the motivation behind generating test inputs from source code to ensure comprehensive testing, as well as the challenges and tools associated with each technique. The evaluation of these methods indicates mixed results in terms of effectiveness and their ability to uncover real faults in software.

Uploaded by

11kacsa11
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)
16 views

SWVV_L17a_Code-based_testing

The document discusses various code-based test generation techniques for software verification and validation, focusing on methods such as random test generation, annotation-based test generation, search-based techniques, and symbolic execution. It highlights the motivation behind generating test inputs from source code to ensure comprehensive testing, as well as the challenges and tools associated with each technique. The evaluation of these methods indicates mixed results in terms of effectiveness and their ability to uncover real faults in software.

Uploaded by

11kacsa11
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/ 20

Software Verification and Validation (VIMMD052)

Code-based test generation

Dávid Honfi, Zoltán Micskei, István Majzik

Budapest University of Technology and Economics


Dept. of Artificial Intelligence and Systems Engineering

Budapest University of Technology and Economics


Dept. of Artificial Intelligence and Systems Engineering 1
Where are we now in the development process?
Requirement
analysis

System
specification

Architecture
design

Component
design

Component
implementation • Source code analysis
• Proof of program correctness by theorem proving
System • Software model checking with abstraction-based methods
integration
• Component testing: classic techniques
System • Component testing: code-based testing
delivery

Operation,
maintenance

2
Motivation
 Goal: Developer testing of software components
(modules, units)
o At this level, detailed specification may be missing
 Idea: Generate test inputs based on the source code
o Execute all parts of the code
(this way source code coverage criteria can be satisfied)
 How test outputs are checked?
o Based on overall expectations (derived from higher level
specifications)
o Using generic criteria: avoiding crash, OS level error signal,
exception, timeout, violated assertion
o Re-using outputs of previous test (regression testing)

3
1. Random test generation
Random selection of input data from the input domain
 Advantage:
o Very fast
o Very cheap
 Ideas:
o If no error found: trying different parts of the input domain
o Selection based on ”difference”, ”distance” of values
 Example tool for Java: Randoop

8
Random test generation: The Randoop tool
 Generation a sequence of method calls
 Creating object parameters using random values in
the constructor

 Heuristics:
o Execution of the selected test case
o Throwing away random tests that seem to be redundant
o Using invalid values for robustness testing

9
2. Annotation-based test generation
 The code shall contain:
o Pre- and post-conditions (e.g.: design by contract)
o Other annotations (e.g., loop invariants)
 These are able to guide test generation
o Preconditions: to be satisfied
(or violated if robustness is tested)
o Postconditions, invariants: to be checked
/*@ requires amt > 0 && amt <= acc.bal;
@ assignable acc.bal;
@ ensures acc.bal == \old(acc.bal) - amt;
@*/
public void transfer(int amt, Account acc) {
acc.withdraw(amt);
deposit(amt);
}
12
Annotation-based test generation: Example tools
 AutoTest
o For the Eiffel language, with design by contract
o Input: object pool
• Random generation of inputs that satisfy the preconditions
o Expected output: checked on the base of the contracts
o Ref: Bertrand Meyer et al., "Program that Test Themselves", IEEE Computer
42:9, 2009.

 QuickCheck: Property based test generation


o Goal: Generate test values that take into account the types
and constraints of the input domains
o Ref: Claessen et al. "QuickCheck: a lightweight tool for random testing of
Haskell programs“ ACM Sigplan 46.4 (2011): 53-64

13
3. Search-based techniques
Approach: Search-based Software Engineering (SBSE)
 Representing a problem as a search:
o Search space:
Possible test inputs + structure of the tested program
o Objective function: reaching a test goal
• Coverage criteria: statements, decision branches
• Minimization of the size of the test suite
 Using metaheuristic algorithms
o Genetic algorithms: a random initial test set and
mutations or crossover + the objective function
• Mutations: Changes in test inputs, adding / removing calls
• Crossover: Combining existing test cases to generate a new set
• Keeping the new test cases that increase the objective function

16
Search-based techniques: Mutation and crossover

Crossover on test cases

Mutations on test cases

Crossover on test suites


17
Search-based techniques: The EVOSUITE tool
 „Whole test suite generation”
o All test goals are taken into account
o Searches are based on multiple metrics: coverage and test suite size
o Uses sandbox for environment interaction
 Example: Increasing coverage vs different search algorithms:

18
4. Symbolic execution
 Static program analysis technique
 Basic idea:
o Following the computation of program paths on the
basis of the source code, with symbolic variables
o Deriving reachability conditions as path constraints (PC)
o Constraint solving on path constraints (e.g., using an
SMT solver):
A solution provides inputs to execute the given path
 Popular nowadays:
o Efficient SMT solvers exist
o Used to generate test inputs for covering given paths

20
Symbolic execution: Program paths and related inputs

int fun1(int a, int b){ Exploring program paths,


if (a == 0){ identifying branch conditions
1 printf(ERROR_MSG);  Deriving path constraint (PC)
2 return -1; for each path
}
if (b > a)
a == 0
3 return b*a + 5; F T
else
4 return (a+b) / 2; a: 0
b > a b: 0
}
F T

PC for this path:


(a==0)  (b>a) a: 2 a: 1
b: 1 b: 2
Selecting inputs that satisfy PC
22
Symbolic execution: Path constraints in a symbolic way
Path constraint Statement ID
Symbolic variables x, y
initial values X, Y

23
Symbolic execution: Example tools
Name Platform Language Notes
KLEE Linux C (LLVM bitcode)
IntelliTest Windows .NET assembly Formerly: Pex
SAGE Windows x86 binary Security testing
Jalangi - JavaScript
Symbolic - Java
PathFinder

Other (mainly discontinued) tools:


CATG, CREST, CUTE, Euclide, EXE, jCUTE, jFuzz, LCT, Palus, PET, etc.

More tools: http://mit.bme.hu/~micskeiz/pages/cbtg.html

27
Symbolic execution: Microsoft IntelliTest
Generate unit tests for your code with IntelliTest
https://learn.microsoft.com/en-us/visualstudio/test/generate-
unit-tests-for-your-code-with-intellitest

Input variable: ”condition”

Test inputs generated Test outputs SEViz (Symbolic Execution Visualizer)


for variable ”condition” (incl. exception here) https://github.com/FTSRG/seviz

28
Symbolic execution: Challenges for symbolic execution

1. Huge number of execution paths


2. Complex arithmetic expressions
3. Floating point operations
4. Compound structures and objects
5. Pointer operations
6. Interaction with the environment
7. Multithreading
8. …
T. Chen et al. „State of the art: Dynamic symbolic execution for automated test generation”.
Future Generation Computer Systems, 29(7), 2013
32
Symbolic execution: Challenge 1
Huge number of execution paths
int hardToTest(int x){
for (int i=0; i<100; i++){
int j = complexMathCalc(i,x);
if (j > 0) break;
}

return i;
}

 Solution ideas:
o Various loop traversal algorithms (instead of DFS)
o “Method summary”: simple representation of methods

33
Symbolic execution: Challenge 2
Complex arithmetic expressions
 Most SMT solvers cannot handle these
int hardToTest2(int x){
if (log(x) > 10)
return x
else
return -x;
}

 Ideas: Using specific solvers

34
Symbolic execution: Challenge 6
Interaction with the environment
 Calls to platform and external libraries
int hardToTest3(string s){
FileStream fs = File.Open(s, FileMode.Open);
if (fs.Lenth > 1024){
return 1;
} else
return 0;
}
}

 Idea:
o „Environment models” (KLEE): for simple C programs
o Special objects representing the environment (Java)
36
Evaluation: Applying code-based techniques
 A large-scale embedded system (C)
o Execution of CREST and KLEE on a project of the company ABB
o ~60% branch coverage reached
o Fails and issues in several cases
X. Qu, B. Robinson: A Case Study of Concolic Testing Tools and Their Limitations, ESEM 2011

 Does it help software developers?


o 49 participants wrote tests and also generated tests
o Generated tests with high code coverage did not discover
more injected failures than manual tests
G. Fraser et al., “Does Automated White-Box Test Generation Really Help Software Testers?,” ISSTA 2013

 Finding real faults


o Defects4J: database of 357 issues from 5 projects
o Tools evaluated: EvoSuite, Randoop, Agitar
o Found 55% of faults – problem: requirements were missing
S. Shamshiri et al., „Do automatically generated unit tests find real faults? An empirical study of effectiveness
and challenges.” ASE 2015
38

You might also like