baretest 0.1.0 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +52 -0
- data/MANIFEST.txt +50 -31
- data/README.rdoc +260 -0
- data/bin/baretest +82 -24
- data/doc/baretest.rdoc +98 -0
- data/doc/mocking_stubbing_test_doubles.rdoc +5 -0
- data/doc/quickref.rdoc +261 -0
- data/doc/writing_tests.rdoc +148 -0
- data/examples/test.rake +58 -30
- data/examples/tests/irb_mode/failures.rb +26 -0
- data/examples/tests/mock_developer/test/helper/mocks.rb +0 -0
- data/examples/tests/mock_developer/test/setup.rb +57 -0
- data/examples/tests/mock_developer/test/suite/mock_demo.rb +19 -0
- data/examples/tests/overview/test.rb +89 -0
- data/examples/tests/variations/variations_01.rb +14 -0
- data/examples/tests/variations/variations_02.rb +19 -0
- data/examples/tests/variations/variations_03.rb +19 -0
- data/lib/baretest/assertion/context.rb +20 -0
- data/lib/baretest/assertion/failure.rb +22 -0
- data/lib/baretest/assertion/skip.rb +21 -0
- data/lib/{test → baretest}/assertion/support.rb +174 -39
- data/lib/baretest/assertion.rb +182 -0
- data/lib/baretest/irb_mode.rb +263 -0
- data/lib/{test/assertion/failure.rb → baretest/layout.rb} +6 -5
- data/lib/baretest/mocha.rb +18 -0
- data/lib/baretest/run/cli.rb +104 -0
- data/lib/{test → baretest}/run/errors.rb +12 -7
- data/lib/{test → baretest}/run/minimal.rb +8 -3
- data/lib/baretest/run/profile.rb +151 -0
- data/lib/{test → baretest}/run/spec.rb +10 -4
- data/lib/baretest/run/tap.rb +44 -0
- data/lib/baretest/run/xml.rb +80 -0
- data/lib/{test → baretest}/run.rb +31 -18
- data/lib/baretest/setup.rb +15 -0
- data/lib/baretest/skipped/assertion.rb +20 -0
- data/lib/baretest/skipped/suite.rb +49 -0
- data/lib/baretest/skipped.rb +15 -0
- data/lib/baretest/suite.rb +234 -0
- data/lib/baretest/utilities.rb +43 -0
- data/lib/{test → baretest}/version.rb +12 -3
- data/lib/baretest.rb +112 -0
- data/test/external/bootstraptest.rb +1 -1
- data/test/setup.rb +1 -1
- data/test/{lib/test → suite/lib/baretest}/assertion/support.rb +78 -24
- data/test/suite/lib/baretest/assertion.rb +192 -0
- data/test/{lib/test → suite/lib/baretest}/irb_mode.rb +0 -0
- data/test/{lib/test → suite/lib/baretest}/run/cli.rb +0 -0
- data/test/{lib/test → suite/lib/baretest}/run/errors.rb +0 -0
- data/test/{lib/test → suite/lib/baretest}/run/interactive.rb +0 -0
- data/test/{lib/test → suite/lib/baretest}/run/spec.rb +0 -0
- data/test/{lib/test → suite/lib/baretest}/run/tap.rb +0 -0
- data/test/{lib/test → suite/lib/baretest}/run/xml.rb +0 -0
- data/test/{lib/test → suite/lib/baretest}/run.rb +63 -61
- data/test/{lib/test → suite/lib/baretest}/suite.rb +77 -54
- data/test/{lib/test.rb → suite/lib/baretest.rb} +37 -37
- metadata +61 -40
- data/README.markdown +0 -229
- data/examples/test.rb +0 -93
- data/lib/test/assertion.rb +0 -117
- data/lib/test/debug.rb +0 -34
- data/lib/test/irb_mode.rb +0 -104
- data/lib/test/run/cli.rb +0 -79
- data/lib/test/run/interactive.rb +0 -60
- data/lib/test/run/tap.rb +0 -32
- data/lib/test/run/xml.rb +0 -56
- data/lib/test/suite.rb +0 -95
- data/lib/test.rb +0 -118
- data/test/lib/test/assertion.rb +0 -142
- data/test/lib/test/debug.rb +0 -63
data/doc/quickref.rdoc
ADDED
@@ -0,0 +1,261 @@
|
|
1
|
+
= BareTest Quick Reference
|
2
|
+
|
3
|
+
This is a very condensed overview over baretest. If you're new to testing and
|
4
|
+
new to baretest, you may be more interested into doc/writing_tests.rdoc
|
5
|
+
Also look into the examples and baretests own test directory.
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
== Setup baretest
|
10
|
+
|
11
|
+
1. Install baretest
|
12
|
+
a) official release: `sudo gem install baretest`
|
13
|
+
b) edge:
|
14
|
+
1. git clone git://github.com/apeiros/baretest.git
|
15
|
+
2. cd baretest
|
16
|
+
3. rake gem:install
|
17
|
+
2. Change into the project directory
|
18
|
+
3. `baretest --init` to create the basic test-directory layout
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
== Location of testfiles
|
23
|
+
|
24
|
+
Your tests for PROJECT/lib/foo.rb belong into PROJECT/test/suite/lib/foo.rb.
|
25
|
+
Your tests for PROJECT/bin/bar belong into PROJECT/test/suite/bin/bar.
|
26
|
+
In other words, for every path, insert /test/suite after PROJECT to get the
|
27
|
+
path to the corresponding testfile.
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
== Writing tests
|
32
|
+
|
33
|
+
A testfile commonly looks like this:
|
34
|
+
|
35
|
+
BareTest.suite "module ModuleName" do
|
36
|
+
setup do
|
37
|
+
# This is run before each assert, that is in this suite or a nested suite
|
38
|
+
end
|
39
|
+
|
40
|
+
teardown do
|
41
|
+
# This is run after each assert, that is in this suite or a nested suite
|
42
|
+
end
|
43
|
+
|
44
|
+
suite "Class methods" do
|
45
|
+
setup do
|
46
|
+
# things used by most nested suites
|
47
|
+
end
|
48
|
+
|
49
|
+
suite "ModuleName::class_method_name" do
|
50
|
+
assert "does this" do
|
51
|
+
...
|
52
|
+
end
|
53
|
+
|
54
|
+
assert "does that" do
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
suite "Instance methods" do
|
59
|
+
suite "ModuleName#instance_method_name" do
|
60
|
+
...
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
suite "class ClassName" do # this is class ModuleName::ClassName
|
65
|
+
suite "Class methods" do
|
66
|
+
...
|
67
|
+
end
|
68
|
+
|
69
|
+
suite "Instance methods" do
|
70
|
+
...
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
This layout makes it easy to figure where tests for something are, and thus
|
76
|
+
makes maintaining the test-code base easier.
|
77
|
+
|
78
|
+
Setup callbacks are invoked from outermost suite to innermost suite, and
|
79
|
+
within the same suite, in the order of definition.
|
80
|
+
|
81
|
+
Teardown callbacks are invoked from innermost suite to outermost suite, and
|
82
|
+
within the same suite, in the order of definition.
|
83
|
+
|
84
|
+
BareTest.suite do
|
85
|
+
setup do puts 1 end
|
86
|
+
setup do puts 2 end
|
87
|
+
teardown do puts 7 end
|
88
|
+
teardown do puts 8 end
|
89
|
+
|
90
|
+
suite "Inner" do
|
91
|
+
setup do puts 3 end
|
92
|
+
setup do puts 4 end
|
93
|
+
teardown do puts 5 end
|
94
|
+
teardown do puts 6 end
|
95
|
+
|
96
|
+
assert "Inner - assert" do puts "Inner - assert" end
|
97
|
+
end
|
98
|
+
|
99
|
+
assert "Outer - assert" do puts "Outer - assert" end
|
100
|
+
end
|
101
|
+
|
102
|
+
Running this suite will print:
|
103
|
+
|
104
|
+
1
|
105
|
+
2
|
106
|
+
3
|
107
|
+
4
|
108
|
+
Inner - assert
|
109
|
+
5
|
110
|
+
6
|
111
|
+
7
|
112
|
+
8
|
113
|
+
1
|
114
|
+
2
|
115
|
+
Outer - assert
|
116
|
+
7
|
117
|
+
8
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
== Skipping Tests and Suites
|
122
|
+
|
123
|
+
A test is skipped if it does not have a block or calls 'skip'
|
124
|
+
|
125
|
+
== Assertion helper methods
|
126
|
+
|
127
|
+
See BareTest::Assertion::Support
|
128
|
+
All methods that have the method signature foo(expected, actual, message=nil)
|
129
|
+
can alternatively be used with named arguments:
|
130
|
+
foo a, b, "message" # is equivalent to:
|
131
|
+
foo :expected => a, :actual => b, :message => "message"
|
132
|
+
|
133
|
+
* skip(message, *args)
|
134
|
+
Description: Skips the assertion, uses sprintf with message and *args
|
135
|
+
Success: not possible
|
136
|
+
Failure: not possible
|
137
|
+
|
138
|
+
* failure(message, *args)
|
139
|
+
Description: Lets the assertion fail, uses sprintf with message and *args
|
140
|
+
Success: not possible
|
141
|
+
Failure: failure("%p was not the inverse of %p", 2, 5)
|
142
|
+
|
143
|
+
* same(expected, actual, message=nil)
|
144
|
+
Description: Uses expected.equal?(actual), which tests for object identity
|
145
|
+
Success: same(:foo, :foo)
|
146
|
+
Failure: same("foo", "foo")
|
147
|
+
|
148
|
+
* hash_key_equal(expected, actual, message=nil)
|
149
|
+
Description: Uses expected.eql?(actual), which is used for hash key equality.
|
150
|
+
Success: hash_key_equal("foo", "foo")
|
151
|
+
Failure: hash_key_equal(1.0, 1)
|
152
|
+
|
153
|
+
* equal(expected, actual, message=nil) (alias: order_equal)
|
154
|
+
Description: Uses expected == actual, which is used for order-equality.
|
155
|
+
Success: equal(1.0, 1)
|
156
|
+
Failure: equal(1, "1")
|
157
|
+
|
158
|
+
* case_equal(expected, actual, message=nil)
|
159
|
+
Description: Uses expected === actual, which is used in case/whens.
|
160
|
+
Success: case_equal(String, "foo")
|
161
|
+
Failure: case_equal(String, 1)
|
162
|
+
|
163
|
+
* equal_unordered(expected, actual, message=nil)
|
164
|
+
Description: Compares unordered enumerables, on the enumerable it uses each,
|
165
|
+
on the items it uses hash and eql?
|
166
|
+
Success: equal_unordered([1,2], [2,1])
|
167
|
+
Failure: equal_unordered([1,2], [2,1,2])
|
168
|
+
|
169
|
+
* within_delta(a, b, delta)
|
170
|
+
Description: Tests whether the difference between a and b is less than delta
|
171
|
+
Success: within_delta(0.5, Math.sin(Math::PI/6), 1e-6)
|
172
|
+
# equal(0.5, Math.sin(Math::PI/6)) would fail
|
173
|
+
Failure: within_delta(0.5, 0.6, 0.05)
|
174
|
+
|
175
|
+
* kind_of(expected, actual, message=nil) (alias: is_a)
|
176
|
+
Description: Uses actual.kind_of?(expected)
|
177
|
+
Success: kind_of(String, "foo")
|
178
|
+
Failure: kind_of(String, 1)
|
179
|
+
|
180
|
+
* throws(symbol)
|
181
|
+
Description: Test whether the block throws the given symbol
|
182
|
+
Success: throws(:foo) do throw(:foo) end
|
183
|
+
Failure: throws(:foo) do throw(:bar) end
|
184
|
+
throws(:foo) do nil end
|
185
|
+
|
186
|
+
* throws_nothing
|
187
|
+
Description: Test whether a piece of code really throws nothing
|
188
|
+
Success: throws_nothing do nil end
|
189
|
+
Failure: throws_nothing do throw(:foo) end
|
190
|
+
|
191
|
+
* raises(exception_class=StandardError, opts={})
|
192
|
+
Description: Test whether the block raises
|
193
|
+
Success: raises do raise "foo" end
|
194
|
+
raises ArgumentError do "12".to_i(10, :superfluous) end
|
195
|
+
Failure: raises do nil end
|
196
|
+
raises ArgumentError do "12".to_i(10) end
|
197
|
+
|
198
|
+
* raises_nothing
|
199
|
+
Description: Test whether the block doesn't raise
|
200
|
+
Success: raise_nothing do nil end
|
201
|
+
Failure: raise_nothing do raise "foo" end
|
202
|
+
|
203
|
+
* touch(thing=nil)
|
204
|
+
Description: Mark reaching a point in code, e.g. that a block was invoked
|
205
|
+
Success: -> see touched
|
206
|
+
Failure: -> see touched
|
207
|
+
|
208
|
+
* touched(thing=nil, times=nil)
|
209
|
+
Description: test whether a mark for reached code was set, optionally test
|
210
|
+
whether it was set the expected number of times
|
211
|
+
Success: touch; touched
|
212
|
+
touch :thing; touched :thing
|
213
|
+
touch :thing; touch :thing; touched :thing, 2
|
214
|
+
Failure: touched
|
215
|
+
touch :thing; touched :something
|
216
|
+
touch :thing; touched :thing, 2
|
217
|
+
|
218
|
+
* not_touched(thing=nil)
|
219
|
+
Description: same as touched(thing, 0)
|
220
|
+
Success: see touched
|
221
|
+
Failure: see touched
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
== Running tests
|
226
|
+
|
227
|
+
baretest's test-cycle is:
|
228
|
+
|
229
|
+
1. Create Run instance and the toplevel suite
|
230
|
+
2. Load everything as required by the command line flags
|
231
|
+
3. Load PROJECT/test/setup.rb
|
232
|
+
4. Find PROJECT/test/suite/**/*.rb
|
233
|
+
5. Load each file found in 2., but for every file, see whether
|
234
|
+
PROJECT/test/helpers/suite/**/*.rb exists and load that first if it does
|
235
|
+
6. Invoke run on the Run instance
|
236
|
+
|
237
|
+
From there on it depends on the loaded formatters and extenders, what really
|
238
|
+
will happen. But the norm is, that suites and assertions will be executed in
|
239
|
+
order of definition.
|
240
|
+
|
241
|
+
|
242
|
+
|
243
|
+
== Debugging tests
|
244
|
+
|
245
|
+
Use `baretest -i` to run baretest in interactive mode. When a failure or an
|
246
|
+
error occurs, you have access to the following commands:
|
247
|
+
|
248
|
+
* s! - original assertions' status
|
249
|
+
* e! - error message and full backtrace
|
250
|
+
* em! - error message
|
251
|
+
* bt! - full backtrace
|
252
|
+
* iv! - all available instance variables
|
253
|
+
* cv! - all available class variables
|
254
|
+
* gv! - all available global variables
|
255
|
+
* file - file this assertion was defined in
|
256
|
+
* line - line number in the file where this assertion's definition starts
|
257
|
+
* nesting - a '>'-separated list of suite descriptions this assertion is
|
258
|
+
nested in
|
259
|
+
* description - this assertion's description
|
260
|
+
* code - code of this assertion
|
261
|
+
* help - overview over all the commands
|
@@ -0,0 +1,148 @@
|
|
1
|
+
= Writing Tests
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
This tutorial assumes you have basic ruby knowledge. It is an introduction into
|
6
|
+
baretest and testing itself.
|
7
|
+
If you're a quick study and have already good knowledge about ruby and testing,
|
8
|
+
you may be more interested in just reading the examples and the
|
9
|
+
doc/quickref.rdoc.
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
== 1. In the beginning there was the project
|
14
|
+
|
15
|
+
The first step is of course the project. Baretest was written with the
|
16
|
+
assumption of a standard ruby project layout (should work fine without too,
|
17
|
+
though - might just require a bit more work on your part).
|
18
|
+
The standard directory layout looks like this:
|
19
|
+
|
20
|
+
|-- bin (executables)
|
21
|
+
|-- doc (additional documentation)
|
22
|
+
|-- ext (native extension code will be here)
|
23
|
+
|-- examples (for the users of the lib)
|
24
|
+
|-- lib (contains the library)
|
25
|
+
|-- rake (contains rake relevant stuff)
|
26
|
+
`-- Rakefile
|
27
|
+
|
28
|
+
In your project directory, you can invoke `baretest --init`, this will
|
29
|
+
create the 'test' directory. It will mirror your project directory. That is,
|
30
|
+
it will recreate all directories nested in bin and lib within test/suite.
|
31
|
+
The directory layout of 'test' is as follows:
|
32
|
+
|
33
|
+
`-- test
|
34
|
+
|-- external (baretest ignores this directory)
|
35
|
+
|-- helper (baretest loads helper/lib/foo.rb when loading suite/lib/foo.rb)
|
36
|
+
|-- setup.rb (setup.rb is loaded as the first file when running baretest)
|
37
|
+
`-- suite (in here are the tests itself)
|
38
|
+
|-- bin (the tests for bin, PROJECT/bin is replicated here)
|
39
|
+
`-- lib (the tests for lib, PROJECT/lib is replicated here)
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
== 2. Writing the tests
|
44
|
+
|
45
|
+
Assume you have `lib/foo.rb` containing the class 'Foo'. To test it, you create
|
46
|
+
the file `test/suite/lib/foo.rb`. You start out by creating a suite for your
|
47
|
+
class:
|
48
|
+
|
49
|
+
BareTest.suite "class Foo" do
|
50
|
+
end
|
51
|
+
|
52
|
+
You're in no way limited in how you name the suites. It's an arbitrary String.
|
53
|
+
Now lets assume 'lib/foo.rb' contains the following code:
|
54
|
+
|
55
|
+
class Foo
|
56
|
+
def bar
|
57
|
+
"bar"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
Then follows the next step, we write the first assertion:
|
62
|
+
|
63
|
+
BareTest.suite do
|
64
|
+
suite "class Foo" do
|
65
|
+
assert "bar returns 'bar'" do
|
66
|
+
Foo.new.bar == 'bar'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
As you can see, the assertion is plain ruby code. The return value of the block
|
72
|
+
decides whether the assertion is considered a success (trueish value, that is
|
73
|
+
all but false and nil) or a failure (falseish value, that is false or nil).
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
== 3. Running the tests
|
78
|
+
|
79
|
+
First you change the directory to your project's root directory.
|
80
|
+
There you run `baretest`. That's it.
|
81
|
+
Baretest will now load the 'test/setup.rb' file, then it'll search in
|
82
|
+
'test/suite' for files and find 'test/suite/lib/foo.rb'. Before loading that
|
83
|
+
file, it'll see if there's also a file 'test/helpers/suite/lib/foo.rb'. If
|
84
|
+
there was, it'd load that first. After that, it loads the
|
85
|
+
'test/suite/lib/foo.rb' file. When all testfiles are discovered and loaded,
|
86
|
+
it'll run the tests.
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
== 4. Separating parts of the test
|
91
|
+
|
92
|
+
A classical test consists of four phases:
|
93
|
+
|
94
|
+
1. setup
|
95
|
+
2. exercise
|
96
|
+
3. validate
|
97
|
+
4. teardown
|
98
|
+
|
99
|
+
Baretest has setup and teardown on suites, which will be run for every assertion
|
100
|
+
the suite contains.
|
101
|
+
Exercise and validate is currently combined in the 'assert' method.
|
102
|
+
|
103
|
+
So let's make use of that and rewrite our previous test:
|
104
|
+
|
105
|
+
BareTest.suite do
|
106
|
+
suite "class Foo" do
|
107
|
+
setup do
|
108
|
+
@foo = Foo.new
|
109
|
+
end
|
110
|
+
|
111
|
+
assert "bar returns 'bar'" do
|
112
|
+
@foo.bar == 'bar'
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
In this simplistic example, this may seem like wasted time. The more complex the
|
118
|
+
setup becomes and the more assertions need the same setup, the more time a
|
119
|
+
separate setup phase saves.
|
120
|
+
It additionally helps in making intent clear: this is setup, and this is test.
|
121
|
+
|
122
|
+
|
123
|
+
== 5. When troubles strike
|
124
|
+
|
125
|
+
If one of your assertions fails or errors, you can use `baretest -i` to
|
126
|
+
investigate the issue. It will throw you into an irb session, with
|
127
|
+
self being the failing/erroring assertion and with several helpful
|
128
|
+
methods (use `help` in the irb session to get a list of those).
|
129
|
+
|
130
|
+
== Things left to be written out
|
131
|
+
* toplevel suite may have a name/description too, it'll act the same as if
|
132
|
+
there was a suite in an unnamed toplevel suite
|
133
|
+
* [setup] They will also be run for every nested suite's assertion,
|
134
|
+
where the outermost setup is run first, the innermost last.
|
135
|
+
* using stubs & mocks
|
136
|
+
* However, suites with the same name are considered the same.
|
137
|
+
|
138
|
+
For example, this code:
|
139
|
+
|
140
|
+
BareTest.suite "class Foo" do
|
141
|
+
suite "class Bar" do
|
142
|
+
assert "foo"
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
Just like ruby's
|
147
|
+
namespacing works. That is, if you twice do `module X; class Y; ...; end; end`,
|
148
|
+
it will both times open the same class X::Y.
|
data/examples/test.rake
CHANGED
@@ -1,37 +1,65 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2009 by Stefan Rusterholz.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
|
1
9
|
# This rake task expects to be in PROJECT_DIR/tasks/test.rake
|
2
10
|
# It assumes that the tests are in PROJECT_DIR/test/**/*.rb
|
3
11
|
# This is relevant as it calculates the paths accordingly.
|
4
|
-
#
|
12
|
+
# It uses BareTest.load_standard_test_files to load setup and test files.
|
13
|
+
# This means it will also load a test/setup.rb file if present, where
|
14
|
+
# you can add paths to $LOAD_PATH.
|
5
15
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
lib_dir = File.expand_path("#{rake_file}/../../lib")
|
16
|
+
namespace :test do
|
17
|
+
desc "Information about how your test directory should look."
|
18
|
+
task :structure do
|
19
|
+
wd = File.expand_path(Dir.getwd)
|
20
|
+
rake_file = File.expand_path(__FILE__)
|
21
|
+
test_dir = ['./test', "#{rake_file}/../../test"].map { |path|
|
22
|
+
full = File.expand_path(path)
|
23
|
+
relative = full[(wd.size+1)..-1]
|
24
|
+
"* #{relative} (#{full})"
|
25
|
+
}
|
17
26
|
|
18
|
-
|
19
|
-
|
20
|
-
"your directory structure first." unless File.directory?(test_dir)
|
27
|
+
puts "rake test:run expects to find one of the these directories:", *test_dir
|
28
|
+
end
|
21
29
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
30
|
+
desc "Run testsuite. Set FORMAT env variable to change the formatter used, INTERACTIVE to have irb mode."
|
31
|
+
task :run do
|
32
|
+
begin
|
33
|
+
require 'baretest'
|
34
|
+
rescue LoadError => e
|
35
|
+
puts "Could not run tests: #{e}"
|
36
|
+
else
|
37
|
+
# Prepare paths
|
38
|
+
rake_file = File.expand_path(__FILE__)
|
39
|
+
test_dir = ["#{rake_file}/../../test", './test'].map { |path|
|
40
|
+
File.expand_path(path)
|
41
|
+
}.find { |path|
|
42
|
+
File.directory?(path)
|
43
|
+
}
|
44
|
+
|
45
|
+
# Verify that the test directory exists
|
46
|
+
raise "Could not determine test directory, please adapt this rake task to " \
|
47
|
+
"your directory structure first (see rake test:structure)." unless test_dir
|
48
|
+
|
49
|
+
# Load all test definitions
|
50
|
+
BareTest.load_standard_test_files(
|
51
|
+
:verbose => $VERBOSE,
|
52
|
+
:setup_file => 'test/setup.rb',
|
53
|
+
:chdir => File.dirname(test_dir) # must chdir to 1 above the 'test' dir
|
54
|
+
)
|
55
|
+
|
56
|
+
# Run all tests
|
57
|
+
format = ENV["FORMAT"] || 'cli'
|
58
|
+
interactive = ENV["INTERACTIVE"] == 'true'
|
59
|
+
BareTest.run(:format => format, :interactive => interactive)
|
60
|
+
end
|
61
|
+
end
|
37
62
|
end
|
63
|
+
|
64
|
+
desc 'Alias for test:run'
|
65
|
+
task :test => 'test:run'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2009 by Stefan Rusterholz.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
BareTest.suite "Failure" do
|
10
|
+
setup do
|
11
|
+
@a = 1
|
12
|
+
@b = 2
|
13
|
+
end
|
14
|
+
|
15
|
+
assert "This one should fail and thus drop you into irb" do
|
16
|
+
c = 3
|
17
|
+
d = 4
|
18
|
+
@a == d
|
19
|
+
end
|
20
|
+
|
21
|
+
assert "This one should error and thus drop you into irb" do
|
22
|
+
c = 3
|
23
|
+
d = 4
|
24
|
+
raise "error!"
|
25
|
+
end
|
26
|
+
end
|
File without changes
|
@@ -0,0 +1,57 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path("#{__FILE__}/../../lib"))
|
2
|
+
require 'baretest'
|
3
|
+
|
4
|
+
BareTest.toplevel_suite.setup do
|
5
|
+
@_mymockname = {
|
6
|
+
:mocks => [],
|
7
|
+
:failures => [],
|
8
|
+
:exceptions => []
|
9
|
+
}
|
10
|
+
end
|
11
|
+
BareTest.toplevel_suite.teardown do
|
12
|
+
@_mymockname[:mocks].each { |mock|
|
13
|
+
mock.teardown(@_mymockname)
|
14
|
+
}
|
15
|
+
unless @_mymockname[:exceptions].empty? then
|
16
|
+
@reason = "An error occurred"
|
17
|
+
@exception = @_mymockname[:exceptions].first
|
18
|
+
@status = :error
|
19
|
+
end
|
20
|
+
unless @status == :error || @_mymockname[:failures].empty?
|
21
|
+
@reason = @_mymockname[:failures].first
|
22
|
+
@status = :failure
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class DemoMock
|
27
|
+
class Error < StandardError; end
|
28
|
+
|
29
|
+
def initialize(action, message)
|
30
|
+
@action, @message = action, message
|
31
|
+
end
|
32
|
+
|
33
|
+
def teardown(recorder)
|
34
|
+
case @action
|
35
|
+
when :fail
|
36
|
+
recorder[:failures] << @message
|
37
|
+
when :raise
|
38
|
+
raise @message
|
39
|
+
end
|
40
|
+
rescue Error => e
|
41
|
+
recorder[:exceptions] << e
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module MockSupport
|
46
|
+
def demo_mock(*args, &block)
|
47
|
+
mock = DemoMock.new(*args, &block)
|
48
|
+
@_mymockname[:mocks] << mock
|
49
|
+
mock
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
module BareTest
|
54
|
+
class Assertion
|
55
|
+
include MockSupport
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
BareTest.suite "MockDemo" do
|
2
|
+
suite "nothing happens" do
|
3
|
+
assert "Success" do
|
4
|
+
demo_mock(nil, nil)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
suite "mock fails" do
|
9
|
+
assert "Failure" do
|
10
|
+
demo_mock(:fail, "this is the mock failure message")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
suite "mock errors" do
|
15
|
+
assert "Exception" do
|
16
|
+
demo_mock(:raise, DemoMock::Error.new("mock errors message"))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
BareTest.suite do
|
2
|
+
# assertions and refutations can be grouped in suites. They will share
|
3
|
+
# setup and teardown
|
4
|
+
# they don't have to be in suites, though
|
5
|
+
suite "Success" do
|
6
|
+
assert "An assertion returning a trueish value (non nil/false) is a success" do
|
7
|
+
true
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
suite "Failure" do
|
12
|
+
assert "An assertion returning a falsish value (nil/false) is a failure" do
|
13
|
+
false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
suite "Pending" do
|
18
|
+
assert "An assertion without a block is pending"
|
19
|
+
end
|
20
|
+
|
21
|
+
suite "Error" do
|
22
|
+
assert "Uncaught exceptions in an assertion are an error" do
|
23
|
+
raise "Error!"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
suite "Special assertions" do
|
28
|
+
assert "Assert a block to raise" do
|
29
|
+
raises do
|
30
|
+
sleep(rand()/3+0.05)
|
31
|
+
raise "If this raises then the assertion is a success"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
assert "Assert a float to be close to another" do
|
36
|
+
a = 0.18 - 0.01
|
37
|
+
b = 0.17
|
38
|
+
within_delta a, b, 0.001
|
39
|
+
end
|
40
|
+
|
41
|
+
suite "Nested suite" do
|
42
|
+
assert "Assert two randomly ordered arrays to contain the same values" do
|
43
|
+
a = [*"A".."Z"] # an array with values from A to Z
|
44
|
+
b = a.sort_by { rand }
|
45
|
+
equal_unordered(a, b) # can be used with any Enumerable, uses hash-key identity
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
suite "Setup & Teardown" do
|
51
|
+
setup do
|
52
|
+
@foo = "foo"
|
53
|
+
@bar = "bar"
|
54
|
+
end
|
55
|
+
|
56
|
+
assert "@foo should be set" do
|
57
|
+
@foo == "foo"
|
58
|
+
end
|
59
|
+
|
60
|
+
suite "Nested suite" do
|
61
|
+
setup do
|
62
|
+
@bar = "inner bar"
|
63
|
+
@baz = "baz"
|
64
|
+
end
|
65
|
+
|
66
|
+
assert "@foo is inherited" do
|
67
|
+
@foo == "foo"
|
68
|
+
end
|
69
|
+
|
70
|
+
assert "@bar is overridden" do
|
71
|
+
@bar == "inner bar"
|
72
|
+
end
|
73
|
+
|
74
|
+
assert "@baz is defined only for inner" do
|
75
|
+
@baz == "baz"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
teardown do
|
80
|
+
@foo = nil # not that it'd make much sense, just to demonstrate
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
suite "Dependencies", :requires => ['foo', 'bar'] do
|
85
|
+
assert "Will be skipped, due to unsatisfied dependencies" do
|
86
|
+
failure "Why the heck do you have a 'foo/bar' file?"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|