Quickdraw is a new test framework for Ruby:
- Spec-like DSL, but with just five methods:
describe
,test
andexpect
,assert
,refute
. Nocontext
,let
,subject
,to
,it
,is_expected
orspecify
, and you’ll never need to guess whether the next symbol should be a space, a colon, a dot or an underscore. - No chaining on matchers. Rather than chain, the matcher can yield if it wants to allow for more complex matching.
- Auto-loaded configuration, so you never need to
require "test_helper"
. - Scoped execution, so you can define methods and constants at the top level without worrying about collisions.
- You can define your own matchers, which can be scoped to a specific type of object and they can be overloaded for different types.
- Designed to take advantage of all your CPU cores — by default it runs one process per CPU core and two threads per process.
- Built in mocking and spying.
- Error messages are calculated lazily, so you don’t need to worry about expensive failure messages slowing down your tests.
- Optional test names — sometimes the code is so clear, you don’t need names.
- Make as many expectations as you want in a test. You’ll get a dot for each one to make you feel good about youtself.
[Coming soon]:
- Hooks for running code before, after, or around tests, files, or suites. You’ll also be able to hook into forking processes and threads.
- Built in code coverage reports.
- Built in profiling.
- Rich diffs for failed equality expectations.
- Configurable dots.
- Retry flaky tests.
Warning
Quickdraw is currently in development. You should almost definitely not use it in a project until 1.0
is released.
Tip
Your test files are executed in an anonymous class, so you can define methods and constants at the top level without worrying about collisions. If you’re testing something that references Class#name
, you may have to define those classes as fixtures somewhere else.
Add this line to your application's Gemfile:
gem 'quickdraw'
And then execute:
bundle install
Now create a file called config/quickdraw.rb
.
To run tests, execute:
bundle exec qt
It stands for "quickdraw tests".
Quickdraw searches for files that end with .test.rb
. You can put these anywhere. Some people like to put them under /tests
or /spec
. Others like to put them next to the code they're testing.
Use the test
method to define a test. The description is optional — sometimes you don’t need it.
test { assert true }
You can pass skip: true
to skip the test. Skipped tests are still run; they pass if they fail and fail they pass.
test(skip: true) { assert false }
You can optionally wrap tests in any number of describe
blocks, which can take a description as a string or module/class.
describe Thing do
# your Thing tests here
end
assert
takes a value and passes if it’s truthy.
test "something" do
assert true
end
You can pass a custom failure message as a block. Using blocks for the failure messages means we don’t waste time constructing them unless the test fails. You don’t need to worry about expensive failure messages slowing down your tests.
test "something" do
assert(false) { "This is a custom failure message" }
end
refute
is just like assert
, but it passes if the value is falsy.
test "something" do
refute false
end
expect
takes either a value or a block and returns an expectation object, which you can call matchers on.
test "equality" do
expect(Thing.foo) == "foo"
expect(Thing.bar) != "foo"
end
test "raises" do
expect { Thing.bar! }.to_raise(ArgumentError) do |error|
expect(error.message) == "Foo bar"
end
end
test "mocks and spies" do
expect(Thing).to_receive(:foo) do |a, b, c|
# The block receives arguments and can make assertions about them.
expect(a) == 1
expect(b) != 1
assert(c)
# Either return a mock response or call the original via `@super`
@super.call
end
Thing.foo(1, 2, 3)
end