baretest 0.2.4 → 0.4.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +6 -6
- data/MANIFEST.txt +40 -18
- data/README.rdoc +8 -1
- data/bin/baretest +126 -118
- data/doc/baretest.rdoc +1 -1
- data/doc/mocking_stubbing_test_doubles.rdoc +31 -3
- data/doc/news/news-0.3.0.rdoc +7 -0
- data/doc/quickref.rdoc +74 -28
- data/doc/whats_going_on.rdoc +5 -0
- data/doc/writing_tests.rdoc +25 -13
- data/examples/components/rack-test.rb +17 -0
- data/examples/{tests/irb_mode → irb_mode}/failures.rb +0 -0
- data/examples/rake/test.rake +40 -0
- data/examples/tests/01_basics_I.rb +34 -0
- data/examples/tests/02_basics_II_helpers.rb +25 -0
- data/examples/tests/03_basics_III_setup_and_teardown.rb +53 -0
- data/examples/tests/04_advanced_I_dependencies.rb +31 -0
- data/examples/tests/05_advanced_II_tags.rb +12 -0
- data/examples/tests/06_advanced_III_requires.rb +21 -0
- data/examples/tests/07_advanced_IV_components.rb +48 -0
- data/examples/tests/08_expert_I_setup_variants.rb +46 -0
- data/lib/baretest.rb +142 -21
- data/lib/baretest/assertion.rb +83 -92
- data/lib/baretest/assertion/context.rb +9 -0
- data/lib/baretest/assertion/support.rb +88 -61
- data/lib/baretest/commandline.rb +268 -0
- data/lib/baretest/formatter.rb +58 -0
- data/lib/baretest/invalidselectors.rb +24 -0
- data/lib/baretest/irb_mode.rb +100 -58
- data/lib/baretest/persistence.rb +94 -0
- data/lib/baretest/run.rb +138 -37
- data/lib/baretest/run/cli.rb +97 -43
- data/lib/baretest/run/minimal.rb +2 -1
- data/lib/baretest/run/none.rb +21 -0
- data/lib/baretest/run/xml.rb +21 -19
- data/lib/baretest/setup.rb +2 -0
- data/lib/baretest/status.rb +93 -0
- data/lib/baretest/suite.rb +185 -59
- data/lib/baretest/uid.rb +51 -0
- data/lib/baretest/use/mocha.rb +24 -0
- data/lib/baretest/use/rack_test.rb +9 -0
- data/lib/baretest/use/rr.rb +17 -0
- data/lib/baretest/version.rb +18 -4
- data/lib/command.rb +36 -0
- data/lib/command/argument.rb +11 -0
- data/lib/command/decoratinghash.rb +31 -0
- data/lib/command/definition.rb +294 -0
- data/lib/command/directorynotfounderror.rb +11 -0
- data/lib/command/env.rb +11 -0
- data/lib/command/filenotfounderror.rb +11 -0
- data/lib/command/kernel.rb +14 -0
- data/lib/command/nodirectoryerror.rb +11 -0
- data/lib/command/nofileerror.rb +11 -0
- data/lib/command/option.rb +16 -0
- data/lib/command/parser.rb +145 -0
- data/lib/command/result.rb +11 -0
- data/lib/command/types.rb +33 -0
- data/lib/command/version.rb +28 -0
- data/test/setup.rb +3 -0
- data/test/suite/lib/baretest.rb +0 -178
- data/test/suite/lib/baretest/assertion.rb +133 -112
- data/test/suite/lib/baretest/assertion/context.rb +40 -0
- data/test/suite/lib/baretest/assertion/failure.rb +19 -0
- data/test/suite/lib/baretest/assertion/skip.rb +19 -0
- data/test/suite/lib/baretest/assertion/support.rb +366 -84
- data/test/suite/lib/baretest/run.rb +114 -15
- data/test/suite/lib/baretest/suite.rb +70 -29
- metadata +46 -24
- data/examples/test.rake +0 -65
- data/examples/tests/mock_developer/test/helper/mocks.rb +0 -0
- data/examples/tests/mock_developer/test/setup.rb +0 -57
- data/examples/tests/mock_developer/test/suite/mock_demo.rb +0 -19
- data/examples/tests/overview/test.rb +0 -89
- data/examples/tests/variations/variations_01.rb +0 -14
- data/examples/tests/variations/variations_02.rb +0 -19
- data/examples/tests/variations/variations_03.rb +0 -19
- data/lib/baretest/mocha.rb +0 -18
- data/lib/baretest/rr.rb +0 -16
- data/lib/baretest/run/errors.rb +0 -49
- data/lib/baretest/skipped.rb +0 -15
- data/lib/baretest/skipped/assertion.rb +0 -20
- data/lib/baretest/skipped/suite.rb +0 -49
- data/test/external/bootstraptest.rb +0 -5
- data/test/external/bootstrapwrap.rb +0 -2
- data/test/helper/mocks.rb +0 -0
data/doc/quickref.rdoc
CHANGED
@@ -14,8 +14,10 @@ Also look into the examples and baretests own test directory.
|
|
14
14
|
1. git clone git://github.com/apeiros/baretest.git
|
15
15
|
2. cd baretest
|
16
16
|
3. rake gem:install
|
17
|
+
If 3. fails, try deleting the MANIFEST.txt and do `rake manifest:create`.
|
18
|
+
Then try step 3 again. Also you must have nokogiri and rdoc >=2.3 installed.
|
17
19
|
2. Change into the project directory
|
18
|
-
3. `baretest
|
20
|
+
3. `baretest init` to create the basic test-directory layout
|
19
21
|
|
20
22
|
|
21
23
|
|
@@ -25,11 +27,17 @@ Your tests for PROJECT/lib/foo.rb belong into PROJECT/test/suite/lib/foo.rb.
|
|
25
27
|
Your tests for PROJECT/bin/bar belong into PROJECT/test/suite/bin/bar.
|
26
28
|
In other words, for every path, insert /test/suite after PROJECT to get the
|
27
29
|
path to the corresponding testfile.
|
30
|
+
Besides 'suite', baretest also recognizes 'integration', 'unit', and 'system'
|
31
|
+
as directories. You can use these to separate different concerns of your suite.
|
28
32
|
|
29
33
|
|
30
34
|
|
31
35
|
== Writing tests
|
32
36
|
|
37
|
+
One way to to learn baretest is to simply look at the examples in
|
38
|
+
'examples/tests'. They should provide you with enough information for a quick
|
39
|
+
start into writing tests using baretest.
|
40
|
+
|
33
41
|
A testfile commonly looks like this:
|
34
42
|
|
35
43
|
BareTest.suite "module ModuleName" do
|
@@ -73,7 +81,7 @@ A testfile commonly looks like this:
|
|
73
81
|
end
|
74
82
|
|
75
83
|
This layout makes it easy to figure where tests for something are, and thus
|
76
|
-
makes maintaining the
|
84
|
+
makes maintaining the testcodebase easier.
|
77
85
|
|
78
86
|
Setup callbacks are invoked from outermost suite to innermost suite, and
|
79
87
|
within the same suite, in the order of definition.
|
@@ -118,9 +126,40 @@ Running this suite will print:
|
|
118
126
|
|
119
127
|
|
120
128
|
|
121
|
-
== Skipping
|
129
|
+
== Skipping and ignoring Suites and Assertions
|
130
|
+
|
131
|
+
A suite is pending if it either has no block or a block which contains no
|
132
|
+
assertions and suites.
|
133
|
+
|
134
|
+
You can skip a suite by:
|
135
|
+
* Creating the suite with a :skip option, like
|
136
|
+
`suite "MySuite", :skip => "I want to skip this suite" do`
|
137
|
+
* Calling skip in the suite, like
|
138
|
+
suite "MySuite" do
|
139
|
+
skip "I want to skip this suite"
|
140
|
+
end
|
141
|
+
You can call skip at any point in the suite.
|
142
|
+
|
143
|
+
You can ignore a suite by:
|
144
|
+
* Adding one or more tags to the suite, like
|
145
|
+
`suite "MySuite", :tags => [:set_x, :set_y]`
|
146
|
+
And then specify any of those tags to be ignored, like:
|
147
|
+
`baretest -- -:set_x`
|
148
|
+
|
149
|
+
An assertion is pending if it has no block.
|
150
|
+
|
151
|
+
You can skip an assertion by:
|
152
|
+
* Having it in a suite that is skipped
|
153
|
+
* Creating the assertion with a :skip option, like
|
154
|
+
`assert "Something", :skip => "I want to skip this assertion" do`
|
155
|
+
* Calling skip in the assertion, like
|
156
|
+
assert "Something" do
|
157
|
+
skip "I want to skip this assertion"
|
158
|
+
end
|
159
|
+
You can call skip at any point in the assertion.
|
122
160
|
|
123
|
-
|
161
|
+
You can ignore an assertion by:
|
162
|
+
* Having it in a suite that is ignored
|
124
163
|
|
125
164
|
== Assertion helper methods
|
126
165
|
|
@@ -226,13 +265,15 @@ can alternatively be used with named arguments:
|
|
226
265
|
|
227
266
|
baretest's test-cycle is:
|
228
267
|
|
229
|
-
1. Create
|
230
|
-
2. Load
|
231
|
-
3.
|
232
|
-
|
233
|
-
|
234
|
-
PROJECT/test/helpers
|
235
|
-
|
268
|
+
1. Create the toplevel suite
|
269
|
+
2. Load PROJECT/test/setup.rb
|
270
|
+
3. Find every file as required by the command line flags (defaults to
|
271
|
+
PROJECT/test/{suite,unit,integration,system}/**/*.rb)
|
272
|
+
4. Load each file found in 3., but for every file, see whether
|
273
|
+
PROJECT/test/helpers/**/*.rb exists and load that first if it does
|
274
|
+
(e.g. for PROJECT/test/suite/foo.rb load PROJECT/test/helpers/suite/foo.rb)
|
275
|
+
5. Create a BareTest::Run instance with the toplevel suite and the passed options
|
276
|
+
6. Invoke run_all on that Run instance.
|
236
277
|
|
237
278
|
From there on it depends on the loaded formatters and extenders, what really
|
238
279
|
will happen. But the norm is, that suites and assertions will be executed in
|
@@ -242,20 +283,25 @@ order of definition.
|
|
242
283
|
|
243
284
|
== Debugging tests
|
244
285
|
|
245
|
-
Use `baretest -i` to run baretest in interactive mode.
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
286
|
+
Use `baretest -i` to run baretest in interactive mode. Try it with
|
287
|
+
`baretest -i examples/irb_mode/failures.rb`
|
288
|
+
When a failure or an error occurs, you have access to the following commands:
|
289
|
+
|
290
|
+
help!:: overview over all the commands
|
291
|
+
s!:: the assertions' original status
|
292
|
+
sc!:: the assertions' original status code
|
293
|
+
e!:: prints the error message and full backtrace
|
294
|
+
em!:: prints the error message
|
295
|
+
bt!:: prints the full backtrace
|
296
|
+
lv!:: lists all available local variables
|
297
|
+
iv!:: lists all available instance variables
|
298
|
+
cv!:: lists all available class variables
|
299
|
+
gv!:: lists all available global variables, per default dropping rubys
|
300
|
+
standard globals (use gv!(false) to avoid that)
|
301
|
+
file!:: the file this assertion was defined in
|
302
|
+
line!:: the line number in the file where this assertion's definition
|
303
|
+
starts
|
304
|
+
nesting!:: a '>'-separated list of suite descriptions this assertion is
|
305
|
+
nested in
|
306
|
+
description!:: this assertion's description
|
307
|
+
code!:: code of this assertion
|
data/doc/whats_going_on.rdoc
CHANGED
data/doc/writing_tests.rdoc
CHANGED
@@ -25,7 +25,7 @@ The standard directory layout looks like this:
|
|
25
25
|
|-- rake (contains rake relevant stuff)
|
26
26
|
`-- Rakefile
|
27
27
|
|
28
|
-
In your project directory, you can invoke `baretest
|
28
|
+
In your project directory, you can invoke `baretest init`, this will
|
29
29
|
create the 'test' directory. It will mirror your project directory. That is,
|
30
30
|
it will recreate all directories nested in bin and lib within test/suite.
|
31
31
|
The directory layout of 'test' is as follows:
|
@@ -118,31 +118,43 @@ In this simplistic example, this may seem like wasted time. The more complex the
|
|
118
118
|
setup becomes and the more assertions need the same setup, the more time a
|
119
119
|
separate setup phase saves.
|
120
120
|
It additionally helps in making intent clear: this is setup, and this is test.
|
121
|
+
The setup and teardown is run (via instance_eval) in the same context as the
|
122
|
+
assertion. Local variables however are NOT shared. To pass data from the setup
|
123
|
+
to the assertion, use instance variables as shown here.
|
124
|
+
|
121
125
|
|
122
126
|
|
123
127
|
== 5. When troubles strike
|
124
128
|
|
125
129
|
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
|
-
|
128
|
-
|
130
|
+
investigate the issue. It will throw you into an irb session, with self being
|
131
|
+
the failing/erroring assertion context and with several helpful methods (use
|
132
|
+
`help` in the irb session to get a list of those).
|
129
133
|
|
130
134
|
== Things left to be written out
|
135
|
+
|
136
|
+
This is not part of the tutorial but things the author of this tutorial should
|
137
|
+
still add to the tutorial itself.
|
138
|
+
|
131
139
|
* toplevel suite may have a name/description too, it'll act the same as if
|
132
140
|
there was a suite in an unnamed toplevel suite
|
133
141
|
* [setup] They will also be run for every nested suite's assertion,
|
134
142
|
where the outermost setup is run first, the innermost last.
|
135
143
|
* using stubs & mocks
|
136
|
-
*
|
144
|
+
* Suites with the same name and nesting are considered the same and become
|
145
|
+
merged
|
137
146
|
|
138
|
-
|
147
|
+
Example:
|
139
148
|
|
140
|
-
BareTest.suite "
|
141
|
-
suite "
|
142
|
-
assert "
|
149
|
+
BareTest.suite "Foo" do
|
150
|
+
suite "Bar" do
|
151
|
+
assert "x"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
BareTest.suite "Foo" do
|
155
|
+
suite "Bar" do
|
156
|
+
assert "y"
|
157
|
+
end
|
143
158
|
end
|
144
159
|
|
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.
|
160
|
+
Now the suite "Foo" > "Bar" has two assertions, "x" and "y"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
MiniApp = proc { |*a| [200, {'Content-Type' => 'text/plain'}, "hello world"] }
|
2
|
+
|
3
|
+
BareTest.suite "Rack-Test", :use => :rack_test do
|
4
|
+
setup do
|
5
|
+
@app = MiniApp
|
6
|
+
end
|
7
|
+
|
8
|
+
assert "Requesting '/' is 200 OK" do
|
9
|
+
get '/'
|
10
|
+
last_response.ok?
|
11
|
+
end
|
12
|
+
|
13
|
+
assert "Requesting / gets the body 'hello world'" do
|
14
|
+
get '/'
|
15
|
+
equal 'hello world', last_response.body
|
16
|
+
end
|
17
|
+
end
|
File without changes
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright 2009-2010 by Stefan Rusterholz.
|
3
|
+
# All rights reserved.
|
4
|
+
# See LICENSE.txt for permissions.
|
5
|
+
#++
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
# This rake task collects some ENV variables and then delegates to duty to
|
10
|
+
# BareTest::CommandLine#run
|
11
|
+
|
12
|
+
namespace :test do
|
13
|
+
desc "Information about how your test directory should look."
|
14
|
+
task :structure do
|
15
|
+
project_dir = File.expand_path(Dir.getwd)
|
16
|
+
|
17
|
+
puts "rake test:run expects to the directory test (#{File.expand_path(project_dir)}/test) to exist."
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Run testsuite. Set FORMAT env variable to change the formatter used, INTERACTIVE to 'true' to have irb mode."
|
21
|
+
task :run do
|
22
|
+
begin
|
23
|
+
require 'baretest'
|
24
|
+
rescue LoadError => e
|
25
|
+
puts "Could not run tests: #{e}"
|
26
|
+
else
|
27
|
+
# Options can only be supplied via ENV
|
28
|
+
options = {
|
29
|
+
:format => (ENV["FORMAT"] || 'cli'),
|
30
|
+
:interactive => (ENV["INTERACTIVE"] =~ /^[ty]/i), # true, TRUE, yes, YES or abbreviated
|
31
|
+
}
|
32
|
+
|
33
|
+
# Run all tests
|
34
|
+
BareTest::CommandLine.run([], options)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
desc 'Alias for test:run'
|
40
|
+
task :test => 'test:run'
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# To start the test definition you do `BareTest.suite do ...`, see
|
2
|
+
# BareTest::Suite::new for more
|
3
|
+
BareTest.suite do
|
4
|
+
|
5
|
+
# The individual tests can be grouped into suites
|
6
|
+
suite "Success" do
|
7
|
+
|
8
|
+
# A test is defined via
|
9
|
+
# assert "description of what we assert" do
|
10
|
+
# (the assertion itself)
|
11
|
+
# end
|
12
|
+
# Where the return value (and/or whether it raises or throws something)
|
13
|
+
# defines its status
|
14
|
+
assert "Returning a trueish value (non nil/false) is a success" do
|
15
|
+
true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
suite "Failure" do
|
20
|
+
assert "Returning a falsish value (nil/false) is a failure" do
|
21
|
+
false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
suite "Pending" do
|
26
|
+
assert "Without a block is pending"
|
27
|
+
end
|
28
|
+
|
29
|
+
suite "Error" do
|
30
|
+
assert "Uncaught exceptions are an error" do
|
31
|
+
raise "Error!"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
BareTest.suite do
|
2
|
+
assert "The given block raises" do
|
3
|
+
raises do
|
4
|
+
raise "If this raises then the assertion is a success"
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
assert "The given block raises a specific exception" do
|
9
|
+
raises ArgumentError do # if you want to use {} instead of do/end, you must use parens: raises(ArgumentError) { ... }
|
10
|
+
raise ArgumentError, "If this raises then the assertion is a success"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
assert "Assert a float to be close to another" do
|
15
|
+
a = 0.18 - 0.01
|
16
|
+
b = 0.17
|
17
|
+
within_delta a, b, 0.001 # using a == b would be false, because a == 0.169... and b == 1.70...
|
18
|
+
end
|
19
|
+
|
20
|
+
assert "Assert two randomly ordered arrays to contain the same values" do
|
21
|
+
a = [*"A".."Z"] # an array with values from A to Z
|
22
|
+
b = a.sort_by { rand }
|
23
|
+
equal_unordered(a, b) # can be used with any Enumerable, uses hash-key identity
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
BareTest.suite do
|
2
|
+
suite "Setup & Teardown" do
|
3
|
+
# All setup blocks are executed, so adding another setup block will not
|
4
|
+
# replace an existing one. They are executed in order of definition and
|
5
|
+
# before *each* execution of an assert.
|
6
|
+
setup do
|
7
|
+
@foo = "foo"
|
8
|
+
end
|
9
|
+
|
10
|
+
assert "@foo should be set" do
|
11
|
+
equal("foo", @foo)
|
12
|
+
end
|
13
|
+
|
14
|
+
# All teardown blocks are executed, so adding another teardown block will
|
15
|
+
# not replace an existing one. They are executed in order of definition and
|
16
|
+
# after *each* execution of an assert.
|
17
|
+
teardown do
|
18
|
+
@foo = nil # setting an instance variable to nil isn't really necessary,
|
19
|
+
# but f.ex. closing an open file handle or similar is a good
|
20
|
+
# idea.
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
suite "Nested Setup & Teardown" do
|
25
|
+
setup do
|
26
|
+
@outer_setup = "outer foo"
|
27
|
+
@bar = "outer bar"
|
28
|
+
end
|
29
|
+
|
30
|
+
suite "Nested suite" do
|
31
|
+
setup do
|
32
|
+
@inner_setup = "inner foo"
|
33
|
+
@bar = "inner bar"
|
34
|
+
end
|
35
|
+
|
36
|
+
assert "@outer_setup is inherited" do
|
37
|
+
equal("outer foo", @outer_setup)
|
38
|
+
end
|
39
|
+
|
40
|
+
assert "@inner_setup is defined" do
|
41
|
+
equal("inner foo", @inner_setup)
|
42
|
+
end
|
43
|
+
|
44
|
+
assert "@bar is overridden" do
|
45
|
+
equal(@bar, "inner bar")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
assert "@inner_setup is not defined in outer suite" do
|
50
|
+
!defined?(@inner_setup)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
BareTest.suite do
|
2
|
+
suite "Dependencies" do
|
3
|
+
suite "Existing dependency" do
|
4
|
+
suite "A", :provides => :a do
|
5
|
+
assert "This assertion will succeed, due to that, :a will be provided" do
|
6
|
+
true
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
suite "B, depending on A", :depends_on => :a do
|
11
|
+
assert "This assertion will succeed, because the dependency ':a' is provided" do
|
12
|
+
true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
suite "Missing dependency" do
|
18
|
+
suite "C", :provides => :c do
|
19
|
+
assert "This assertion will fail, due to that, :c will NOT be provided" do
|
20
|
+
failure 'Intentional failure'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
suite "D, depending on C", :depends_on => :c do
|
25
|
+
assert "This assertion will be skipped, because the dependency ':c' is not provided" do
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|