我在寫一些ruby(不是Rails),並且用shoulda來測試/測試單元。有沒有好的ruby測試追蹤解決方案?
是否有任何寶石可以讓我實現從測試到設計/需求的可追溯性?
即:我想與他們測試的要求,名稱標記我的測試,然後生成的未測試的要求,報告或有失敗的測試等
希望這不是爲紅寶石太enterprisey 。
謝謝!
我在寫一些ruby(不是Rails),並且用shoulda來測試/測試單元。有沒有好的ruby測試追蹤解決方案?
是否有任何寶石可以讓我實現從測試到設計/需求的可追溯性?
即:我想與他們測試的要求,名稱標記我的測試,然後生成的未測試的要求,報告或有失敗的測試等
希望這不是爲紅寶石太enterprisey 。
謝謝!
更新:該解決方案可作爲寶石:http://rubygems.org/gems/test4requirements
是否有任何寶石是是否允許我實現從我的 測試回溯到設計/要求的可追溯性?
我不知道任何寶石,但你的需要是一個小實驗的靈感,它是如何解決的。
而現在的例子:
gem 'test-unit'
require 'test/unit'
###########
# This should be a gem
###########
class Test::Unit::TestCase
def self.requirements(req)
@@requirements = req
end
def requirement(req)
raise RuntimeError, "No requirements defined for #{self}" unless defined? @@requirements
caller.first =~ /:\d+:in `(.*)'/
@@requirements.add_test(req, "#{self.class}##{$1}")
end
alias :run_test_old :run_test
def run_test
run_test_old
#this code is left if a problem occured.
#in other words: if we reach this place, then the test was sucesfull
if defined? @@requirements
@@requirements.test_successfull("#{self.class}##{@method_name}")
end
end
end
class RequirementList
def initialize(*reqs)
@requirements = reqs
@tests = {}
@success = {}
#Yes, we need two at_exit.
#tests are done also at_exit. With double at_exit, we are after that.
#Maybe better to be added later.
at_exit {
at_exit do
self.overview
end
}
end
def add_test(key, loc)
#fixme check duplicates
@tests[key] = loc
end
def test_successfull(loc)
#fixme check duplicates
@success[loc] = true
end
def overview()
puts "Requirements overiew"
@requirements.each{|req|
if @tests[req] #test defined
if @success[@tests[req]]
puts "Requirement #{req} was tested in #{@tests[req] }"
else
puts "Requirement #{req} was unsuccessfull tested in #{@tests[req] }"
end
else
puts "Requirement #{req} was not tested"
end
}
end
end #RequirementList
###############
## Here the gem end. The test will come.
###############
$req = RequirementList.new(1,2,3, 4)
class MyTest < Test::Unit::TestCase
#Following requirements exist, and must be tested sucessfull
requirements $req
def test_1()
requirement(1) #this test is testing requirement 1
assert_equal(2,1+1)
end
def test_2()
requirement(2)
assert_equal(3,1+1)
end
def test_3()
#no assignment to requirement 3
pend 'pend'
end
end
class MyTest_4 < Test::Unit::TestCase
#Following requirements exist, and must be tested sucessfull
requirements $req
def test_4()
requirement(4) #this test is testing requirement 4
assert_equal(2,1+1)
end
end
結果:
Loaded suite testing_traceability_solutions
Started
.FP.
1) Failure:
test_2(MyTest)
[testing_traceability_solutions.rb:89:in `test_2'
testing_traceability_solutions.rb:24:in `run_test']:
<3> expected but was
<2>.
2) Pending: pend
test_3(MyTest)
testing_traceability_solutions.rb:92:in `test_3'
testing_traceability_solutions.rb:24:in `run_test'
Finished in 0.65625 seconds.
4 tests, 3 assertions, 1 failures, 0 errors, 1 pendings, 0 omissions, 0 notifications
50% passed
Requirements overview:
Requirement 1 was tested in MyTest#test_1
Requirement 2 was unsuccessfull tested in MyTest#test_2
Requirement 3 was not tested
Requirement 4 was tested in MyTest_4#test_4
如果你認爲,這可能是一個解決方案給你,請給我一個反饋。然後我會嘗試從它身上創建一個寶石。
代碼示例使用與早該
#~ require 'test4requirements' ###does not exist/use code above
require 'shoulda'
#use another interface ##not implemented###
#~ $req = Requirement.new_from_file('requirments.txt')
class MyTest_shoulda < Test::Unit::TestCase
#Following requirements exist, and must be tested sucessfull
#~ requirements $req
context 'req. of customer X' do
#Add requirement as parameter of should
# does not work yet
should 'fullfill request 1', requirement: 1 do
assert_equal(2,1+1)
end
#add requirement via requirement command
#works already
should 'fullfill request 1' do
requirement(1) #this test is testing requirement 1
assert_equal(2,1+1)
end
end #context
end #MyTest_shoulda
隨着cucumber你可以有你的要求是測試,沒有得到任何比這更可追蹤:)
所以一個要求是功能,和功能有要測試場景。
# addition.feature
Feature: Addition
In order to avoid silly mistakes
As a math idiot
I want to be told the sum of two numbers
Scenario Outline: Add two numbers
Given I have entered <input_1> into the calculator
And I have entered <input_2> into the calculator
When I press <button>
Then the result should be <output> on the screen
Examples:
| input_1 | input_2 | button | output |
| 20 | 30 | add | 50 |
| 2 | 5 | add | 7 |
| 0 | 40 | add | 40 |
那麼你已經使用Ruby編寫的步驟定義映射到場景
# step_definitons/calculator_steps.rb
begin require 'rspec/expectations'; rescue LoadError; require 'spec/expectations'; end
require 'cucumber/formatter/unicode'
$:.unshift(File.dirname(__FILE__) + '/../../lib')
require 'calculator'
Before do
@calc = Calculator.new
end
After do
end
Given /I have entered (\d+) into the calculator/ do |n|
@calc.push n.to_i
end
When /I press (\w+)/ do |op|
@result = @calc.send op
end
Then /the result should be (.*) on the screen/ do |result|
@result.should == result.to_f
end
這看起來很漂亮,但我不知道它會爲我工作。例如,我的一個測試檢查一個方法的返回值,該方法是一個包含150個元素的3D數組。我如何在黃瓜中做到這一點? (我已經寫在測試/單元中。) –
這看起來像個好主意 - 我正在考慮以不同的方式滾動自己。我的reqs在一個txt文件中,每個文件都有一個標籤[REQnnnn]。然後,我將這個標籤添加到每個測試中的「應該」行(我正在使用shoulda)。我最後一步是編寫一個運行單元測試的TestRunner類,抓取輸出並對照需求txt文件進行交叉檢查。感謝您的靈感。 –
我剛剛添加了與shoulda一起使用的代碼示例。你覺得那樣嗎? Requirement#new_by_file將讀取一個包含需求的文本文件。你有特殊的格式嗎?我會推薦一個yaml文件。 – knut
此代碼作爲寶石的預發佈版本可在http://rubygems.org/gems/test4requirements – knut