Skip to content

Commit

Permalink
Improve examples and documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
soveran committed Sep 20, 2010
1 parent e31e6d1 commit 5f3f99b
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 32 deletions.
83 changes: 72 additions & 11 deletions README.markdown
Expand Up @@ -8,16 +8,39 @@ Description

Run tests in separate processes to avoid shared state.

Each test file is loaded in a forked process and, if the second
parameter to `Cutest.run` is true, inside an anonymous module. Once a
failure is found in a file, the rest of the file is skipped and the
error is reported. This way, running your test suite feels faster.

There are no nested contexts, just the `setup` and `test` methods.
Unlike other testing tools, the result of evaluating the setup is
passed as a parameter to each test. Even if you can still use instance
variables, the code in the examples is the suggested way to keep tests
from sharing information.
Each test file is run in a forked process and, if the second parameter to
`Cutest.run` is true, it is also loaded inside an anonymous module. Once a
failure is found in a file, the rest of the file is skipped and the error is
reported. This way, running your test suite feels faster.

You can use the `scope` command around tests: it guarantees that no instance
variables are shared between tests.

There are two commands very similar in nature, but with a subtle difference that
makes them easy to combine in order to satisfy different needs: `prepare` and
`setup`.

The `prepare` blocks are executed before each test. If you call `prepare` many
times, each passed block is appended to an array. When the test is run, all
those prepare blocks are executed in order. The result of the block is
discarded, so it is only useful for preparing the environment (flushing the
database, removing a directory, etc.).

The `setup` block is executed before each test and the result is passed as a
parameter to the `test` block. Unlike `prepare`, each definition of `setup`
overrides the previous one. Even if you can declare instance variables and
share them between tests, the recommended usage is to pass the result of the
block as a parameter to the `test` blocks.

The `test` method executes the passed block after running `prepare` and
`setup`. This is where assertions must be declared.

Two assertions are available: `assert` and `assert_raise`. The first accepts a
value and raises an `AssertionFailed` exception if it's false or nil, and the
later receives an expected exception and a block: the block is executed and
the raised exception is compared with the expected one. An `AssertionFailed`
exception is raised if the block runs fine or if the raised exception doesn't
match the expectation.

Usage
-----
Expand Down Expand Up @@ -50,6 +73,7 @@ In your tests:
assert 23 == params[:a]
end


To run the tests:

$ rake
Expand All @@ -63,6 +87,43 @@ Instead of a description of the error, you get to see the assertion
that failed along with the file and line number. Adding a debugger and
fixing the bug is left as an exercise for the reader.

An example working with a prepare block:

prepare do
Ohm.flush
end

setup do
Ohm.redis.get("foo")
end

test do |foo|
assert foo.nil?
end

And working with scopes:

setup do
@foo = true
end

@bar = true

scope do
test "should not share instance variables" do |foo|
assert !defined?(@foo)
assert !defined?(@bar)
assert foo == true
end
end

The tests in these two examples will pass.

Unlike other testing frameworks, Cutest does not compile all the tests before
running them. Another shift in design is that one dot is shown after a file is
examined, and not the usual one-dot-per-assertion. And finally, the execution
of a file stops one the first failure is found.

Installation
------------

Expand All @@ -71,7 +132,7 @@ Installation
License
-------

Copyright (c) 2009 Damian Janowski and Michel Martens
Copyright (c) 2010 Damian Janowski and Michel Martens

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
Expand Down
23 changes: 10 additions & 13 deletions lib/cutest.rb
Expand Up @@ -3,14 +3,8 @@
class Cutest < Batch
VERSION = "0.0.6"

def report_errors
return if @errors.empty?

$stderr.puts "\nSome errors occured:\n\n"

@errors.each do |item, error|
$stderr.puts error, "\n"
end
def report_error(_, error)
$stderr.puts "#{error}\n"
end

def self.run(files, anonymous = false)
Expand Down Expand Up @@ -65,14 +59,14 @@ def cutest
Thread.current[:cutest]
end

# Create a class where the block will be evaluated. Recomended to improve
# Create a class where the block will be evaluated. Recommended to improve
# isolation between tests.
def scope(&blk)
Cutest::Scope.new(&blk).call
def scope(&block)
Cutest::Scope.new(&block).call
end

# Prepare the environment in order to run the tests. This method can be called
# many times, and each new block is appened to a list of preparation blocks.
# many times, and each new block is appended to a list of preparation blocks.
# When a test is executed, all the preparation blocks are ran in the order they
# were declared. If called without a block, it returns the array of preparation
# blocks.
Expand Down Expand Up @@ -101,7 +95,10 @@ def setup(&block)
cutest[:setup]
end

# Call all the prepare blocks and setup blocks before executing the test. Even
# Kernel includes a test method for performing tests on files.
undef test if defined? test

# Call the prepare and setup blocks before executing the test. Even
# though the assertions can live anywhere (it's not mandatory to put them
# inside test blocks), it is necessary to wrap them in test blocks in order to
# execute preparation and setup blocks.
Expand Down
4 changes: 2 additions & 2 deletions test/prepare.rb
Expand Up @@ -18,8 +18,8 @@
assert $foo == [true, false]
end

module Foo
test "and run inside modules" do
scope do
test "and run inside scopes" do
assert $foo = [true, false]
end
end
4 changes: 0 additions & 4 deletions test/scopes.rb
@@ -1,20 +1,16 @@
@bar = true

prepare { $foo = false }

scope do
@foo = true

test "something" do
assert !$foo
assert defined?(@foo)
assert !defined?(@bar)
end
end

scope do
test "something" do
assert !$foo
assert !defined?(@foo)
assert !defined?(@bar)
end
Expand Down
4 changes: 2 additions & 2 deletions test/setup.rb
Expand Up @@ -22,8 +22,8 @@
assert "Hello world!" == value
end

module Foo
test "works inside modules too" do |value|
scope do
test "works inside scopes too" do |value|
assert "Hello world!" == value
end
end

0 comments on commit 5f3f99b

Please sign in to comment.