Как включить модульные тесты в модуль ruby?

Я пытаюсь включить модульные тесты для модуля в том же исходном файле, что и сам модуль, следуя Perl modulino.

#! /usr/bin/env ruby

require 'test/unit'

module Modulino
    def modulino_function
        return 0
    end
end

class ModulinoTest < Test::Unit::TestCase
    include Modulino
    def test_modulino_function
        assert_equal(0, modulino_function)
    end
end

Теперь я могу запустить unit-tests, выполняющий этот исходный файл.

Но, они также запускаются, когда я требую/загружать их из другого script. Как этого можно избежать?

Есть ли более идиоматический способ добиться этого с помощью Ruby, если эта практика не обескуражена?

Ответ 1

Лично я никогда не слышал, чтобы кто-то пытался сделать это в Ruby. Это определенно не стандартная практика. Тем не менее, вы можете использовать этот трюк:

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

Код в блоке if будет выполняться только в том случае, если файл выполняется напрямую, а не если он требуется другой библиотекой или приложением.

Больше рубиновых трюков здесь: http://www.rubyinside.com/21-ruby-tricks-902.html

Ответ 2

На самом деле это не так уж редко встречается в Ruby, хотя это, конечно, не обычная практика в Rails.

Одной из проблем, с которыми вы можете столкнуться, является то же самое, что этот пост, который заключается в том, что модули действительно должны быть включены в классы, чтобы проверить их. Конечно, можно протестировать модуль, включив его в тестовый пример, но вы проверяете, работает ли модуль, когда он смешивается с Test:: Unit:: TestCase, но не работает, когда вы смешиваете его с чем-то более полезным.

Поэтому модульные тесты, вероятно, должны жить в файле класса или если вы просто хотите, чтобы общедоступные методы использовали функцию класса вместо модуля.

Ответ 3

Вы можете включить модульные тесты внутри самого исходного кода модуля, используя minitest.

Попробуйте этот пример:

class Foo < String
end

if $0 == __FILE__
    require 'minitest/autorun'
    require 'minitest/pride'

    class FooTest < MiniTest::Unit::TestCase
        def test_foo_instantiation
            foo = Foo.new()
            assert_instance_of Foo, foo
        end

        def test_foo_parent_class
            foo = Foo.new()
            assert_kind_of String, foo
        end
    end
end

Здесь я создал класс Foo, который наследуется от класса String. Затем я создал два модульных теста. В первом тесте я проверяю, могу ли я создать экземпляр объект класса Foo. Во втором тесте я проверяю, что экземпляр объекта класса Foo является своего рода строкой.

Если этот код написан в файле с именем foo.rb, я могу просто запустить тесты с помощью этой команды:

ruby foo.rb

Minitest работает быстро. Модуль "Гордость" позволяет выводить результат теста в цветные шрифты, что приятно на глазу.

Ответ 4

Просто найден один способ предотвратить выполнение unit test, когда модуль требуется от script. В unit.rb в .../lib/ruby/1.8/test/ есть флаг, чтобы установить значение true.

В сочетании с трюком samg (спасибо снова), мы можем написать:

if (__FILE__ != $0)
    Test::Unit.run = true  ### do not run the unit tests
end