A TestCase defines a suite of related tests. You can further categorize your tests by declaring nested contexts inside the class. See ::context.
Fancy name for your test case, reports can use this to give nice, descriptive output when running your tests.
Define a new test context nested under the current one. All
setup
and teardown
blocks defined on the current
context will be inherited by the new context. This method is aliased as
describe
and story
for your comfort.
# File lib/protest/test_case.rb, line 120 def self.context(description, &block) subclass = Class.new(self) subclass.class_eval(&block) if block subclass.description = description const_set(sanitize_description(description), subclass) end
Add a setup
block that will be run once for
the entire test case, before the first test is run.
Keep in mind that while setup
blocks are evaluated on the
context of the test, and thus you can share state between them, your tests
will not be able to access instance variables set in a
global_setup
block.
This is usually not needed (and generally using it is a code smell, since you could make a test dependent on the state of other tests, which is a huge problem), but it comes in handy when you need to do expensive operations in your test setup/teardown and the tests won't modify the state set on this operations. For example, creating large amount of records in a database or filesystem, when your tests will only read these records.
This method is aliased as before_all
for your comfort.
# File lib/protest/test_case.rb, line 77 def self.global_setup(&block) (class << self; self; end).class_eval do define_method :do_global_setup do super() instance_eval(&block) end end end
Add a teardown
block that will be run once
for the entire test case, after the last test is run.
Keep in mind that while teardown
blocks are evaluated on the
context of the test, and thus you can share state between the tests and the
teardown blocks, you will not be able to access instance variables set in a
test from your global_teardown
block.
See ::global_setup for a discussion on why these methods are best avoided unless you really need them and use them carefully.
This method is aliased as after_all
for your comfort.
# File lib/protest/test_case.rb, line 107 def self.global_teardown(&block) (class << self; self; end).class_eval do define_method :do_global_teardown do instance_eval(&block) super() end end end
Initialize a new instance of a single test. This test can be run in isolation by calling #run.
# File lib/protest/test_case.rb, line 148 def initialize(name, location, &block) @test = block @location = location @name = name end
Run all tests in this context. Takes a Runner instance in order to provide output.
# File lib/protest/test_case.rb, line 30 def self.run(runner) runner.report(TestWrapper.new(:setup, self)) tests.each {|test| runner.report(test) } runner.report(TestWrapper.new(:teardown, self)) rescue Exception => e # If any exception bubbles up here, then it means it was during the # global setup/teardown blocks, so let's just skip the rest of this # context. return end
Add a setup block to be run before each test in this context. This method
is aliased as before
for your comfort.
# File lib/protest/test_case.rb, line 54 def self.setup(&block) define_method :setup do super() instance_eval(&block) end end
Add a teardown block to be run after each test in this context. This method
is aliased as after
for your comfort.
# File lib/protest/test_case.rb, line 88 def self.teardown(&block) define_method :teardown do instance_eval(&block) super() end end
Add a test to be run in this context. This method is aliased as
it
, should
and scenario
for your
comfort.
# File lib/protest/test_case.rb, line 48 def self.test(name, &block) tests << new(name, caller.at(0), &block) end
Tests added to this context.
# File lib/protest/test_case.rb, line 42 def self.tests @tests ||= [] end
# File lib/protest/test_case.rb, line 239 def self.do_global_setup end
# File lib/protest/test_case.rb, line 243 def self.do_global_teardown end
# File lib/protest/test_case.rb, line 252 def self.inherited(child) Protest.add_test_case(child) end
# File lib/protest/test_case.rb, line 234 def self.sanitize_description(description) "Test#{description.gsub(/\W+/, ' ').strip.gsub(/(^| )(\w)/) { $2.upcase }}".to_sym end
Ensure a condition is met. This will raise AssertionFailed if the condition isn't met. You can override the default failure message by passing it as an argument.
# File lib/protest/test_case.rb, line 177 def assert(condition, message="Expected condition to be satisfied") @report.on_assertion raise AssertionFailed, message unless condition end
Passes if expected == actual. You can override the default failure message by passing it as an argument.
# File lib/protest/test_case.rb, line 184 def assert_equal(expected, actual, message=nil) assert expected == actual, message || "#{expected.inspect} expected but was #{actual.inspect}" end
Passes if the code block raises the specified exception. If no exception is specified, passes if any exception is raised, otherwise it fails. You can override the default failure message by passing it as an argument.
# File lib/protest/test_case.rb, line 192 def assert_raise(exception_class=Exception, message=nil) begin yield rescue exception_class => e ensure assert e, message || "Expected #{exception_class.name} to be raised" end end
Name of the test
# File lib/protest/test_case.rb, line 208 def name @name end
Make the test be ignored as pending. You can override the default message that will be sent to the report by passing it as an argument.
# File lib/protest/test_case.rb, line 203 def pending(message="Not Yet Implemented") raise Pending, message, [@location, *caller].uniq end
Tests must not re-raise exceptions
# File lib/protest/test_case.rb, line 213 def raise_exceptions? false end
This is a real test
# File lib/protest/test_case.rb, line 218 def real? true end
Run a test in isolation. Any setup
and teardown
blocks defined for this test case will be run as expected.
You need to provide a Runner instance to handle errors/pending tests/etc.
If the test's block is nil, then the test will be marked as pending and nothing will be run.
# File lib/protest/test_case.rb, line 161 def run(report) @report = report pending if test.nil? begin setup instance_eval(&test) ensure teardown @report = nil end end
# File lib/protest/test_case.rb, line 230 def test @test end