-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathREADME
296 lines (231 loc) · 7.99 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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
NAME
testy.rb
DESCRIPTION
a minimalist BDD testing framework for ruby that's mad at the world and
plans to kick its ass by ruthlessly removing lines of testing framework
code
SYNOPSIS
Testy.testing 'your code' do
test 'some behaviour' do |t|
ultimate = Ultimate.new
t.check :name, :expect => 42, :actual => ultimate.answer
end
end
GIT
open http://github.com/ahoward/testy/tree/master
git clone git://github.com/ahoward/testy.git
PRINCIPLES AND GOALS
. it.should.not.merely.be.a.unit.testing.with.a.clever.dsl
. testing should not require learning a framework. ruby is a great
framework so testy uses it instead, requiring programmers learn exactly 2
new method calls
. testing loc should not dwarf those of the application
. testing framework loc should not dwarf those of the application
. testing frameworks should *never* alter ruby built-ins nor add methods to
Object, Kernel, .et al
. the output of tests should be machine parsable for reporting and ci tools
to easily integrate with
. the output of tests should be beautiful so that humans can read it
. the shape of the test file should not insult the programmer so that tests
can double as sample code
. the testing framework should never alter exception semantics
. hi-jacking at_exit sucks ass
. the exit status of running a test suite should indicate the degree of its
failure state (testy returns the percent of failed tests using a non-zero
exit status)
. sample code should easily be able to double as a test suite, including
its output
. testing should improve your code and help your users, not make you want to
kill yourself
. using a format that aligns in terminal is sanity saving when comparing
output
. testing frameworks should provide as few shortcuts for making brittle
tightly coupled tests as possible
. test suites should be able to be created, manipulated, have their output
streamed to different ports, and even tested themselves - they should be
plain ol objects under the hood
SAMPLES
<========< samples/a.rb >========>
~ > cat samples/a.rb
# simple use of testy involves simply writing code, and recording the result
# you expect against the actual result
#
# notice that the output is very pretty and that the exitstatus is 0 when all
# tests pass
#
require 'testy'
Testy.testing 'the kick-ass-ed-ness of testy' do
test 'the ultimate answer to life' do |result|
list = []
list << 42
result.check :a, :expect => 42, :actual => list.first
list << 42.0
result.check :b, 42.0, list.last
end
end
~ > ruby samples/a.rb #=> exitstatus=0
---
the kick-ass-ed-ness of testy:
the ultimate answer to life:
success:
a: 42
b: 42.0
<========< samples/b.rb >========>
~ > cat samples/b.rb
# testy will handle unexpected results and exceptions thrown in your code in
# exactly the same way - by reporting on them in a beautiful fashion and
# continuing to run other tests. notice, however, that an unexpected result
# or raised exception will cause a non-zero exitstatus (the percent of tests
# that failed) for the suite as a whole. also note that previously
# accumulated expect/actual pairs are still reported on in the error report.
#
require 'testy'
Testy.testing 'the exception handling of testy' do
test 'raising an exception' do |result|
list = []
list << 42
result.check :a, :expect => 42, :actual => list.first
list.method_that_does_not_exist
end
test 'returning unexpected results' do |result|
result.check 'a', 42, 42
result.check :b, :expect => 'forty-two', :actual => 42.0
end
end
~ > ruby samples/b.rb #=> exitstatus=100
---
the exception handling of testy:
raising an exception:
failure:
error:
class: NoMethodError
message: undefined method `method_that_does_not_exist' for [42]:Array
backtrace:
- samples/b.rb:18:in `call'
- ./lib/testy.rb:130:in `run'
- ./lib/testy.rb:113:in `instance_eval'
- ./lib/testy.rb:113:in `run'
- /opt/local/lib/ruby/site_ruby/1.8/orderedhash.rb:65:in `each'
- /opt/local/lib/ruby/site_ruby/1.8/orderedhash.rb:65:in `each'
- ./lib/testy.rb:108:in `run'
- ./lib/testy.rb:78:in `call'
- ./lib/testy.rb:78:in `context'
- ./lib/testy.rb:102:in `run'
- ./lib/testy.rb:167:in `testing'
- samples/b.rb:10
expect:
a: 42
actual:
a: 42
returning unexpected results:
failure:
expect:
a: 42
b: forty-two
actual:
a: 42
b: 42.0
<========< samples/c.rb >========>
~ > cat samples/c.rb
# in some cases you may not even want to make test assertions and simply
# provide example code which should run without error, with testy it's not
# only easy to do this but the commanline supports --list to see which samples
# can be run and running a single or multiple tests based on name or pattern.
# notice that, when no assertions are made using 'result.check' the output of
# the test becomes the expected *and* actual and is therefore shown in the
# output as yaml. of course, if your samples have errors they are reported in
# the normal fashion and the tests will fail.
#
#
require 'testy'
Testy.testing 'some samplz for you' do
test 'foo sample' do
list = 1,2
list.last + list.first
end
test 'bar sample' do
list = 1,2
list.shift * list.pop
end
test 'foobar sample' do
list = 1,2
eval(list.reverse.join) * 2
end
end
# here are some examples of using the command line arguments on the above test
#
# cfp:~/src/git/testy > ruby samples/c.rb --list
# ---
# - foo sample
# - bar sample
# - foobar sample
#
# cfp:~/src/git/testy > ruby samples/c.rb foobar
# ---
# some samplz for you:
# foobar sample:
# success: 42
#
# cfp:~/src/git/testy > ruby samples/c.rb foo
# ---
# some samplz for you:
# foo sample:
# success: 3
# foobar sample:
# success: 42
#
# cfp:~/src/git/testy > ruby samples/c.rb bar
# ---
# some samplz for you:
# bar sample:
# success: 2
~ > ruby samples/c.rb #=> exitstatus=0
---
some samplz for you:
foo sample:
success: 3
bar sample:
success: 2
foobar sample:
success: 42
<========< samples/d.rb >========>
~ > cat samples/d.rb
# of course testy includes smartly inherited contexts and context sensitive
# setup and teardown methods which stack as well.
#
require 'testy'
Testy.testing 'your bitchin lib' do
context 'A' do
setup{ @list = [40] }
test 'foo' do
@list << 2
@list.first + @list.last
end
test 'bar' do |t|
t.check :list, @list, [40]
end
context 'B' do
setup{ @list << 2 }
test(:bar){ @list.join.delete('0') }
end
end
end
# the context name is applied to the test name, so you can selectively run
# groups of tests from the command line
#
# cfp:~/src/git/testy > ruby -I lib samples/d.rb 'A - B'
# ---
# your bitchin lib:
# A - B - bar:
# success: "42"
~ > ruby samples/d.rb #=> exitstatus=0
---
your bitchin lib:
A - foo:
success: 42
A - bar:
success:
list:
- 40
A - B - bar:
success: "42"