Writing Specifications with MiniTest::Spec
We are using MiniTest::Spec, Fabricator and Capybara to write the Specifications for the dreamforge project. We write Model Specs and Integration Specs. Every feature first needs to be specified via MiniTest before it gets implemented. Every Bug needs to be formulated as a Regression Test.
For every model we create a spec file in test/models/
named MODELNAME_spec.rb
and a fabricator in test/fabricators/
named MODELNAME_fabricator.rb
. In the fabricator create the model with all fields filled in. To invalidate your model you can remove attributes from your fabricator. You can find all information on Fabricator here.
For each page the user might visit we create an integration test in test/integration
named CONTROLLERNAME_integration_spec.rb
. We use Capybara, so there are some additional matchers available.
To add a expectation, go to the test/support
directory and add the corresponding expectation to custom_capybara_expectations.rb if it is Integration-Test specific or custom_minitest_expectations.rb if it is of general usage.
Are added as follows to the MiniTest::Assertions
module:
def assert_valid(obj, msg = nil)
msg = message(msg) { "Expected #{mu_pp(obj)} to be valid" }
assert obj.valid?, msg
end
And then add the expectation to the module MiniTest::Expectations
via the infect_an_assertion
method like this:
infect_an_assertion :assert_valid, :must_be_valid
Are added as follows to the Capybara::Sessions
class:
def has_flash_message?(message)
within '#flash' do
has_content? message
end
end
And then add the expectation as a matcher as follows:
CapybaraMiniTestSpec::Matcher.new(:has_flash_message?)
Only positive expectations listed – for negative expectations switch must
to wont
.
Based on the list from RubyInside. Thanks, Peter!
-
obj.must_be(operator, expected): for example,
10.must_be :< , 11
- obj.must_be_close_to: the equivalent of assert_in_delta
- obj.must_be_empty: Fails unless obj.empty?
-
obj.must_be_instance_of(klass): Fails unless
obj.class == klass
- obj.must_be_kind_of(klass): Fails unless obj is of class klass or klass is one of its superclasses
- obj.must_be_nil
- obj.must_be_same_as: tests for true object equality
- lambda {}.must_be_silent
- obj.must_be_within_delta
- obj.must_be_within_epsilon
-
obj.must_equal(other): Does a
==/eql?
comparison between two objects. - obj.must_include(other)
- obj.must_match(regex)
- lambda {}.must_output(stdout, [stderr..]): The block should have certain output on stdout or stderr. Set stdout to nil just to check stderr.
- lambda {}.must_raise(exception)
- obj.must_respond_to(message)
- obj.must_throw(sym)
- must_be_valid
- must_be_invalid
- page.must_have_selector('table tr')
- page.must_have_selector(:xpath, '//table/tr')
- page.must_have_no_selector(:content)
- page.must_have_xpath('//table/tr')
- page.must_have_css('table tr.foo')
- page.must_have_content('foo')
- must_have_flash_message
- must_have_link_to(path)
- visit(path): Goes to the specified page, always uses GET.
- current_path: Returns the current path
- click_link(id-or-link-text)
- click_button(id-or-button-text)
- click_on(id-or-text-of-link-or-button
- fill_in('First Name', :with => 'John')
- fill_in('Password', :with => 'Seekrit')
- fill_in('Description', :with => 'Really Long Text...')
- choose('A Radio Button')
- check('A Checkbox')
- uncheck('A Checkbox')
- attach_file('Image', '/path/to/image.jpg')
- select('Option', :from => 'Select Box')
- find_field('First Name').value
- find_link('Hello').visible?
- find_button('Send').click
- find(:xpath, "//table/tr").click
- find("#overlay").find("h1").click
- all('a').each { |a| a[:href] }
- within(selector, &block): Scopes the block to the given selector
- within_fieldset(selector, &block): Scopes the block to the given selector
- within_table(selector, &block): Scopes the block to the given selector
- save_and_open_page: Take a snapshot of the page as it currently is and take a look at it
- sign_in: Goes to the sign-in page, logs in as a normal user. Returns the logged-in user
-
sign_in(user): Goes to the sign-in page, logs in as
user