Как я могу протестировать сообщения регистратора с помощью MiniTest?

У меня есть приложение, и я хочу проверить, получаю ли я правильные сообщения от моего регистратора.

Короткий пример (вы можете переключаться между log4r и регистратором):

gem 'minitest'
require 'minitest/autorun'
require 'log4r'
#~ require 'logger'
class Testlog < MiniTest::Test
  def setup
    if defined? Log4r
      @log = Log4r::Logger.new('log')
      @log.outputters << Log4r::StdoutOutputter.new('stdout', :level => Log4r::INFO)
    else
      @log = Logger.new(STDOUT)
      @log.level = Logger::INFO
    end
  end

  def test_silent
    assert_silent{ @log.debug("hello world") }
    assert_output(nil,nil){ @log.debug("Hello World") }
  end
  def test_output
    #~ refute_silent{ @log.INFO("Hello") }#-> NoMethodError: undefined method `refute_silent'        
    assert_output("INFO log: Hello World\n",''){ @log.info("Hello World") }
  end

end

Но я получаю:

  1) Failure:
Testlog#test_output [minitest_log4r.rb:27]:
In stdout.
Expected: "INFO log: Hello World\n"
  Actual: ""

На моем экране вывода я вижу сообщение. У меня похожие результаты с Log4r::StderrOutputter и Log4r::Outputter.stdout.

Таким образом, кажется, что он отправляется на экран вывода, но не перехватывается минитестом в STDOUT или STDERR.

Прежде чем я начну писать minitest-log4r-Gem:

Есть ли возможность протестировать вывод регистратора в минитесте?


Если нет: какие-нибудь рекомендации по реализации minitest-log4r-Gem?

Примеры того, что я мог представить:

  • определить новый модуль вывода для минитеста (Log4r::MinitestOutputter)
  • Издевайтесь над регистратором.
  • new assertions (add the new outputter as parameter?):
    • assert_message('INFO log: Hello World'){ @log.info("Hello World") }
    • assert_messages(:info => 1, :debug => 2){ @log.info("Hello World") } для подсчета сообщений.
    • assert_info_messages('Hello World'){ @log.info("Hello World") }
    • assert_debug_messages('Hello World'){ @log.info("Hello World") }

person knut    schedule 01.04.2015    source источник


Ответы (3)


Тем временем я создал minitest-logger-Gem.

Пример кода, как его использовать:

require 'log4r'
require 'minitest-logger'

class Test_log4r < MiniTest::Test
  def setup 
    @log = Log4r::Logger.new('log')
    @log.level = Log4r::INFO
  end    
  def test_output_1 
    assert_log(" INFO log: Hello World\n"){ @log.info("Hello World") }
  end
  def test_output_regex
    assert_log(/Hello World/){ @log.info("Hello World") }
  end  

  def test_silent
    assert_silent_log(){
      @log.debug("Hello World")
      #~ @log.info("Hello World")     #uncomment this to see a failure
    }
    refute_silent_log(){
      @log.warn("Hello World")     #comment this to see a failure
    }
  end

end

Во время теста в регистратор @log добавляется временный вывод. После теста выходной модуль снова удаляется.

Gem поддерживает log4r и регистратор.

person knut    schedule 16.04.2015

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

http://ruby-doc.org/core-2.1.0/IO.html#method-c-pipe

Что-то типа:

require 'logger'
r, w = IO.pipe
log = Logger.new(w)
log.info "testing info log message"
output = r.gets
puts "Test passed: #{!!(/testing/ =~ output)}"
person Puhlze    schedule 01.04.2015
comment
Здесь небольшая опечатка. Должно быть output = r.gets - person Derek Hill; 13.11.2016

Ответ @Pulze хороший. Просто для неблокировки проверьте заранее, есть ли доступный ввод:

if IO.select([r], [], [], 0.01).nil?
person dev-Bilal    schedule 04.10.2020