2009-12-01 3 views
4

Я пытаюсь включить модульные тесты для модуля в том же исходном файле, что и сам модуль, следуя модели 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 

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

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

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

ответ

11

Лично я никогда не слышал о том, чтобы кто-то пытался это сделать в 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

+0

Я считаю, что это удобный способ работы с (как правило) небольшими независимыми модулями, когда они все еще «молоды», особенно когда я работаю в редакторе, в котором я могу выполнить сразу (например, SciTE). Очевидно, что это не проблема, когда у вас есть более крупные тела кода и/или AutoTest. Но я не живу в этом мире ;-) –

+0

Thansk, это будет работать со стандартным (нормальным?) Модулем, но НЕ работает с модульными тестами, поскольку они выполняются автоматически. +1 для ссылки – philant

+1

Вы можете поставить 'require 'test/unit'' и определения тестового примера внутри оператора if, а затем они будут выполняться только при выполнении текущего файла. – BaroqueBobcat

3

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

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

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

1

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

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

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

Вы можете включать в себя модульные тесты внутри самого исходного кода модуля с использованием 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 является своего рода String.

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

ruby foo.rb 

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