行動駆動開発の3つは,テスト駆動開発から

5634 ワード

TDDの由来


テストドライバ開発(Test Driven Development,TDD)の考え方は限界プログラミング(Extreme Programming,XP)から来ている.XPは1999年に始まり、テストを先取りすることをコンセプトとしています.ツールのサポートが不足しているため、XPは最初は暖かくなく、Junitが登場するまで、XPは広く普及した.噂によると、JunitはKent BeckとEric Gammaの2人の大牛が飛行機の中で退屈になって遊びを書いて作ったという.03年になると、XPのテストはTDDに優先的に進化しました.
  • コードを書く前に、ユニットテスト
  • を書きます.
  • ユニットテストが実行可能で失敗した後、コード
  • を記述する.
  • コードが前のテストに合格するまで、符号化は
  • に完了する.
  • 試験の合格を維持する場合、再構成コード
  • ruby言語でのTDDの例:


    x,yで座標を初期化し、異常値をエラーする点を実現したい.テスト:
    class TC_Point < Test::Unit::TestCase 
      @@valid_points = [[1, 2], [0, 0]] 
      @@invalid_points = [[nil, 3], [3, nil], [1, -2], [-1, 2], [1.5, 2], [35, 5.66778]] 
      def test_valid_point
        @@valid_points.each do |point| 
          p = Point.new(point[0], point[1]) 
          assert(p.row == point[0])
          assert(p.column == point[1]) 
        end 
      end 
      def test_invalid_point 
        @@invalid_points.each do |point| 
          assert_raise RuntimeError do 
            p = Point.new(point[0], point[1]) 
          end
       end
      end
    end  

    このコードは実行後、Pointというクラスの書き込みを実現することができます.
    class Point 
      attr_reader :row, :column 
      def initialize(row, column) 
        if !row.is_a?(Integer) or !column.is_a?(Integer) 
          raise "row #{row} and column #{column} must be integer" 
        end 
        if row<0 or column<0 
          raise "row #{row} and column #{column} must be >= 0" 
        end 
        @row = row 
        @column = column 
      end 
    end
    

      
    テストを実行します.テストに合格する.その後、Pointというコードを再構築します.再構成,すなわち,既存のコード挙動を一定に保ち,コードの可読性,独立性などを改善する.改善されたPointクラスがテストに合格できる限り、すなわち、再構築は従来の機能に影響を及ぼさない.

    TDDの進化


    JUnitの後、続々と、様々な言語にも独自のUnit Test Frameworkがあり、一時TDDツールは雨後のタケノコのように、地面を抜いた.しかし、風の多くの人たちと道具を熟練している間に、より敏捷な先輩たちを求めて前進し続けた.TDDの次のステップはどこですか?より良い分離コード(Working Effectively with legacy code)、より良いテストフレームワーク(Xunit Test Patterns)、これらはすべて花を添えています.しかし、雪の中で炭を送る道はどこにあるのだろうか.先輩たちは頭を絞って、二つの道を考え出した.
  • の既存のTDDのT、すなわちテスト例はまだ最下位で、集積層、システム層、ユーザー層に着いて、このように歩いて、通じません.だから先輩たちはもう一つの道を考え出した.検収性テスト駆動開発(Automate Acceptance Test Driven Development,AATDD)で、この中で有名なツールはFitnesseだ.
  • の既存のテスト例は、やはり分かりにくいですが、コードなので、自然言語に近づけたほうがいいです.

  • BDDの由来


    行動駆動開発(Behavior Driven development,BDD)は,第2のアイデアから進化したものである.上記の例を続けて、私のテストコードをもっと分かりやすくしたいと思っています.私はこのような方法を使用することができます.
    def test_valid_point -> 
    def test_point_should_support_set_integer_to_x_and_y 
    
    def test_invalid_point -> 
    def test_point_should_raise_error_when_set_none_integer_to_x_and_y
    

      
    RubyのBDDのツールRspecを使用する場合、テストコードは自然言語で次のように記述できます.
    describe "A new point" do 
      it "should raise exception when set none integer as x or y" do 
        none_integers = [[nil, 3], [3, nil], [1, -2], [-2, 1], [1.5, 2], [2, 1.5]] 
        none_integers.each do |ni| 
          Point.new(ni[0], ni[1]).should raise_error() 
        end 
      end 
      it "should accept when set integer as x and y" do 
        integers = [[1, 2], [0, 0]] 
        integers.each do |i| 
          p = Point.new(i[0], i[1]) 
          p.x.should == i[0] 
          p.y.should == i[1] 
        end 
      end 
    end

    Rspec後、他のプログラミング言語も次々と真似され、一連のSpecツールは雨後のタケノコのようだ.しかし、より敏捷な先輩たちを追うには、足を止めなかった.Rspecは依然としてユニットテスト層、すなわちdescribe/it/doの中にとどまっているからだ.コードだ.スペックに自然言語を導入するため、先輩たちはその上でCucumberを開発した.
    CucumberはもともとRspecの新しい表現として開発されたが,その文法Given/When/thenの強さにより,独創的である.必要性、システム設計、モジュール設計など、すべての動作を記述できます.すなわち、自動検収性テスト、自動化システムテスト、自動化統合テストのスクリプトとして使用できます.これでJunitがXP/TDDに春をもたらしたようにCucumberが来て、BDDの春も来ました.Cucumberを使用すると、上記の例は、
    Scenario: valid pairs 
      Given a pair of integers "<x>" and "<y>" 
      When I initialize a Point with it 
      Then a point should be generated 
    	
      Examples: 
    	|x | y | 
    	|3 | 1| 
    	|0 | 0| 
    
    Scenario: invalid pairs 
      Given a pair of none integers "<x>" and "<y>" 
      When I initialize a Point with it 
      Then a point should raise exception 
    	
      Examples: 
    	|x |y |
    	|nil |3 |
    	|3 |nil |
    	|0.1|1 |
    	|1 |0.1|

    Cucumberができてから、BDDの定義はやっと矢を放つことができます.
  • TDDをベースに、自然言語へのサポートを強化した
  • は外部から開発することができて、つまり先に需要-ユーザーの行為を書いて、更にシステムの行為を書いて、更にモジュールの行為を書いて、それからコードを書いて、このコードはPassユニットのテスト、モジュールのテスト、システムのテスト、ユーザーのテストに行くべきで、このようにして、1つの交付できるソフトウェアは発生して、
  • 高度自動化、外から中まで自動化、
  • 多くの参加者が協力して仕事をして、自然言語は取引先、テスト人員、開発者が
  • に参加することができます.

    TDDか、BDDか


    TDDまたはBDDを採用する前に、まず要因を考慮してください.
  • TDDにおいて、開発者の意思
  • 私のグループの中でTDDは3年も話していましたが、今私の知っている限りでは、TDDの2冊の名作を見て、ユニットテストを書き続けている人は1人しかいません(私のグループの開発者は15人です).TDDを行う場合、書き込みユニットのテストとコードは一緒に行われ、この過程でテスト担当者が参加できる機会は多くありません.では、テスト担当者が普及したTDDは、テスト担当者がでたらめを言って、開発者が目を白黒させるようになった.だから、テストスタッフの観点からTDDを普及させるには、ボスが強力にサポートしていない限り、実行できません(開発はTDDだと言われていますが、テストしなければなりません).もちろん、あなたの開発者が積極的に勉強しているなら、別です.
  • テスターのコードスキル
  • テストスタッフがBDDを普及すれば、プロセスは順調になります.需要、システム行為、モジュール行為を作成する過程で、開発者はテスト者と一緒に仕事をすることができ、開発者自身の一方的な努力ではなく、協同作業の時間を高めることができるからだ.しかし、動作ドキュメントが生成されると、ドキュメントを実行可能なプログラムにするには、後でコードが必要になります.これは、テスト担当者にコードを作成する能力の要求です.手動でテストしているのに、コードを書いたことがないテスト担当者は、投入が大きくなり、進展が遅くなる可能性があります.
  • プロジェクトで使用する技術
  • TDDを選択すると、開発用の言語はもちろん、ユニットテストは何を使うのか、ほとんど選択されていません.BDDは少し柔軟で、製品インタフェースがBDDツールに呼び出されさえすれば、このツールを使用することができます.私のグループ内でJava開発を使用すると、プログラムはWebインタフェース、データベースインタフェース、コマンドラインインタフェースを提供し、Cucumber/Rubyを使用しても簡単に呼び出すことができるので、JavaのBDDツールを必ずしも使用する必要はありません.