Tiramisu - super-simple testing library for Ruby
Its base API consist of just 10 memorable methods:
- spec, context
- before, around, after
- test
- assert, refute
- skip, fail
Assertions uses native Ruby methods so no need to remember contrived ones.
Forget about repeatedly scanning documentation, just use methods Ruby already provides.
Want to check whether something is nil? Use nil?
method:
assert(something).nil?
Want to check whether some array contains some value? Use include?
method:
assert(some_array).include? some_value
Need to check equality? Nothing simpler:
assert(something) == something_else
Perhaps match?
assert(something) =~ something_else
Or any?
assert(some_array).any? {|v| v > 0}
Whatever. Use Ruby rather than contrived APIs.
And when you need to cook your own assertions simply use assert
method to define them:
# defining a custom assertion
assert :is_a_pizza do |something|
something =~ /Cheese/ && something =~ /Olives/
end
# using it inside tests
test 'food' do
assert(something).is_a_pizza
end
Installation
Add this line to your application's Gemfile:
gem 'tiramisu'
And then execute:
$ bundle
Or install it yourself as:
$ gem install tiramisu
Usage
Add require 'tiramisu'
to your Rakefile
.
Then create a task and use Tiramisu.run
:
task :test do
Tiramisu.run
end
By default it will load *_spec.rb
and *_test.rb
files from ./spec
and ./test
folders.
If you named your test files differently use Tiramisu.run
with your pattern:
# search for test_*.rb files in ./tests folder
task :test do
Tiramisu.run 'tests/test_*.rb'
end
If you want to run tests directly just use tiramisu
in your terminal:
tiramisu
This will load *_spec.rb
and *_test.rb
files from ./spec
and ./test
folders.
If your tests have different naming conventions call tiramisu
command with a pattern.
For ex. load test_*.rb
files in ./tests
folder:
tiramisu tests/test_*.rb
Specs
Specs are defined by using spec
method. It requires a single argument - the spec label.
It can be whatever but nil
(which is used for another purpose, as shown below).
# defining a spec
spec Apple do
# and tests inside it
test :color do
end
end
Nested contexts can be used for splitting logic:
spec Greens do
context Fruits do
context Apple do
end
end
end
Specs are modules
spec
method returns a module. Specs including that module will inherit all tests:
FruitsTests = spec Fruits do
# some tests
end
spec Apple do
# inheriting tests from FruitsTests spec
include FruitsTests
# defining own specs
end
If you want a module that just holds tests without run them, use nil
for label:
FruitsTests = spec nil do
# tests defined here will run only on specs that includes FruitsTests
end
Global setups
spec
method can also be used for defining a superset of instructions that will be run by all specs.
For this to work spec
method should be called without arguments.
Then the given block will run equally on all consequent specs.
Multiple global setups can be defined and they will run inside specs in the order they was defined.
# supposedly in setup.rb
spec do
include SomeModule
end
# somewhere in test files
spec Fruits do
# this spec will include SomeModule implicitly
end
Before, around, after
Run some code before every test:
spec 'Fruits' do
before { @fruit = Fruit.new }
# tests here will have @fruit variable defined
end
When you need to run some code after every test simply use after
method same way as before
.
There is also an around
method that will wrap each test into a block.
The difference is you have to call test manually:
spec 'Fruits' do
around do |test|
# initialization stuff
test.call
# teardown stuff
end
# tests here will run inside around block
end
There is no way to run code before/around/after specific tests.
If you have tests that needs specific initialization/teardown logic put them into a separate context
.
Skipping tests and specs
When you need to skip a test simply use skip
method with a reason provided as first argument:
test 'something' do
# any code before skip will still run
skip 'will test this later'
# code here wont run
end
skip
also works for entire specs:
spec Fruits do
skip 'concentrating on Vegetables for now...'
# tests here wont run
end
Explicit failures
When you need to throw a failure with a custom message use fail
method:
test 'something' do
@a > @b || fail("#a should be greater than #b")
# code here wont run
end
raise
helper
raise
allows to check whether some code raises a specific or any exception.
Check the block raises whatever exception:
assert {some code}.raise
Check the block raises a NameError exception:
assert {some code}.raise NameError
Check the block raises a FruitError exception that match /apple/:
assert {some code}.raise FruitError, /apple/
Use a block to check raised exception:
assert {some code}.raise {|e| e.is_a? FruitError}
Also alternative syntax available:
expect {some code}.to_raise ...
throw
helper
Check the block throws whatever symbol:
assert {some code}.throw
Check the block throws :ok
symbol:
assert {some code}.throw :ok
Use a block to validate thrown symbol:
assert {some code}.throw {|s| s == :ok}
Also alternative syntax available:
expect {some code}.to_throw ...
Development
Make sure bundler
is installed then run bundle install
to install all dependencies.
Make your changes and run rake
to check all tests pass.
Contributing
- Fork it ( https://github.com/[my-github-username]/tiramisu/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request