How to Include Unit Tests in a Ruby Module

How to include unit tests in a ruby module?

Personally I've never heard of anyone trying to do this in Ruby. It's definitely not a standard practice. That said you may be able to leverage this trick:

if __FILE__ == $0
# Do something.. run tests, call a method, etc. We're direct.
end

The code in the if block will only execute if the file is executed directly, not if it's required by another library or application.

More ruby tricks here: http://www.rubyinside.com/21-ruby-tricks-902.html

Rails: How do I write tests for a ruby module?

IMHO, you should be doing functional test coverage that will cover all uses of the module, and then test it in isolation in a unit test:

setup do
@object = Object.new
@object.extend(Greeter)
end

should "greet person" do
@object.stubs(:format).returns("Hello {{NAME}}")
assert_equal "Hello World", @object.greet("World")
end

should "greet person in pirate" do
@object.stubs(:format).returns("Avast {{NAME}} lad!")
assert_equal "Avast Jim lad!", @object.greet("Jim")
end

If your unit tests are good, you should be able to just smoke test the functionality in the modules it is mixed into.

Or…

Write a test helper, that asserts the correct behaviour, then use that against each class it's mixed in. Usage would be as follows:

setup do
@object = FooClass.new
end

should_act_as_greeter

If your unit tests are good, this can be a simple smoke test of the expected behavior, checking the right delegates are called etc.

Test modules with Test::Unit

Yeah, your initialize should definitely suggest that you're going towards a class. A module in ruby often feels like an interface in other languages, as long as you implement some basic things when you include the module you'll get a lot for free.

Enumerable is a great example, as long as you define [] and each when you include Enumerable you suddenly get pop, push, etc.

So my gut feeling about testing modules is that you should probably be testing classes that include the module rather than testing the module itself unless the module is designed to not be included in anything, it's simply a code storage mechanism.

How to test module in a module with rspec?

First of all, module A do syntax seems to be wrong - there shouldn't be a do word. The second thing is that you tries to call foo method on a module A::B (there is no class method defined on A::B - foo is an instance method). Your code should looks like:

module A
module B
def self.foo
end
end
end

*(In this case, you can call A::B.foo)

OR if you want to have foo as an instance method:

module A
module B
def foo
end
end
end

In this case you cannot call A::B.foo, but you can create a class, which can include A::B module:

class Test
include A::B
end

Now you can call Test.new.foo

Regarding rspec testing:

  • class method: as you described
  • instance method:

    • define Test class in your spec and then test this class
    • include this module to your rspec context (ugly way)

Ruby::test/unit - How do I dynamically insert tests in to the middle of a testcase?

Your custom tests are not running since they do not start with the word "test".

The "test" prefix is how Test::Unit knows which methods are tests vs regular methods. I believe Watir::TestCase is the same.

Try:

#customTest1.rb
module myStuff
def test_customTest1
#do stuff
end

def test_customTest2
#do stuff
end
end

UPDATE - Use TestSuite:

I am not sure why your solution does not work, but one solution that looks like works would be to use a TestSuite. You could then call your starting test cases, your custom test cases and then your ending test cases.

The test suite:

#testsuite.rb
require 'test/unit/ui/console/testrunner'
require 'test/unit/testsuite'
require 'rubygems'
require 'watir/testcase'
require 'testcase_start'
require 'testcase_end'
require 'customTest1'

class TS_MyTests
def self.suite
suite = Test::Unit::TestSuite.new
suite << TC_Test_US_Start.suite
suite << MyStuff.suite
suite << TC_Test_US_End.suite
return suite
end
end
Test::Unit::UI::Console::TestRunner.run(TS_MyTests)

Your starting tests:

#testcase_start.rb
class TC_Test_US_Start < Watir::TestCase
def test_a
#do stuff
puts 'a'
end

def test_b
#do stuff
puts 'b'
end
end

Your ending tests:

#testcase_end.rb
class TC_Test_US_End < Watir::TestCase
def test_y
#do stuff
puts 'y'
end

def test_z
#do stuff
puts 'z'
end

end

Your custom middle tests:

#customTest1.rb
class MyStuff < Watir::TestCase
def test_customTest1
puts '1'
end

def test_customTest2
puts '2'
end
end

Unit testing a module that is included in ActiveRecord models

First off, self.included is not a good way to describe your modules, and class_exec is needlessly complicating things. Instead, you should extend ActiveSupport::Concern, as in:

module Phoneable
extend ActiveSupport::Concern

included do
has_one :phone_number
validates_uniqueness_of :phone_number
end
end

You didn't mention what test framework you're using, but RSpec covers exactly this case. Try this:

shared_examples_for "a Phoneable" do
it "should have a phone number" do
subject.should respond_to :phone_number
end
end

Assuming your models look like:

class Person              class Business
include Phoneable include Phoneable
end end

Then, in your tests, you can do:

describe Person do
it_behaves_like "a Phoneable" # reuse Phoneable tests

it "should have a full name" do
subject.full_name.should == "Bob Smith"
end
end

describe Business do
it_behaves_like "a Phoneable" # reuse Phoneable tests

it "should have a ten-digit tax ID" do
subject.tax_id.should == "123-456-7890"
end
end

writing tests for modules in lib folder

I finally realized what was wrong. In my test files, I was including my modules from the lib directory, Instead of reopening the module and put the test files in the the module. After doing that rake test:units works perfectly. Test files should remain in test/unit directory



Related Topics



Leave a reply



Submit