CSE3009: 소프트웨어 구조및설계
(Software Architecture and Design)
Yann-Gaël Guéhéneuc
Département de génie informatique et de génie logiciel
Testing Method Sequences Slides by Giuliano Antoniol
CSE3009: (Software Architecture and Design) Yann-Gal - - PowerPoint PPT Presentation
CSE3009: (Software Architecture and Design) Yann-Gal Guhneuc Testing Method Sequences Slides by Giuliano Antoniol Dpartement de gnie informatique et de gnie logiciel Example I Coin box of a
(Software Architecture and Design)
Département de génie informatique et de génie logiciel
Testing Method Sequences Slides by Giuliano Antoniol
Coin box of a vending machine in C++
2/71
Coin box of a vending machine in C++
3/71
class CCoinBox { unsigned totalQtrs; unsigned curQtrs; unsigned allowVend; public: Ccoinbox() {Reset();} void AddQtrs(); void ReturnQtrs() { void CCoinBox::AddQtr() { curQtrs = curQtrs + 1; if (curQtrs > 1) allowVend = 1; } void CCoinBox::Vend() { if (isAllowedVend()) { totalQtrs = totalQtrs + 2;
4/71
void ReturnQtrs() { curQtrs = 0; } unsigned isAllowedVend() { return allowVend; } void Reset() { totalQtrs = 0; allowVend = 0; curQtrs = 0; } void Vend(); }; totalQtrs = totalQtrs + 2; curQtrs = curQtrs - 2; if (curQtrs < 2) allowVend = 0; } }
State transitions caused by events, enabled
Engine Off
start [transmission= neutral]
Engine On
5/71
event(arguments) [condition] ^target.sendEvent(arguments) /method(arguments)
event name guard executed method trigger
event dispatch Engine Off Engine On
Reset()
Functioning
AddQtr ReturnQtr() AddQtr() Vend() Vend()
CCoinBox()
Vend() [self.curQrts = 3] Vend() [self.curQrts = 2] allowVend = 0 curQrts = 0 allowVend = 0 curQrts = 1 Vend() 6/71
– allowVend=1 curQrts=0 : AddQrts() – allowVend=0 curQrts=0 : ReturnQrt() – allowVend=1 curQrts:[2,M] : AddQrt() ReturnQtr() Vend() [self.curQrts >= 4] ReturnQtr() allowVend = 1 curQrts = 0 allowVend = 1 curQrts:[2,M]
The state diagram indicates that the
7/71
This is a state-dependent fault
8/71
Method structural testing would conclude
The omission may remain unforeseen even
9/71
Problem: a failure results from a certain sequence of methods Solution: identify minimal set of sequences of methods
Motivations Data Slices
10/71
Method Per- / Post-conditions Conclusion
Motivations Data Slices
11/71
Method Per- / Post-conditions Conclusion
Using inheritance context coverage, control-
12/71
What about classes?
Testing a class aims at finding the sequence
13/71
Testing classes for all possible sequences of
14/71
The resources required to test a class
15/71
It is necessary to devise a way to reduce the
Deriving method sequences
16/71
Motivations Data Slices
17/71
Method Per- / Post-conditions Conclusion
Goal: identify a minimal number of method
18/71
The state of an object at a single point in
The correctness of a class depends on
19/71
A class is a composition of slices
20/71
Bashir and Goel’s class testing strategy is to
21/71
the class partial correctness
A class K encapsulates a set of variables
22/71
A data slice of K
23/71
(where @@ denotes the usage relationship) (and → denotes a modification)
Potential problems with data slices
24/71
variable would not be tested and the fault may remain undetected
legal sequences because a method may be used more than once in a sequence !
Motivations Data Slices
25/71
Method Per- / Post-conditions Conclusion
class SampleStatistic { friend TestSS; // test driver! protected: int n; double x; double x2; double minValue, maxValue; public: sampleStatistic(); virtual ~SampleStatistic(); virtual void reset();
26/71
Formerly part of the GNU C++ library
virtual void reset(); virtual void operator +=(double); int samples(); double mean(); double stdDev(); double var(); double min(); double max(); double confidence(int p_percentage); double confidence(double p_value); void error(cont char * msg); };
SampleStatistic::mean() { if (n > 0) double SampleStatistics::stdDev() { if (n <= 0 || this->var() <= 0) return (0); else return (double) sqrt(var()); } double SampleStatistics::var() { if (n > 1) return ((x2 - ((x * x) / 2)) / n - 1); }
27/71
if (n > 0) return (x / n); else return (0.0); } SampleStatistic::operator+=(double value) { n += 1; x += value; x2 += (value * value); if (minValue > value) minValue = value; if (maxValue < value) maxValue = value; }
MaDUM: Minimal Data member Usage
28/71
MaDUM reports the usage of instance
MaDUM accounts for indirect use of instance
29/71
Use the MaDUM to devise a testing strategy,
Categories: constructors, reporters, transformers,
Mdi(K) = {Rdi, C, Tdi, Odi}
– R = {r | r is a reporter method for
30/71
– Rdi = {rdi | rdi is a reporter method for variable di} – C = {ci | ci is a constructor of K} – Tdi = {mdi | mdi ∉ Rdi ∧ mdi ∉ C ∧ mdi → di} – Odi = {odi | odi @@ di ∧ odi ∉ Rdi ∧ odi ∉ C ∧ odi ∉ Tdi}
Categories: constructors, reporters, transformers,
– Account for indirect use of data members, through intermediate methods
31/71
intermediate methods – Others
MaDUM accounts for indirect uses
32/71
The method categories is used to decide the
33/71
We would like to automate that procedure as
(Add to all classes get() and set()
34/71
Systematically set and get values of instance
Constructors initialise instance variables, we
35/71
Run the constructor and append reporter
Verify if correct initial state (state invariant)
For each slice di
36/71
are 5,040 possible permutations!
Other methods
37/71
Yet, they must be tested as other methods Only their functionality as stand-alone
Any standard test technique can be used
Slice allowVend
38/71
Slice curQrts
As a result of the fault, possibly important
Slicing may not be helpful for many classes
Number of methods sequences still large
39/71
Many sequences may be impossible (illegal)
Automation?
Are we missing many faults by testing slices
40/71
Are we missing many faults by testing slices
Implicitly aimed at classes with no state-
Motivations Data Slices
41/71
Method Per- / Post-conditions Conclusion
When two classes are related through
The derived class may add functionality or
42/71
Extreme options for testing a derived class
Assuming the base class has been
43/71
Extend MaDUM of the base class to
class SampleHistogram : public SampleStatistic { protected: short howmanybuckets; int *bucketCount; double *bucketLimit; public: SampleHistogram(double low, double hi, double bucketWidth = -1.0);
44/71
SampleHistogram(double low, double hi, double bucketWidth = -1.0); ~SampleHistogram(); virtual void reset(); // Redefined virtual void operator+=(double); // Redefined int similarSamples(double); int buckets(); double bucketThreshold(int i); int inBucket(int i); void printBuckets(ostream&); }
If a newly defined method mderived calls an
45/71
Even though the base class has no a priori
46/71
For example, if a method m1base calls
The MaDUM of SampleHistogram has
47/71
Both reset() and +=() are redefined or
48/71
“Local” variables
Retest inherited variables (i.e., their slices):
49/71
Retest inherited variables (i.e., their slices):
An inherited variable must be re-tested if the
50/71
For SampleHistogram, the set of inherited
Motivations Data Slices
51/71
Method Per- / Post-conditions Conclusion
Method pre-condition
52/71
Method post-condition
Possible notations
53/71
Class Queue (unbounded queue) Attribute: Number of elements in the queue, count Init(q:Queue) pre: Queue q does not exist post: Queue q exists and is empty Empty(q:Queue) pre: Queue q exists post: Returns 1 if q is empty (count=0), 0
54/71
post: Returns 1 if q is empty (count=0), 0
Eque(q:Queue, e:Element) pre: Queue q exists post: Element e is added to the tail of queue q, and q is not empty (count=old(count)+1) Dque(q:Queue, e:Element) pre: Queue q exists and is not empty (count>0) post: Element e is removed from q (count=old(count)-1) Top(q:Queue, e:Element) pre: Queue q exists and is not empty (count>0) post: The first element is returned (e)
Get pre- and post-conditions
55/71
Derive method sequence constraints from
Choose a criterion
Derive method sequences satisfying a
56/71
Derive method sequences satisfying a
Pre- and post-conditions imply method
57/71
– m1 post-condition implies m2 pre-condition
58/71
– m1 post-condition implies the negation of m2 pre-condition
some conditions
– BoolExp lists the conditions under which the sequence is possible (disjunctive normal form): C = C1 ∨ C2 ∨ …
Always Valid Coverage (T)
59/71
Never Valid Coverage (F)
Always/Possibly True Coverage (T/pT)
– Each always-valid constraint and each possibly-true constraint must be covered at least once, i.e., each (m1, m2, T) and each (m1, m2, C) using one of the disjunction
60/71
m2, T) and each (m1, m2, C) using one of the disjunction in C (C1, C2, or…)
Always/Possibly True Coverage+ (T/pT+)
– Each always-valid constraint and each possibly-true constraint (using each disjunction) must be covered at least once, i.e., each (m1, m2, T) and each (m1, m2, Ci) using each of the disjunction in C (C1, C2, and…)
Never Valid/Possibly False (F/pF)
– Each never-valid constraint and, using one of the disjunction, false constraint must be covered at least
61/71
Never Valid/Possibly False Plus (F/pF+)
– Each never-Valid constraint and each possibly false constraint must be covered at least once, not(C) = C’1 ∨ C’2 ∨ …, i.e., each (m1, m2, F) and each (m1, m2, not(C1)), (m1, m2, not(C2)), …
Always/Possibly True Plus/Never/Possibly False
T/pT+/F/pF+ T/pT+ F/pF+
62/71
T/pT T F/pF F
Sequencing constraints
C . (Init,Top,F) C . (Eque,Init,F) C . (Dque,Top,C) C . (Top,Top,T)
63/71
Where: C = count>0
Criterion T requires the use of
C7.(Eque,Dque,T) C12.(Dque,Eque,T)
C9.(Eque,Eque,T) C8.(Eque,Top,T) C20.(Top,Top,T)
64/71
Partial tree based on sequencing constraints
C8.(Eque,Top,T) C18.(Top,Eque,T) C20.(Top,Top,T) C17.(Top,Dque,T) C12.(Dque,Eque,T) C7.(Eque,Dque,T) C12.(Dque,Eque,T) C8.(Eque,Top,T) C18.(Top,Eque,T) C8.(Eque,Top,T) C17.(Top,Dque,T) C18.(Top,Eque,T) C7.(Eque,Dque,T) C12.(Dque,Eque,T) C8.(Eque,Top,T) C17.(Top,Dque,T) C18.(Top,Eque,T) C17.(Top,Dque,T) C12.(Dque,Eque,T) C8.(Eque,Top,T)
Automation?
65/71
Several sequences can be adequate for a
66/71
different
Selecting another criterion than T
may be necessary
67/71
may be necessary
(m1, m2, C), may require specific calls before the call to m1 (because of pre- and post-conditions of m1)
Empirical comparison of the different criteria
From Daniels and Tai
68/71
69/71
Motivations Data Slices
70/71
Method Per- / Post-conditions Conclusion
Testing method in “isolation”
71/71
Testing classes