2011-08-05 34 views
2

我在寫一些ruby(不是Rails),並且用shoulda來測試/測試單元。有沒有好的ruby測試追蹤解決方案?

是否有任何寶石可以讓我實現從測試到設計/需求的可追溯性?

即:我想與他們測試的要求,名稱標記我的測試,然後生成的未測試的要求,報告或有失敗的測試等

希望這不是爲紅寶石太enterprisey 。

謝謝!

回答

1

更新:該解決方案可作爲寶石:http://rubygems.org/gems/test4requirements

是否有任何寶石是是否允許我實現從我的 測試回溯到設計/要求的可追溯性?

我不知道任何寶石,但你的需要是一個小實驗的靈感,它是如何解決的。

  • 你必須與RequirementList.new(1,2,3,4)
  • 這種要求可以用要求在一個TestCase
  • 每個測試可分配分配定義您的要求在測試後要求
  • 的要求會導致你(全成)
這要求測試的概述

而現在的例子:

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 
+0

這看起來像個好主意 - 我正在考慮以不同的方式滾動自己。我的reqs在一個txt文件中,每個文件都有一個標籤[REQnnnn]。然後,我將這個標籤添加到每個測試中的「應該」行(我正在使用shoulda)。我最後一步是編寫一個運行單元測試的TestRunner類,抓取輸出並對照需求txt文件進行交叉檢查。感謝您的靈感。 –

+0

我剛剛添加了與shoulda一起使用的代碼示例。你覺得那樣嗎? Requirement#new_by_file將讀取一個包含需求的文本文件。你有特殊的格式嗎?我會推薦一個yaml文件。 – knut

+0

此代碼作爲寶石的預發佈版本可在http://rubygems.org/gems/test4requirements – knut

1

隨着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 
+0

這看起來很漂亮,但我不知道它會爲我工作。例如,我的一個測試檢查一個方法的返回值,該方法是一個包含150個元素的3D數組。我如何在黃瓜中做到這一點? (我已經寫在測試/單元中。) –

相關問題