-
Notifications
You must be signed in to change notification settings - Fork 0
/
README
106 lines (99 loc) · 3.69 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
MUT - A more interesting way to test your Scala classes.
==== Idea ====
Using MUT, rather than writing specifications to test a class, you write
specifications to test how one (or a few) class instance(s) behave in
different states.
==== Why use MUT ====
Suppose that you have a class which has:
- Operations (change the state of class)
- Specifications (documented behaviors of class in different states)
And the state of class is determined by the value of the class attributes.
There are two specifications which from two perspectives define the behavior
of an operation that transforms the class instance's state from S1 to S2
then to S3.
Our goal is to verify the correctness of the class instance in each of the
states against the two specifications.
Using the popular unit testing tools, such as ScalaCheck, ScalaTest, specs2,
you may need to write four tests:
Test 1 - setup an instance at state S1 and test against spec 1
Test 2 - setup an instance at state S1, execute the operation to change the
state to S2 then test against spec 1
Test 3 - setup an instance at state S1, execute the operation to
change to state to S2, execute again to chance to state S3 then test against
spec 1.
Test 4 - setup an instance at state S1 and test against spec 2
MUT is thus designed to eliminate the need of the repetitive class instance
setup and states transition. The above three tests will be written as the
following MUT test:
test("Test 1") { // instance now at state 1
test against spec 1
}
next("Test 2") { // instance now at state 2
execute the operation
test against spec 1
}
next("Test 3") { // instance now at state 3
execute the operation
test against spec 1
}
test("Test 4") { // instance now at state 1
test against spec 2
}
cleanup
==== How To Use MUT ====
class MyMutTest extends MUT {
var instance: MyClass = null
override def setup {
// Setup your instance(s)
instance = new MyClass
}
override def cleanup {
// Clean up for the whole test
if (instance != null) // You must have this line
instance.close().deleteTempFile()
}
test("Spec1 - instance should behave like A") {
instance.operation(123)
if (instance state is like A)
true
else
false
} otherwise {
// Help to diagnose the problem when the preceding block falsed
println("instance has the incorrect state because of GGG")
// Skip all the following "next(){}" tests
halt("Very serious error!! Shall not proceed to the next state tests!")
}
next("Sepc1 - instance should behave like B") {
instance.operation(234)
if (instance state is like B)
true
else
false
} otherwise { println("instance has the incorrect state") }
// Following "test(){}", You can have any number of "next(){}" tests
// "otherwise{}" block is not compulsory
next("...") { ... }
// Call "test(){}" will cleanup then re-setup
test("Spec2 - instance should behave like C") {
...
}
// You can also use "timeTest" and "timeNext" instead of "test" and "next"
// to print out the time taken to complete the test.
cleanup // Do not forget this line
}
==== Author ====
Houzuo (Howard) Guo
http://twitter.com/#!/hzguo
http://www.linkedin.com/pub/houzuo-guo/27/b62/2b1
https://github.com/HouzuoGuo
==== License ====
Use the source code in anyway you want, but please retain the author
information, in case the user of your test code needs technical support.
==== Background ====
The idea of MUT originated from designing a testing tool for my pet Scala
project ScalaDB:
flat file DB engine in Scala - https://github.com/HouzuoGuo/ScalaDB
Usage of MUT in the pet project is here:
https://github.com/HouzuoGuo/ScalaDB/tree/master/src/test
(Good place to have a look at how MUT is used in real scenarios)