debugging and injecting course software testing & verification 2014/15 wishnu prasetya the...

30
Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra. The ‘”injecting” part is about mutation testing; this is discussed in Ch 5 of the book.

Upload: theodore-carr

Post on 15-Jan-2016

215 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Debugging and Injecting

Course Software Testing & Verification2014/15

Wishnu Prasetya

The debugging part uses Andreas Zeller’s slides. This is extra. The ‘”injecting” part is about mutation testing; this is discussed in Ch 5 of the book.

Page 2: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Debugging

• Suppose we observe a program “fails”. Debugging: find the root cause of the failure (the error made in the program).

• Then we can fix the program.• Very time consuming, especially at the system-level.• How about automation?

2

Page 3: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Simplification

• Debugging = find an item of some property, in a given search space.

• It can at least be made easier if the “search space” is shrunk (simplification).

• Can we simplify systematically?• E.g. binary search comes to mind....

3

Page 4: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Let’s First Re-express the Problem

• More abstractly, so that we can later apply the solution to different concrete situations.

• A test-case is abstractly represented by a configuration c , which is made up of “units” 1, 2,... n organized in some structure (e.g. a list of units, or a tree of units).

• For simplicity, here we assume c is a set of units. So: c = {1, 2,... n}

4

Page 5: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Configurations

• test(c) executes the configuration c , resulting either (pass), (fail), or ? (the configuration is actually invalid).

• two configurations can be compared to decide which one is “simpler”. Since we said a configuration is a set, we use c1 c2.

• Minimalization: if c is the initial failing configuration, (test(c)= ), find the smallest subset c of c such that test(c)= .

• Expensive...5

Page 6: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Simplification

• Simplification: find a “relevant” configuration. • If c is the initial failing configuration (test(c)= ), a subset c of c is relevant if test(c)= and if removing any unit from c causes to disappear. That is: : c : test(c /{})

• Note that a relevant configuration does not have to be minimal.

6

Page 7: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Binary Strategy

• Let c be the initial failingconfiguration.

• A binary simplify(c) is defined as follows:

1. simplify(c) = 2. if |c|= 1 then return c // minimal

3. split c to c1 c2

4. if test(c1)= then return simplify(c1)

5. if test(c2)= then return simplify(c2)

6. /* 4 and 5 give or ? */ return c• Yield a simpler confg, but not necessarily relevant.

7

Page 8: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Delta Debugging-min Algorithm

• simplify(c) = ddmin(c,2) defined below1. ddmin(c,N) = // N is split granularity2. if |c|= 1 then return c3. split c into c1 ... cN

4. if for some k, test(c/ck)= then return ddmin ( c/ck , max(N-1,2) )

5. else if N<|c| // increase granularity then return ddmin( c , min(2N, |c|) )

6. else return c

8

Page 9: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Example

9

orig ddmin([1..8], 2) ?

?ddmin([1..8], 4)

ddmin([1,2,3,4,7,8], 3) ddmin([1,2,7,8], 2) ?

?ddmin([1,2,7,8], 4) ddmin([2,7,8], 3) ?

??

return with c = [2,7,8]

Page 10: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Complexity ddmin

• Worst case, invoking test this number of times: ( |c|2 + 7 |c| ) / 2

• If– there is only one failure-inducing unit in the initial

configuration, and– all configurations that include the unit would fail

• then the number of tests is: 2log(|c|).

10

Page 11: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Localizing

• Let c be the initial failing configuration. Find subsets s f c such that:– s succeeds

– f fails– their difference = f/s is “minimal”. That is, for

any : test(s { }) test(f / { })

• If||=1 , it contains the problem unit. If || >1 , it may contain units whose addition or removal lead to an invalid configuration.

11

Page 12: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Idea

• Adapt ddmin to operate on a pair input configurations: s and f

• Split = f/s to 1 ... N

• Check the outcome of:– test(s k)

– test(f / k)

• Well, now we have more outcome combinations...

12

Page 13: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Possible outcomes of tests

test(s k) f := s k s := s k

test(f / k) f := f / k s := f / k

13

Else, (so, for any partition k of the outcome is none of the above), increase split granularity.

If for for some partition k of the outcome is one of these:

Page 14: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

The dd Algorithm• localize(c) = dd(,c,2) defined below1. dd(s,f,N) =2. := f/s 3. if ||= 1 then return (s,f)4. split into 1 ... N

5. if for some k, test(s k)= then return dd (s, s k ,2)

6. if for some k, test(s k)= then return dd (s k ,f , max(N-1,2) )

7. if for some k, test(f/k)= then return dd ( s, f/k , max(N-1,2) )

8. if for some k, test(f / k)= then return dd (f/ k ,f,2 )

9. if N<|| // increase granularity then return dd( f,d , min(2N, ||) )

10. else return (s,f)

14

Page 15: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Mutation Test

15

Page 16: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Mutants

• Mutation: changing a valid artifact, usually by a minimalistic amount, to produce an invalid version of it. The result: mutant (Def 5.47, different formulation)

• Application:– negative testing, to produce invalid inputs.– seeding errors in a program

• To systematically generate mutants, we introduce mutation operators (Def 5.46)

16

Page 17: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Example

17

