Как включить модульные тесты в модуль 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