Выполнить Rspec из Ruby
Я пытаюсь выполнить rspec из ruby и получить статус или количество отказов от метода или что-то в этом роде. На самом деле я запускаю что-то вроде этого:
system("rspec 'myfilepath'")
но я могу получить строку, возвращаемую функцией. Есть ли способ сделать это непосредственно с помощью объектов?
Ответы
Ответ 1
Я думаю, что лучший способ - использовать конфигурацию RSpec и Formatter. Это не связано с анализом потока ввода-вывода, а также программным образом улучшает настройку результатов.
RSpec 2:
require 'rspec'
config = RSpec.configuration
# optionally set the console output to colourful
# equivalent to set --color in .rspec file
config.color = true
# using the output to create a formatter
# documentation formatter is one of the default rspec formatter options
json_formatter = RSpec::Core::Formatters::JsonFormatter.new(config.output)
# set up the reporter with this formatter
reporter = RSpec::Core::Reporter.new(json_formatter)
config.instance_variable_set(:@reporter, reporter)
# run the test with rspec runner
# 'my_spec.rb' is the location of the spec file
RSpec::Core::Runner.run(['my_spec.rb'])
Теперь вы можете использовать объект json_formatter
для получения результата и сводки теста спецификации.
# gets an array of examples executed in this test run
json_formatter.output_hash
Пример значения output_hash
можно найти здесь:
RSpec 3
require 'rspec'
require 'rspec/core/formatters/json_formatter'
config = RSpec.configuration
formatter = RSpec::Core::Formatters::JsonFormatter.new(config.output_stream)
# create reporter with json formatter
reporter = RSpec::Core::Reporter.new(config)
config.instance_variable_set(:@reporter, reporter)
# internal hack
# api may not be stable, make sure lock down Rspec version
loader = config.send(:formatter_loader)
notifications = loader.send(:notifications_for, RSpec::Core::Formatters::JsonFormatter)
reporter.register_listener(formatter, *notifications)
RSpec::Core::Runner.run(['spec.rb'])
# here your json hash
p formatter.output_hash
Другие ресурсы
Ответ 2
Я предлагаю вам ознакомиться с исходным кодом rspec, чтобы узнать ответ. Я думаю, вы можете начать с example_group_runner
Изменить: Хорошо вот путь:
RSpec::Core::Runner::run(options, err, out)
Параметры - массив каталогов, err и out-streams. Например
RSpec::Core::Runner.run(['spec', 'another_specs'], $stderr, $stdout)
Ответ 3
Ваша проблема заключается в том, что вы используете метод Kernel#system
для выполнения вашей команды, которая возвращает только истину или ложь, основываясь на том, может ли она найти команду и успешно ее запустить. Вместо этого вы хотите захватить вывод команды rspec
. По сути, вы хотите захватить все, что rspec выводит на STDOUT. Затем вы можете перебирать результат, чтобы найти и проанализировать строку, которая расскажет вам, сколько примеров было выполнено и сколько было ошибок.
Что-то в следующих строках:
require 'open3'
stdin, stdout, stderr = Open3.popen3('rspec spec/models/my_crazy_spec.rb')
total_examples = 0
total_failures = 0
stdout.readlines.each do |line|
if line =~ /(\d*) examples, (\d*) failures/
total_examples = $1
total_failures = $2
end
end
puts total_examples
puts total_failures
Это должно выводить количество общих примеров и количество отказов - при необходимости адаптироваться.
Ответ 4
Он печатает на консоль и одновременно записывает сообщение. Formatter.stop - просто функция-заглушка, я не знаю, для чего она обычно, мне пришлось включить ее, чтобы использовать DocumentationFormatter. Также вывод форматера содержит коды раскраски консоли.
formatter = RSpec::Core::Formatters::DocumentationFormatter.new(StringIO.new)
def formatter.stop(arg1)
end
RSpec.configuration.reporter.register_listener(formatter, :message, :dump_summary, :dump_profile, :stop, :seed, :close, :start, :example_group_started)
RSpec::Core::Runner.run(['test.rb','-fdocumentation'])
puts formatter.output.string