baretest 0.1.0 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|