oktest 1.0.2 → 1.2.1
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.
- checksums.yaml +5 -5
- data/README.md +460 -51
- data/Rakefile.rb +5 -2
- data/benchmark/Rakefile.rb +4 -0
- data/lib/oktest.rb +557 -74
- data/oktest.gemspec +3 -3
- data/test/assertion_test.rb +70 -5
- data/test/filter_test.rb +2 -2
- data/test/fixture_test.rb +14 -1
- data/test/generator_test.rb +1 -1
- data/test/helper_test.rb +7 -7
- data/test/initialize.rb +8 -1
- data/test/mainapp_test.rb +95 -42
- data/test/matcher_test.rb +424 -0
- data/test/misc_test.rb +5 -5
- data/test/node_test.rb +27 -4
- data/test/reporter_test.rb +87 -29
- data/test/runner_test.rb +97 -25
- data/test/tc.rb +12 -0
- data/test/util_test.rb +71 -1
- data/test/utilhelper_test.rb +84 -0
- data/test/visitor_test.rb +1 -1
- metadata +9 -8
data/README.md
CHANGED
@@ -4,12 +4,13 @@
|
|
4
4
|
|
5
5
|
Oktest.rb is a new-style testing library for Ruby.
|
6
6
|
|
7
|
-
* `ok {actual} == expected` style assertion.
|
8
|
-
*
|
7
|
+
* `ok {actual} == expected` style [assertion](#assertions).
|
8
|
+
* [Fixture injection](#fixture-injection) inspired by dependency injection.
|
9
9
|
* Structured test specifications like RSpec.
|
10
|
-
*
|
10
|
+
* [JSON Matcher](#json-matcher) similar to JSON Schema.
|
11
|
+
* [Filtering](#tag-and-filtering) testcases by pattern or tags.
|
11
12
|
* Blue/red color instead of green/red for accesability.
|
12
|
-
* Small code size (
|
13
|
+
* Small code size (less than 3000 lines) and good performance.
|
13
14
|
|
14
15
|
```ruby
|
15
16
|
### Oktest ### Test::Unit
|
@@ -42,7 +43,7 @@ Oktest.scope do #
|
|
42
43
|
end #
|
43
44
|
```
|
44
45
|
|
45
|
-
Oktest.rb requires Ruby 2.
|
46
|
+
Oktest.rb requires Ruby 2.0 or later.
|
46
47
|
|
47
48
|
|
48
49
|
|
@@ -73,6 +74,7 @@ Oktest.rb requires Ruby 2.3 or later.
|
|
73
74
|
* <a href="#at_end-crean-up-handler"><code>at_end()</code>: Crean-up Handler</a>
|
74
75
|
* <a href="#named-fixtures">Named Fixtures</a>
|
75
76
|
* <a href="#fixture-injection">Fixture Injection</a>
|
77
|
+
* <a href="#fixture-keyword-argument"><code>fixture:</code> keyword argument</a>
|
76
78
|
* <a href="#global-scope">Global Scope</a>
|
77
79
|
* <a href="#helpers">Helpers</a>
|
78
80
|
* <a href="#capture_sio"><code>capture_sio()</code></a>
|
@@ -82,12 +84,19 @@ Oktest.rb requires Ruby 2.3 or later.
|
|
82
84
|
* <a href="#dummy_attrs"><code>dummy_attrs()</code></a>
|
83
85
|
* <a href="#dummy_ivars"><code>dummy_ivars()</code></a>
|
84
86
|
* <a href="#recorder"><code>recorder()</code></a>
|
87
|
+
* <a href="#partial_regexp"><code>partial_regexp()</code></a>
|
88
|
+
* <a href="#json-matcher">JSON Matcher</a>
|
89
|
+
* <a href="#simple-example">Simple Example</a>
|
90
|
+
* <a href="#nested-example">Nested Example</a>
|
91
|
+
* <a href="#complex-example">Complex Example</a>
|
92
|
+
* <a href="#helper-methods-for-json-matcher">Helper Methods for JSON Matcher</a>
|
85
93
|
* <a href="#tips">Tips</a>
|
86
94
|
* <a href="#ok--in-minitest"><code>ok {}</code> in MiniTest</a>
|
87
95
|
* <a href="#testing-rack-application">Testing Rack Application</a>
|
96
|
+
* <a href="#environment-variale-oktest_rb">Environment Variale <code>$OKTEST_RB</code></a>
|
88
97
|
* <a href="#traverser-class">Traverser Class</a>
|
89
|
-
* <a href="#benchmarks">Benchmarks</a>
|
90
98
|
* <a href="#--faster-option"><code>--faster</code> Option</a>
|
99
|
+
* <a href="#benchmarks">Benchmarks</a>
|
91
100
|
* <a href="#change-log">Change Log</a>
|
92
101
|
* <a href="#license-and-copyright">License and Copyright</a>
|
93
102
|
|
@@ -109,7 +118,7 @@ $ oktest --help
|
|
109
118
|
$ mkdir test
|
110
119
|
|
111
120
|
### create test script
|
112
|
-
$ oktest --
|
121
|
+
$ oktest --skeleton > test/example_test.rb
|
113
122
|
$ less test/example_test.rb
|
114
123
|
|
115
124
|
### run test script
|
@@ -165,6 +174,7 @@ Result:
|
|
165
174
|
|
166
175
|
```terminal
|
167
176
|
$ oktest test/example01_test.rb # or: ruby test/example01_test.rb
|
177
|
+
## test/example01_test.rb
|
168
178
|
* Hello
|
169
179
|
* #hello()
|
170
180
|
- [pass] returns greeting message.
|
@@ -206,6 +216,7 @@ Result:
|
|
206
216
|
|
207
217
|
```terminal
|
208
218
|
$ oktest test/example02_test.rb # or: ruby test/example02_test.rb
|
219
|
+
## test/example02_test.rb
|
209
220
|
* other examples
|
210
221
|
- [Fail] example of assertion failure
|
211
222
|
- [ERROR] example of something error
|
@@ -260,6 +271,7 @@ Result:
|
|
260
271
|
|
261
272
|
```terminal
|
262
273
|
$ oktest test/example03_test.rb # or: ruby test/example03_test.rb
|
274
|
+
## oktest test/example03_test.rb
|
263
275
|
* other examples
|
264
276
|
- [Skip] example of skip (reason: requires Ruby3)
|
265
277
|
- [TODO] example of todo
|
@@ -280,6 +292,7 @@ Verbose mode (default):
|
|
280
292
|
|
281
293
|
```terminal
|
282
294
|
$ oktest test/example01_test.rb -s verbose # or -sv
|
295
|
+
## test/example01_test.rb
|
283
296
|
* Hello
|
284
297
|
* #hello()
|
285
298
|
- [pass] returns greeting message.
|
@@ -291,6 +304,16 @@ Simple mode:
|
|
291
304
|
|
292
305
|
```terminal
|
293
306
|
$ oktest test/example01_test.rb -s simple # or -ss
|
307
|
+
## test/example01_test.rb
|
308
|
+
* Hello:
|
309
|
+
* #hello(): ..
|
310
|
+
## total:2 (pass:2, fail:0, error:0, skip:0, todo:0) in 0.000s
|
311
|
+
```
|
312
|
+
|
313
|
+
Compact mode:
|
314
|
+
|
315
|
+
```terminal
|
316
|
+
$ oktest test/example01_test.rb -s compact # or -sc
|
294
317
|
test/example01_test.rb: ..
|
295
318
|
## total:2 (pass:2, fail:0, error:0, skip:0, todo:0) in 0.000s
|
296
319
|
```
|
@@ -298,7 +321,7 @@ test/example01_test.rb: ..
|
|
298
321
|
Plain mode:
|
299
322
|
|
300
323
|
```terminal
|
301
|
-
$ oktest test/example01_test.rb -s
|
324
|
+
$ oktest test/example01_test.rb -s plain # or -sp
|
302
325
|
..
|
303
326
|
## total:2 (pass:2, fail:0, error:0, skip:0, todo:0) in 0.000s
|
304
327
|
```
|
@@ -315,6 +338,8 @@ Quiet mode reports progress only of failed or error test cases (and doesn't
|
|
315
338
|
report progress of passed ones), so it's output is very compact. This is
|
316
339
|
very useful for large project which contains large number of test cases.
|
317
340
|
|
341
|
+
(Note: `ruby test/example01_test.rb -s <STYLE>` is also available.)
|
342
|
+
|
318
343
|
|
319
344
|
### Run All Test Scripts Under Directory
|
320
345
|
|
@@ -324,7 +349,7 @@ How to run test scripts under `test` directory:
|
|
324
349
|
$ ls test/
|
325
350
|
example01_test.rb example02_test.rb example03_test.rb
|
326
351
|
|
327
|
-
$ oktest -s
|
352
|
+
$ oktest -s compact test # or: ruby -r oktest -e 'Oktest.main' -- test -s compact
|
328
353
|
test/example01_test.rb: ..
|
329
354
|
test/example02_test.rb: fE
|
330
355
|
----------------------------------------------------------------------
|
@@ -457,6 +482,7 @@ Result:
|
|
457
482
|
|
458
483
|
```terminal
|
459
484
|
$ ruby test/example05_test.rb
|
485
|
+
## test/example05_test.rb
|
460
486
|
* Integer
|
461
487
|
* #abs()
|
462
488
|
- When value is negative...
|
@@ -984,15 +1010,15 @@ end
|
|
984
1010
|
Result:
|
985
1011
|
|
986
1012
|
```terminal
|
987
|
-
$ oktest -s
|
1013
|
+
$ oktest -s quiet test/example21a_test.rb
|
988
1014
|
*** before_all() ***
|
989
1015
|
=== before() ===
|
990
1016
|
---- example spec #1 ----
|
991
1017
|
=== after() ===
|
992
|
-
|
1018
|
+
=== before() ===
|
993
1019
|
---- example spec #2 ----
|
994
1020
|
=== after() ===
|
995
|
-
|
1021
|
+
*** after_all() ***
|
996
1022
|
|
997
1023
|
## total:2 (pass:2, fail:0, error:0, skip:0, todo:0) in 0.000s
|
998
1024
|
```
|
@@ -1022,8 +1048,8 @@ Oktest.scope do
|
|
1022
1048
|
after { puts "===== Inner: after =====" } # !!!!!
|
1023
1049
|
|
1024
1050
|
spec "example" do
|
1025
|
-
|
1026
|
-
|
1051
|
+
ok {1+1} == 2
|
1052
|
+
end
|
1027
1053
|
|
1028
1054
|
end
|
1029
1055
|
|
@@ -1209,12 +1235,42 @@ end
|
|
1209
1235
|
-->
|
1210
1236
|
|
1211
1237
|
|
1238
|
+
### `fixture:` keyword argument
|
1239
|
+
|
1240
|
+
`scope()` takes `fixture:` keyword argument which overwrites fixture value.
|
1241
|
+
|
1242
|
+
test/example26_test.rb:
|
1243
|
+
|
1244
|
+
```ruby
|
1245
|
+
require 'oktest'
|
1246
|
+
|
1247
|
+
Oktest.scope do
|
1248
|
+
|
1249
|
+
fixture :user do |uname, uid: 101| # `uid` is keyword param
|
1250
|
+
{name: uname, id: uid}
|
1251
|
+
end
|
1252
|
+
|
1253
|
+
fixture :uname do
|
1254
|
+
"Alice"
|
1255
|
+
end
|
1256
|
+
|
1257
|
+
## keyword argument `fixture:` overwrites fixture values
|
1258
|
+
spec "example", fixture: {uname: "Bob", uid: 201} do # !!!!!
|
1259
|
+
|user|
|
1260
|
+
ok {user[:name]} == "Bob" # != "Alice"
|
1261
|
+
ok {user[:id]} == 201 # != 101
|
1262
|
+
end
|
1263
|
+
|
1264
|
+
end
|
1265
|
+
```
|
1266
|
+
|
1267
|
+
|
1212
1268
|
### Global Scope
|
1213
1269
|
|
1214
1270
|
It is a good idea to separate common fixtures into dedicated file.
|
1215
1271
|
In this case, use `Oktest.global_scope()` instead of `Oktest.scope()`.
|
1216
1272
|
|
1217
|
-
test/
|
1273
|
+
test/example27_test.rb:
|
1218
1274
|
|
1219
1275
|
```ruby
|
1220
1276
|
require 'oktest'
|
@@ -1588,6 +1644,334 @@ end
|
|
1588
1644
|
```
|
1589
1645
|
|
1590
1646
|
|
1647
|
+
### `partial_regexp()`
|
1648
|
+
|
1649
|
+
`partial_regexp()` can embed regexp pattern into string, and compile it into Regexp object. This is very useful to validate multiline string with regexp.
|
1650
|
+
|
1651
|
+
Assume that you are testing the following function `f1()`. It generates multiline string containing date and random string.
|
1652
|
+
|
1653
|
+
```ruby
|
1654
|
+
def f1()
|
1655
|
+
today = Date.today.to_s # ex: '2021-12-31'
|
1656
|
+
secret = Random.bytes(8).unpack('H*')[0] # ex: "cd0b260ac728eda5"
|
1657
|
+
return <<END
|
1658
|
+
* [config.date] #{today}
|
1659
|
+
* [config.secret] #{secret}
|
1660
|
+
END
|
1661
|
+
end
|
1662
|
+
```ruby
|
1663
|
+
|
1664
|
+
To test `f1()`, you may write the following test code.
|
1665
|
+
As you can see, expected regexp literal is complicated.
|
1666
|
+
|
1667
|
+
```ruby
|
1668
|
+
topic 'f1()' do
|
1669
|
+
spec "generates multiline string." do
|
1670
|
+
expected = /\A\* \[config\.date\] \d\d\d\d-\d\d-\d\d\n\* \[config\.secret\] [0-9a-f]+\n/
|
1671
|
+
ok {f1()} =~ expected
|
1672
|
+
end
|
1673
|
+
end
|
1674
|
+
```
|
1675
|
+
|
1676
|
+
[`x` option](https://ruby-doc.org/core-2.7.0/Regexp.html#class-Regexp-label-Free-Spacing+Mode+and+Comments) of regexp (such as `/.../x`) allows you to write regexp literal in multiline format.
|
1677
|
+
But you have to escape metachars (`*`, `.`, `[]`, and white space).
|
1678
|
+
|
1679
|
+
```ruby
|
1680
|
+
topic 'f1()' do
|
1681
|
+
spec "generates multiline string." do
|
1682
|
+
expected = /\A
|
1683
|
+
\*\ \[config\.date\]\ \ \ \d\d\d\d-\d\d-\d\d\n
|
1684
|
+
\*\ \[config\.secret\]\ [0-9a-f]+\n
|
1685
|
+
\z/x # !!!!!
|
1686
|
+
ok {f1()} =~ expected
|
1687
|
+
end
|
1688
|
+
end
|
1689
|
+
```
|
1690
|
+
|
1691
|
+
In such case, `partial_regexp()` is very useful. It compiles string into Regexp object.
|
1692
|
+
Using `partial_regexp()`, you can write expected regexp very easily.
|
1693
|
+
|
1694
|
+
```ruby
|
1695
|
+
topic 'f1()' do
|
1696
|
+
spec "generates multiline string." do
|
1697
|
+
# - Regexp can be in `{== ==}`.
|
1698
|
+
# - Other text part is escaped by `Regexp.escape()`.
|
1699
|
+
expected = partial_regexp <<'END' # !!!!!
|
1700
|
+
* [config.date] {== \d\d\d\d-\d\d-\d\d ==}
|
1701
|
+
* [config.secret] {== [0-9a-f]+ ==}
|
1702
|
+
END
|
1703
|
+
ok {f1()} =~ expected
|
1704
|
+
## above is equivarent to:
|
1705
|
+
#expected = /\A
|
1706
|
+
#\*\ \[config\.date\]\ \ \ \d\d\d\d-\d\d-\d\d\n
|
1707
|
+
#\*\ \[config\.secret\]\ [0-9a-f]+\n
|
1708
|
+
#\z/x # !!!!!
|
1709
|
+
#ok {f1()} =~ expected
|
1710
|
+
end
|
1711
|
+
end
|
1712
|
+
```
|
1713
|
+
|
1714
|
+
`partial_regexp()` takes 4 arguments.
|
1715
|
+
|
1716
|
+
```ruby
|
1717
|
+
def partial_regexp(pattern, begin_='\A', end_='\z', mark='{== ==}')
|
1718
|
+
```
|
1719
|
+
|
1720
|
+
`partial_regexp()` adds `\A` and `\z` automatically.
|
1721
|
+
If you want not to add them, pass empty string or nil as 2nd and 3rd argument, like this:
|
1722
|
+
|
1723
|
+
```ruby
|
1724
|
+
partial_regexp <<-'END', '', '' # !!!!!
|
1725
|
+
...
|
1726
|
+
END
|
1727
|
+
```
|
1728
|
+
|
1729
|
+
If you want to change embed mark, specify 4th argument, like this:
|
1730
|
+
|
1731
|
+
```ruby
|
1732
|
+
partial_regexp <<-'END', '\A', '\z', '%% %%' # !!!!!
|
1733
|
+
* [config.date] %% \d\d\d\d-\d\d-\d\d %%
|
1734
|
+
* [config.secret] %% [0-9a-f]+ %%
|
1735
|
+
END
|
1736
|
+
```
|
1737
|
+
|
1738
|
+
Oktest.rb provides `partial_regexp!()`, too.
|
1739
|
+
Difference between `partial_regexp()` and `partial_regexp!()` is the result of `#inspect()`.
|
1740
|
+
This is imortant only when assertion failed and error message reported.
|
1741
|
+
You can use whichever you like.
|
1742
|
+
|
1743
|
+
```ruby
|
1744
|
+
r1 = partial_regexp <<-'END'
|
1745
|
+
* [config.date] {== \d\d\d\d-\d\d-\d\d ==}
|
1746
|
+
* [config.secret] {== [0-9a-f]+ ==}
|
1747
|
+
END
|
1748
|
+
p r1
|
1749
|
+
#=> /\A
|
1750
|
+
# \*\ \[config\.date\]\ \ \ \d\d\d\d-\d\d-\d\d\n
|
1751
|
+
# \*\ \[config\.secret\]\ [0-9a-f]+\n
|
1752
|
+
# \z/x
|
1753
|
+
|
1754
|
+
r2 = partial_regexp! <<-'END' # !!!!!
|
1755
|
+
* [config.date] {== \d\d\d\d-\d\d-\d\d ==}
|
1756
|
+
* [config.secret] {== [0-9a-f]+ ==}
|
1757
|
+
END
|
1758
|
+
p r2
|
1759
|
+
#=> partial_regexp(<<PREXP, '\A', '\z')
|
1760
|
+
# * [config.date] {== \d\d\d\d-\d\d-\d\d ==}
|
1761
|
+
# * [config.secret] {== [0-9a-f]+ ==}
|
1762
|
+
# PREXP
|
1763
|
+
```
|
1764
|
+
|
1765
|
+
|
1766
|
+
## JSON Matcher
|
1767
|
+
|
1768
|
+
Oktest.rb provides easy way to assert JSON data.
|
1769
|
+
This is very convenient feature, but don't abuse it.
|
1770
|
+
|
1771
|
+
|
1772
|
+
### Simple Example
|
1773
|
+
|
1774
|
+
<!--
|
1775
|
+
test/example41_test.rb:
|
1776
|
+
-->
|
1777
|
+
```ruby
|
1778
|
+
require 'oktest'
|
1779
|
+
require 'set' # !!!!!
|
1780
|
+
|
1781
|
+
Oktest.scope do
|
1782
|
+
topic 'JSON Example' do
|
1783
|
+
|
1784
|
+
spec "simple example" do
|
1785
|
+
actual = {
|
1786
|
+
"name": "Alice",
|
1787
|
+
"id": 1001,
|
1788
|
+
"age": 18,
|
1789
|
+
"email": "alice@example.com",
|
1790
|
+
"gender": "F",
|
1791
|
+
"deleted": false,
|
1792
|
+
"tags": ["aaa", "bbb", "ccc"],
|
1793
|
+
#"twitter": "@alice",
|
1794
|
+
}
|
1795
|
+
## assertion
|
1796
|
+
ok {JSON(actual)} === { # requires `JSON()` and `===`
|
1797
|
+
"name": "Alice", # scalar value
|
1798
|
+
"id": 1000..9999, # range object
|
1799
|
+
"age": Integer, # class object
|
1800
|
+
"email": /^\w+@example\.com$/, # regexp
|
1801
|
+
"gender": Set.new(["M", "F"]), # Set object ("M" or "F")
|
1802
|
+
"deleted": Set.new([true, false]), # boolean (true or false)
|
1803
|
+
"tags": [/^\w+$/].each, # Enumerator object (!= Array obj)
|
1804
|
+
"twitter?": /^@\w+$/, # key 'xxx?' means optional value
|
1805
|
+
}
|
1806
|
+
end
|
1807
|
+
|
1808
|
+
end
|
1809
|
+
end
|
1810
|
+
```
|
1811
|
+
|
1812
|
+
(Note: Ruby 2.4 or older doesn't have `Set#===()`, so above code will occur error
|
1813
|
+
in Ruby 2.4 or older. Please add the folllowing hack in your test script.)
|
1814
|
+
|
1815
|
+
```ruby
|
1816
|
+
require 'set'
|
1817
|
+
unless Set.instance_methods(false).include?(:===) # for Ruby 2.4 or older
|
1818
|
+
class Set; alias === include?; end
|
1819
|
+
end
|
1820
|
+
```
|
1821
|
+
|
1822
|
+
Notice that `Enumerator` has different meaning from `Array` in JSON matcher.
|
1823
|
+
|
1824
|
+
```ruby
|
1825
|
+
actual = {"tags": ["foo", "bar", "baz"]}
|
1826
|
+
|
1827
|
+
## Array
|
1828
|
+
ok {JSON(actual)} == {"tags": ["foo", "bar", "baz"]}
|
1829
|
+
|
1830
|
+
## Enumerator
|
1831
|
+
ok {JSON(actual)} == {"tags": [/^\w+$/].each}
|
1832
|
+
```
|
1833
|
+
|
1834
|
+
|
1835
|
+
### Nested Example
|
1836
|
+
|
1837
|
+
<!--
|
1838
|
+
test/example42_test.rb:
|
1839
|
+
-->
|
1840
|
+
```ruby
|
1841
|
+
require 'oktest'
|
1842
|
+
require 'set' # !!!!!
|
1843
|
+
|
1844
|
+
Oktest.scope do
|
1845
|
+
topic 'JSON Example' do
|
1846
|
+
|
1847
|
+
spec "nested example" do
|
1848
|
+
actual = {
|
1849
|
+
"teams": [
|
1850
|
+
{
|
1851
|
+
"team": "Section 9",
|
1852
|
+
"members": [
|
1853
|
+
{"id": 2500, "name": "Aramaki", "gender": "M"},
|
1854
|
+
{"id": 2501, "name": "Motoko" , "gender": "F"},
|
1855
|
+
{"id": 2502, "name": "Batou" , "gender": "M"},
|
1856
|
+
],
|
1857
|
+
"leader": "Aramaki",
|
1858
|
+
},
|
1859
|
+
{
|
1860
|
+
"team": "SOS Brigade",
|
1861
|
+
"members": [
|
1862
|
+
{"id": 1001, "name": "Haruhi", "gender": "F"},
|
1863
|
+
{"id": 1002, "name": "Mikuru", "gender": "F"},
|
1864
|
+
{"id": 1003, "name": "Yuki" , "gender": "F"},
|
1865
|
+
{"id": 1004, "name": "Itsuki", "gender": "M"},
|
1866
|
+
{"id": 1005, "name": "Kyon" , "gender": "M"},
|
1867
|
+
],
|
1868
|
+
},
|
1869
|
+
],
|
1870
|
+
}
|
1871
|
+
## assertion
|
1872
|
+
ok {JSON(actual)} === { # requires `JSON()` and `===`
|
1873
|
+
"teams": [
|
1874
|
+
{
|
1875
|
+
"team": String,
|
1876
|
+
"members": [
|
1877
|
+
{"id": 1000..9999, "name": String, "gender": Set.new(["M", "F"])}
|
1878
|
+
].each, # Enumerator object (!= Array obj)
|
1879
|
+
"leader?": String, # key 'xxx?' means optional value
|
1880
|
+
}
|
1881
|
+
].each, # Enumerator object (!= Array obj)
|
1882
|
+
}
|
1883
|
+
end
|
1884
|
+
|
1885
|
+
end
|
1886
|
+
end
|
1887
|
+
```
|
1888
|
+
|
1889
|
+
|
1890
|
+
### Complex Example
|
1891
|
+
|
1892
|
+
* `OR(x, y, z)` matches to `x`, `y`, or `z`.
|
1893
|
+
* `AND(x, y, z)` matches to `x`, `y`, and `z`.
|
1894
|
+
* Key `"*"` matches to any key of hash object.
|
1895
|
+
* `Any()` matches to anything.
|
1896
|
+
|
1897
|
+
<!--
|
1898
|
+
test/example43_test.rb:
|
1899
|
+
-->
|
1900
|
+
```ruby
|
1901
|
+
require 'oktest'
|
1902
|
+
require 'set'
|
1903
|
+
|
1904
|
+
Oktest.scope do
|
1905
|
+
topic 'JSON Example' do
|
1906
|
+
|
1907
|
+
spec "OR() example" do
|
1908
|
+
ok {JSON({"val": "123"})} === {"val": OR(String, Integer)} # OR()
|
1909
|
+
ok {JSON({"val": 123 })} === {"val": OR(String, Integer)} # OR()
|
1910
|
+
end
|
1911
|
+
|
1912
|
+
spec "AND() example" do
|
1913
|
+
ok {JSON({"val": "123"})} === {"val": AND(String, /^\d+$/)} # AND()
|
1914
|
+
ok {JSON({"val": 123 })} === {"val": AND(Integer, 1..1000)} # AND()
|
1915
|
+
end
|
1916
|
+
|
1917
|
+
spec "`*` and `ANY` example" do
|
1918
|
+
ok {JSON({"name": "Bob", "age": 20})} === {"*": Any()} # '*' and Any()
|
1919
|
+
end
|
1920
|
+
|
1921
|
+
spec "complex exapmle" do
|
1922
|
+
actual = {
|
1923
|
+
"item": "awesome item",
|
1924
|
+
"colors": ["red", "#cceeff", "green", "#fff"],
|
1925
|
+
"memo": "this is awesome.",
|
1926
|
+
"url": "https://example.com/awesome",
|
1927
|
+
}
|
1928
|
+
## assertion
|
1929
|
+
color_names = ["red", "blue", "green", "white", "black"]
|
1930
|
+
color_pat = /^\#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/
|
1931
|
+
ok {JSON(actual)} === {
|
1932
|
+
"colors": [
|
1933
|
+
AND(String, OR(Set.new(color_names), color_pat)), # AND() and OR()
|
1934
|
+
].each,
|
1935
|
+
"*": Any(), # match to any key (`"*"`) and value (`ANY`)
|
1936
|
+
}
|
1937
|
+
end
|
1938
|
+
|
1939
|
+
end
|
1940
|
+
end
|
1941
|
+
```
|
1942
|
+
|
1943
|
+
(Note: `/^\d+$/` implies String value, and `1..100` implies Integer value.)
|
1944
|
+
|
1945
|
+
```ruby
|
1946
|
+
## No need to write:
|
1947
|
+
## ok {JSON{...}} === {"val": AND(String, /^\d+$/)}
|
1948
|
+
## ok {JSON{...}} === {"val": AND(Integer, 1..100)}
|
1949
|
+
ok {JSON({"val": "A"})} === {"val": /^\d+$/} # implies String value
|
1950
|
+
ok {JSON({"val": 99 })} === {"val": 1..100} # implies Integer value
|
1951
|
+
```
|
1952
|
+
|
1953
|
+
|
1954
|
+
### Helper Methods for JSON Matcher
|
1955
|
+
|
1956
|
+
Oktest.rb provides some helper methods and objects:
|
1957
|
+
|
1958
|
+
* `Enum(x, y, z)` is almost same as `Set.new([x, y, z])`.
|
1959
|
+
* `Bool()` is same as `Enum(true, false)`.
|
1960
|
+
* `Length(3)` matches to length 3, and `Length(1..3)` matches to length 1..3.
|
1961
|
+
|
1962
|
+
<!--
|
1963
|
+
test/example44_test.rb:
|
1964
|
+
-->
|
1965
|
+
```ruby
|
1966
|
+
actual = {"gender": "M", "deleted": false, "code": "ABCD1234"}
|
1967
|
+
ok {JSON(actual)} == {
|
1968
|
+
"gender": Enum("M", "F"), # same as Set.new(["M", "F"])
|
1969
|
+
"deleted": Bool(), # same as Enum(true, false)
|
1970
|
+
"code": Length(6..10), # code length should be 6..10
|
1971
|
+
}
|
1972
|
+
```
|
1973
|
+
|
1974
|
+
|
1591
1975
|
|
1592
1976
|
## Tips
|
1593
1977
|
|
@@ -1597,7 +1981,7 @@ end
|
|
1597
1981
|
If you want to use `ok {actual} == expected` style assertion in MiniTest,
|
1598
1982
|
install `minitest-ok` gem instead of `otest` gem.
|
1599
1983
|
|
1600
|
-
test/
|
1984
|
+
test/example51_test.rb:
|
1601
1985
|
|
1602
1986
|
```ruby
|
1603
1987
|
require 'minitest/spec'
|
@@ -1620,7 +2004,7 @@ See [minitest-ok README](https://github.com/kwatch/minitest-ok) for details.
|
|
1620
2004
|
|
1621
2005
|
`rack-test_app` gem will help you to test Rack application very well.
|
1622
2006
|
|
1623
|
-
test/
|
2007
|
+
test/example52_test.rb:
|
1624
2008
|
|
1625
2009
|
```ruby
|
1626
2010
|
require 'rack'
|
@@ -1689,11 +2073,25 @@ end
|
|
1689
2073
|
```
|
1690
2074
|
|
1691
2075
|
|
2076
|
+
### Environment Variale `$OKTEST_RB`
|
2077
|
+
|
2078
|
+
You can set default command-line option to environment variale `$OKTEST_RB`.
|
2079
|
+
For examle, you can specify default reporting style with `$OKTEST_RB`.
|
2080
|
+
|
2081
|
+
```terminal
|
2082
|
+
### change default reporting style to plain-style.
|
2083
|
+
$ export OKTEST_RB="-s plain" # !!!!!
|
2084
|
+
|
2085
|
+
### run test script in plain-style reporting without '-s' option.
|
2086
|
+
$ ruby test/foo_test.rb
|
2087
|
+
```
|
2088
|
+
|
2089
|
+
|
1692
2090
|
### Traverser Class
|
1693
2091
|
|
1694
2092
|
Oktest.rb provides `Traverser` class which implements Visitor pattern.
|
1695
2093
|
|
1696
|
-
test/
|
2094
|
+
test/example54_test.rb:
|
1697
2095
|
|
1698
2096
|
```ruby
|
1699
2097
|
require 'oktest'
|
@@ -1750,8 +2148,8 @@ MyTraverser.new.start()
|
|
1750
2148
|
Result:
|
1751
2149
|
|
1752
2150
|
```terminal
|
1753
|
-
$ ruby test/
|
1754
|
-
# scope: test/
|
2151
|
+
$ ruby test/example54_test.rb
|
2152
|
+
# scope: test/example54_test.rb
|
1755
2153
|
+ topic: Example Topic
|
1756
2154
|
- spec: sample #1
|
1757
2155
|
- spec: sample #2
|
@@ -1762,18 +2160,36 @@ $ ruby test/example44_test.rb
|
|
1762
2160
|
```
|
1763
2161
|
|
1764
2162
|
|
2163
|
+
### `--faster` Option
|
2164
|
+
|
2165
|
+
~~If you are working in very larget project and you want to run test scripts as fast as possible, try `--faster` option of `oktest` command.~~
|
2166
|
+
|
2167
|
+
```terminal
|
2168
|
+
$ oktest -s quiet --faster test/ ## only for very large project
|
2169
|
+
```
|
2170
|
+
|
2171
|
+
~~Or set `Oktest::Config.ok_location = false` in your test script.~~
|
2172
|
+
|
2173
|
+
```ruby
|
2174
|
+
require 'oktest'
|
2175
|
+
Oktest::Config.ok_location = false ## only for very large project
|
2176
|
+
```
|
2177
|
+
|
2178
|
+
`--faster` option is still available but no longer recommended, because performance of `ok{}` is improved significantly since Oktest.rb 1.2.0.
|
2179
|
+
|
2180
|
+
|
1765
2181
|
### Benchmarks
|
1766
2182
|
|
1767
2183
|
Oktest.rb gem file contains benchmark script.
|
1768
2184
|
It shows that Oktest.rb runs more than three times faster than RSpec.
|
1769
2185
|
|
1770
2186
|
```terminal
|
1771
|
-
$ gem install oktest # ver 1.
|
2187
|
+
$ gem install oktest # ver 1.2.0
|
1772
2188
|
$ gem install rspec # ver 3.10.0
|
1773
2189
|
$ gem install minitest # ver 5.14.4
|
1774
2190
|
$ gem install test-unit # ver 3.4.4
|
1775
2191
|
|
1776
|
-
$ cp -pr $GEM_HOME/gems/oktest-1.
|
2192
|
+
$ cp -pr $GEM_HOME/gems/oktest-1.2.0/benchmark .
|
1777
2193
|
$ cd benchmark/
|
1778
2194
|
$ rake -T
|
1779
2195
|
$ ruby --version
|
@@ -1782,67 +2198,60 @@ ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-darwin18]
|
|
1782
2198
|
$ rake benchmark:all
|
1783
2199
|
```
|
1784
2200
|
|
2201
|
+
Summary of example result:
|
2202
|
+
|
2203
|
+
```
|
2204
|
+
Oktest: 6.815 real 6.511 user 0.257 sys
|
2205
|
+
Oktest (--faster): 6.401 real 6.123 user 0.240 sys
|
2206
|
+
RSpec: 32.062 real 27.778 user 4.383 sys
|
2207
|
+
MiniTest: 9.140 real 8.657 user 0.705 sys
|
2208
|
+
Test::Unit: 19.580 real 19.020 user 0.885 sys
|
2209
|
+
```
|
2210
|
+
|
1785
2211
|
Example result:
|
1786
2212
|
|
1787
2213
|
```
|
1788
2214
|
==================== oktest ====================
|
1789
2215
|
oktest -sq run_all.rb
|
1790
2216
|
|
1791
|
-
## total:100000 (pass:100000, fail:0, error:0, skip:0, todo:0) in
|
2217
|
+
## total:100000 (pass:100000, fail:0, error:0, skip:0, todo:0) in 2.36s
|
1792
2218
|
|
1793
|
-
|
2219
|
+
6.815 real 6.511 user 0.257 sys
|
1794
2220
|
|
1795
2221
|
==================== oktest:faster ====================
|
1796
2222
|
oktest -sq --faster run_all.rb
|
1797
2223
|
|
1798
|
-
## total:100000 (pass:100000, fail:0, error:0, skip:0, todo:0) in
|
2224
|
+
## total:100000 (pass:100000, fail:0, error:0, skip:0, todo:0) in 2.01s
|
1799
2225
|
|
1800
|
-
|
2226
|
+
6.401 real 6.123 user 0.240 sys
|
1801
2227
|
|
1802
2228
|
==================== rspec ====================
|
1803
2229
|
rspec run_all.rb | tail -4
|
1804
2230
|
|
1805
|
-
Finished in
|
2231
|
+
Finished in 15.27 seconds (files took 16.08 seconds to load)
|
1806
2232
|
100000 examples, 0 failures
|
1807
2233
|
|
1808
2234
|
|
1809
|
-
|
2235
|
+
32.062 real 27.778 user 4.383 sys
|
1810
2236
|
|
1811
2237
|
==================== minitest ====================
|
1812
2238
|
ruby run_all.rb | tail -4
|
1813
2239
|
|
1814
|
-
Finished in 5.
|
2240
|
+
Finished in 5.281425s, 18934.2838 runs/s, 37868.5677 assertions/s.
|
1815
2241
|
|
1816
|
-
100000 runs,
|
2242
|
+
100000 runs, 200000 assertions, 0 failures, 0 errors, 0 skips
|
1817
2243
|
|
1818
|
-
|
2244
|
+
9.140 real 8.657 user 0.705 sys
|
1819
2245
|
|
1820
2246
|
==================== testunit ====================
|
1821
2247
|
ruby run_all.rb | tail -5
|
1822
2248
|
-------------------------------------------------------------------------------
|
1823
|
-
100000 tests,
|
2249
|
+
100000 tests, 200000 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
|
1824
2250
|
100% passed
|
1825
2251
|
-------------------------------------------------------------------------------
|
1826
|
-
|
1827
|
-
|
1828
|
-
17.838 real 17.201 user 0.879 sys
|
1829
|
-
```
|
2252
|
+
7775.59 tests/s, 15551.18 assertions/s
|
1830
2253
|
|
1831
|
-
|
1832
|
-
### `--faster` Option
|
1833
|
-
|
1834
|
-
If you are working in very larget project and you want to run test scripts
|
1835
|
-
as fast as possible, try `--faster` option of `oktest` command.
|
1836
|
-
|
1837
|
-
```terminal
|
1838
|
-
$ oktest -s quiet --faster test/ ## only for very large project
|
1839
|
-
```
|
1840
|
-
|
1841
|
-
Or set `Oktest::Config.ok_location = false` in your test script.
|
1842
|
-
|
1843
|
-
```ruby
|
1844
|
-
require 'oktest'
|
1845
|
-
Oktest::Config.ok_location = false ## only for very large project
|
2254
|
+
19.580 real 19.020 user 0.885 sys
|
1846
2255
|
```
|
1847
2256
|
|
1848
2257
|
|