NLpostcode Area Space StreetArea FirstDigit Digit Digit DigitStreet Letter LetterFirstDigit 1 | 2 ...Digit 0 | 1 | 2 ...Letter a | b | c ... | A | B | C ...Space | “ “ Space

NLpostcode Street Area

Area FirstDigit Digit Digit

Area FirstDigit Digit Digit Digit Digit

If an input is described by a BNF grammar, we can systematically mutate the grammar to produce mutants for negative tests.

Page 18: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Some coverage concepts for grammar-based mutants generation

• To define how much mutants to generate.• Imagine a set of mutation operators can be applied

on BNF production rules.• (C 5.33) Mutation Operator Coverage (MOC) : for

every mutop , TR contains 1x mutant produced by .• (C5.34) Mutation Production Cov: for every

production rule r and every mutop applicable to r, TR contains one mutant produced by (r).

18

Page 19: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Systematic error seeding (5.2)

• Let’s mutate a program to “simulate” programming mistakes, resulting syntactically valid mutants, but containing mistakes.

• We can use this to test your tests, to see how “effective” they are called mutation test.

• Considered to be very strong. Tools:– Pitest, Major for Java– NinjaTurtles (beta) for C#– MuCheck for Haskell

19

Page 20: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Example

20

(mutations generated by the tool Mothra)

Page 21: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Typical Tooling Setup

21

Program P

Mutants of P

Fix P

construct test set T

run T on P

run T on

mutants

a test-case fails

not enough mutants percentage killed

This is a simpler variation of the scheme in Fig. 5.2

Page 22: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Killing a mutant

• (D 5.50) Let P be the original program. A test t of P weakly kills a mutant P’ of P if executing t on them results in different (internal) states, immediately after the mutation spot.

• (D 5.50) The test t strongly kills P’ if executing it on P and P’ produces different outcomes.

22

P(x) { if (x<0) { y=x ; return x } y=1 ; return 0 }

P(x) { if (x0) { y=x ; return x } y=1 ; return 0 }

test2() { r = P(0) ; assert (return==0) }

test1() { r = P(0) ; assert (y==1) }

test3() { r = P(2) ; assert (return==2) }

Page 23: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Mutation-based coverage criteria

• (C5.32) Given a set M of mutants, the TR is simply M: you have to “kill” every mutant in M.

• OA remark that in practice strong vs weak do not make much difference careful, this depends on the oracles used. In particular if you use partial oracles, e.g. in property-based testing, they mat actually make much difference.

• The strength depends on the choice of mutops. See 5.2.2 and 5.3.2.

• Preferably you want mutops that simulate realistic errors.• Also, try to minimize the mutops, or else mutation testing

becomes too expensive.

23

Page 24: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Mutation operators

• (D5.51) Given a set O2 of mutation operators; a subset O1 is effective if test-cases designed specifically to kill mutants produced by O1 will (very likely) also kill mutants from O2/O1.

• The smallest set of effective mutops? Hard to know, and very situation specific.

• Still, there have been plenty of research to see if there are some general patterns. For mutations over imperative constructs, see 5.2.2. Mutations on OO aspects, see 5.3.2.

24

Page 25: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

Mutops on imperative constructs (5.2.2)

• ABS (Absolute Value Insertion) Modify each arithmetic (sub)expression by using functions abs(), negAbs(), and failOnZero().

• AOR (Arithmetic Operator Replacement) Replace each occurrence of arithmetic operators +,- ,*,/ , % by each other; and in addition, by leftOp, and rightOp.

• SVR (Scalar Variable Replacement) Replace each variable reference by another (type compatible and in-scope) variable.

• BSR (Bomb Statement Replacement) Replace each statement by Bomb().

• More... see book.

25

Page 26: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

OO-related Mutops

• 5.3.3 additionally lists 20 mutops targeting typical OO aspects, e.g. :– Inheritance: method overriding, variables

shadowing, constructors overriding works differently

– Polymorphism– Use of static members

• I will only show some, as examples

26

Page 27: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

OO-related Mutops

27

ANC – Argument Number Change

Point3D p; p.set (1, 2, 3); p.set (2, 3);

Point3Dvoid set (int x, int y, int z);void set (int x, int y);

AOC – Argument Order Change

Point3D p ; p.set (1, 2, ‘t’) ; p.set (‘t’, 1, 2) ;

Point3Dvoid set (int x, int y, char c);void set (char a, int x, int y);

Page 28: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

OO-related Mutops

• OMD (Overriding Method Deletion): delete an overriding method.

• OMM (Overridden Method Moving): move a call to a super.method to the first or last position, or up and down one statement.

28

m() { x ++ ; y = y/x ; super.m() ; }

Page 29: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

OO-related Mutops

29

HVI – Hiding Variable Insertion

colorpoint1 int x;2 int y;

pointint x;int y;

HVD – Hiding Variable Deletion

pointint x;int y;

colorpointint x;

1 // int x;int y;

2 // int y;

Page 30: Debugging and Injecting Course Software Testing & Verification 2014/15 Wishnu Prasetya The debugging part uses Andreas Zeller’s slides. This is extra

OO-related Mutops

30

ATC – Actual Type Change

Point p ; p = new Point(); p = new Point3D();

DTC – Declared Type Change

Point p ; Point3D p ;

p = PointFactory();

Point

Point3D