有没有办法创建一个自定义格式化程序,其中显示传递的测试详细信息,并显示除了列表?
这个问题的背景知识:我们正在尝试迁移到RSpec进行硬件集成和系统测试。结果应推送到CouchDB。我想要实现的是一个可以生成类似YAML输出的记者,如下面的片段:
{
"_id": "0006b6f0-c1bd-0135-1a98-455c37fe87f1",
"_rev": "1-9c9786b4b4681ee8493f182d4fc56ef9",
"sha1_repo": "68bb327b540097c10683830f0d82acbe54a47f03",
"steps": [
{
"result": "pass",
"description": "Time for Routing expect OK: 126 micro seconds (DLC and Data also OK)"
},
{
"result": "pass",
"description": "Time for Routing expect OK: 146 micro seconds (DLC and Data also OK)"
},
{
"result": "pass",
"description": "Time for Routing expect OK: 162 micro seconds (DLC and Data also OK)"
}
],
"time_start": "1513119108000",
"time_end": "1513119108000",
"result": "pass",
"testcase_title": "Komfort_TSG_HBFS_03_to_Komfort2_TSG_HBFS_03",
"testcase_id": "TC_1zu1_BAF_Komfort_TSG_HBFS_03_to_Komfort2_TSG_HBFS_03",
"hierarchy": [
"Hardware Integration Test",
"1 - Routing",
"1.1 Normal Routing",
"1zu1_BAF_TestCases",
"CAN_to_CAN"
]
}
如果测试失败,那么实现这一目标是没有问题的,但我们还需要通过测试的结果,以便能够创建长期统计数据。
我可以覆盖传递的RSPec事件,但示例对象只提供描述而不再提供信息。
class EliteReporter
RSpec::Core::Formatters.register self, :example_started, :example_passed, :example_failed, :example_finished
def example_passed(passed)
@output.printf "pass \n #{passed.example.description}"
end
end
提前感谢您的帮助。
答案 0 :(得分:1)
最后在我的同事的帮助下,感谢Tip from RSPec Emailing list我能做到这一点。
我创建了一个收集测试结果的Recorder类,而不是覆盖Expect方法。这种方式在自定义格式化程序中,我可以收集所有传递的结果:
class ExpectWrapper
def initialize(_expect, _recorder, _description)
@expect = _expect
@recorder = _recorder
@description = _description
end
def to(matcher, failure_message=nil)
begin
expect_ret = @expect.to(matcher, failure_message) # test
# for tests that aggregate failures
if expect_ret.instance_of?(TrueClass)
@recorder.record(matcher.actual, matcher.description, @description)
else
@recorder.record_error(matcher.actual, matcher.description, failure_message, @description)
end
expect_ret
rescue RSpec::Expectations::ExpectationNotMetError => e
# for test that do not aggregate failures
@recorder.record_error(matcher.actual, matcher.description, failure_message, @description)
raise e
end
end
end
class Recorder
def self.start
@@data = []
return Recorder.new
end
def record(expect, data, description)
@@data << { :pass => true, :expect => expect, :value => data, :description => description }
self
end
def record_error(expect, data, failure_message, description)
@@data << { :pass => false, :expect => expect, :value => data, :message => failure_message, :description => description }
self
end
def self.data
@@data
end
def expect(object, value, description = "")
return ExpectWrapper.new(object.expect(value), self, description)
end
end
自定义格式化程序看起来如下,只是一个例子,数据可以放到JSON并推送到Couch:
class EliteVerboseFormatter
RSpec::Core::Formatters.register self, :example_started, :example_passed, :example_failed, :example_finished
def initialize(output)
@output = output
end
def example_passed(notification)
@output.puts( format_output(notification.example, Recorder) )
end
def get_test_name( group, description)
"#{group.example.example_group}/#{description}".gsub('RSpec::ExampleGroups::','')
end
def format_output( example, recorder )
test_case = get_test_name( example.example_group, example.description)
str = "**********TEST: #{test_case} ************\n"
recorder.data.each do |d|
str += sprintf("%s: ---> expected '%-10s' to '%-20s' DESC: %s \n", d[:pass] ? 'PASS' : 'FAIL', d[:expect], d[:value], d[:description])
end
str
end
def example_failed(notification)
@output.puts(format_output( notification.example, Recorder))
exception = notification.exception
message_lines = notification.fully_formatted_lines(nil, RSpec::Core::Notifications::NullColorizer)
exception_details = if exception
{
# drop 2 removes the description (regardless of newlines) and leading blank line
:message => message_lines.drop(2).join("\n"),
:backtrace => notification.formatted_backtrace.join("\n"),
}
end
@output.puts RSpec::Core::Formatters::ConsoleCodes.wrap(exception_details[:message], :failure)
end
end
答案 1 :(得分:0)
我想你可以阅读Module: RSpec::Core::Formatters
你可能会发现一些有用的东西。
P.S。我曾经多次使用过Cucumber,我曾经想要定制黄瓜格式化程序来显示每一步的细节,无论它失败还是过去。我终于通过阅读黄瓜核心文件得到了解决方案。所以我想也许rspec核心文档可以帮助你找到解决方案。
答案 2 :(得分:0)
我发现我不能把代码放在评论中,所以我把它放在这里。 编辑您的代码如下:
class EliteReporter
RSpec::Core::Formatters.register self, :example_started, :example_passed, :example_failed, :example_finished
def example_passed(example)
example_failed(example)
end
end
我希望它有用:)