2008-09-22 61 views
2

以下是我有:如何刪除應用程序測試中的重複?

context "Create ingredient from string" do 
     context "1 cups butter" do 

     setup do 
      @ingredient = Ingredient.create(:ingredient_string => "1 cups butter") 
     end 

     should "return unit" do 
      assert_equal @ingredient.unit, 'cups' 
     end 

     should "return amount" do 
      assert_equal @ingredient.amount, 1.0 
     end 

     should "return name" do 
      assert_equal @ingredient.name, 'butter' 
     end 
     end 
     context "1 (18.25 ounce) package devil's food cake mix with pudding" do 

     setup do 
      @ingredient = Ingredient.create(:ingredient_string => "1 (18.25 ounce) package devil's food cake mix with pudding") 
     end 

     should "return unit" do 
      assert_equal @ingredient.unit, '(18.25 ounce) package' 
     end 

     should "return amount" do 
      assert_equal @ingredient.amount, 1.0 
     end 

     should "return name" do 
      assert_equal @ingredient.name, 'devil\'s food cake mix with pudding' 
     end 
     end 
    end 

很明顯,有很多重複出現。關於如何刪除它的任何想法,只要至少在上下文和字符串?

回答

4

這是您的具體問題的解決方案。這個想法是創建一個類方法(像Shoulda的上下文,設置和應該)。

封裝在一個類的方法重複接受所有不同的部分爲這樣的論點:

def self.should_get_unit_amount_and_name_from_string(unit, amount, name, string_to_analyze) 
    context string_to_analyze do 
    setup do 
     @ingredient = Ingredient.create(:ingredient_string => string_to_analyze) 
    end 

    should "return unit" do 
     assert_equal @ingredient.unit, unit 
    end 

    should "return amount" do 
     assert_equal @ingredient.amount, amount 
    end 

    should "return name" do 
     assert_equal @ingredient.name, name 
    end 
    end 
end 

現在你可以調用一個襯墊(5派這裏可讀性;-)

所有這些封裝測試
context "Create ingredient from string" do 
    should_get_unit_amount_and_name_from_string(
    'cups',     
    1.0, 
    'butter', 
    "1 cups butter") 
    should_get_unit_amount_and_name_from_string(
    '(18.25 ounce) package', 
    1.0, 
    'devil\'s food cake mix with pudding', 
    "1 (18.25 ounce) package devil's food cake mix with pudding") 
end 

在某些情況下,您可能想要接受可用作Shoulda設置的塊。

+0

使用[Shoulda] [1]的最新版本,您可以將自己的宏放在[RAILS_ROOT] \ test \ shoulda_macros中,Shoulda會自動將其選中。 [1]:http://giantrobots.thoughtbot.com/2008/9/30/shoulda-2-0 – 2008-10-23 11:48:49

0

個人爲這個測試,我不會使用Shoulda。在測試中

class DefineMethodTest < Test::Unit::TestCase 
    [{:string => '1 cups butter', :unit => 'cups', :amount => 1.0, :name => 'butter'},{:string => '1 (18.25 ounce) package devil's food cake mix with pudding', :unit => '(18.25 ounce) package', :unit => 1.0, :name => "devil's food cake mix with pudding"}].each do |t| 
     define_method "test_create_ingredient_from_string_#{t[:string].downcase.gsub(/[^a-z0-9]+/, '_')}" do 
      @ingredient = Ingredient.create(:ingredient_string => t[:string]) 

      assert_equal @ingredient.unit, t[:unit], "Should return unit #{t[:unit]}" 
      assert_equal @ingredient.amount, t[:amount], "Should return amount #{t[:amount]}" 
      assert_equal @ingredient.name, t[:name], "Should return name #{t[:name]}" 
     end 
    end 
end 
+0

雖然這是一個動態方法的流暢使用,但我發現這個測試的可讀性遠低於Shoulda實現。 – 2008-10-23 11:50:33

2

複製並非一定是壞事(TM)

我建議你閱讀從周杰倫現場

下面的文章: 您可以輕鬆地通過使用動態方法創建如下消除重複

http://blog.jayfields.com/2007/06/testing-one-assertion-per-test.html

http://blog.jayfields.com/2008/05/testing-duplicate-code-in-your-tests.html

他們做出convinvin g的情況下,在測試中的代碼重複和每個測試保持一個斷言。

+0

是的,你的主要目標是測試(而不是測試你的代碼)應該是可讀性的。必須維護您的代碼的開發人員會爲此感謝您。 – 2008-10-23 11:52:42

1

測試/規格不是生產代碼,因此乾燥不是重點。

原理是規格應該清晰可讀,即使這意味着跨測試有文本重複。

不要太擔心規格變幹。干涉測試過於強調會讓事情變得更加困難,因爲你不得不跳到事物的定義來理解發生的事情。