Build Status

Tokyo - 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 'tokyo'

And then execute:

$ bundle

Or install it yourself as:

$ gem install tokyo

Usage

Add require 'tokyo' to your Rakefile.

Then create a task and use Tokyo.run:

task :test do
  Tokyo.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 Tokyo.run with your pattern:

# search for test_*.rb files in ./tests folder
task :test do
  Tokyo.run 'tests/test_*.rb'
end

If you want to run tests directly just use tokyo in your terminal:

tokyo

This will load *_spec.rb and *_test.rb files from ./spec and ./test folders.
If your tests have different naming conventions call tokyo command with a pattern.
For ex. load test_*.rb files in ./tests folder:

tokyo 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

  1. Fork it ( https://github.com/[my-github-username]/tokyo/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request