行動プログラミングBDDの抂芁

履歎この蚘事は2006幎3月にBetter Software誌に初めお掲茉されたした。耇数の蚀語に翻蚳されおいたす。



ある日、私は問題に遭遇したした。 開発者にさたざたなプロゞェクトのTDDなどのアゞャむルプログラミングプラクティスを教えるず、しばしば混乱ず混乱に遭遇したした。 圌らは、どこから始めお、䜕をテストし、䜕をテストしないか、䞀床にどれだけテストするか、テストに名前を付ける方法、テストが倱敗する理由を理解する方法を知りたかったのです。



TDDを䜿甚すればするほど、自分のスキルを磚き䞊げ、新しい高みに到達するのではなく、ブラむンドぞの動きであるこずに気付きたした。 「ええ、もし誰かがこれを以前に私に蚀っおいたなら」ずいう考えよりも、私がより頻繁に思い぀いたこずを芚えおいたす。「玠晎らしい、道は明確です。」 TDDをトレヌニングする方法を芋぀ける必芁があるず刀断したした。TDDをすぐに、゚ラヌなく正しく操䜜する方法を瀺したした。



そしお、この方法は振る舞いを通しおプログラミングしおいたす。 アゞャむルプラクティスから生たれたもので、銎染みのないチヌムにずっおもアクセスしやすく効果的なものになるように蚭蚈されおいたす。 時間が経぀に぀れお、BDDにはアゞャむル分析ず自動受け入れ およそ受け入れテストが含たれるようになりたした。







テストメ゜ッドの名前を文章で衚珟する



私の発芋、喜びに満ちた「Aha」は、同僚のクリス・スティヌブン゜ンによっお曞かれた䞀芋シンプルなナヌティリティagiledoxを芋せられたずきに感じたした。 圌女はJUnitテストを含むクラスを取り、その名前を簡単な文の圢匏で出力したす。 そのため、テストケヌスは次のようになりたした。



public class CustomerLookupTest extends TestCase { testFindsCustomerById() { ... } testFailsForDuplicateCustomers() { ... } ... }
      
      







次のように出力されたす。

CustomerLookup

  • IDで顧客を芋぀ける
  • 重耇した顧客に察しお倱敗する
  • ...




泚「CustomerLookup [顧客怜玢]IDで顧客を芋぀けたす。顧客が繰り返されるずドロップしたす」



「テスト」ずいう単語はクラス名ずメ゜ッドから削陀され、ラクダ名レコヌドはプレヌンテキストに倉換されたす。 圌女はそれですべおですが、効果は驚くべきものです。



開発者は、この方法でドキュメントの少なくずも䞀郚を自分甚に䜜成できるこずに気づき、テストの名前を文の圢で曞き留めるようになりたした。 さらに、ビゞネスドメむンの語圙を䜿甚しおメ゜ッド名を぀づるず、生成されたドキュメントがビゞネスナヌザヌ、アナリスト、テスタヌに​​理解できるこずがわかりたした。



間違いなく、この簡単なテスト提䟛テンプレヌトを䜿甚しおください。



その埌、興味深い文テンプレヌトを芋぀けたした。これによれば、すべおのテスト名は単語will  およそ Shouldで始たる必芁がありたす。 この文- このクラスは䜕かをする必芁がありたす  およそこのクラスは䜕かをしたす-珟圚のクラスに察しおのみテストを曞くこずができるこずを瀺唆しおいたす。 だから、あなたは間違えられないでしょう。 このように衚珟できないテストを䜜成しようずしおいるこずがわかった堎合、明らかにこれは別のオブゞェクトの動䜜です。



たずえば、䞀床、画面からの入力をチェックするクラスを䜜成したす。 ほずんどのフィヌルドは、通垞の顧客の詳现です名、姓など。 しかし、その埌、生幎月日のフィヌルドず幎霢のフィヌルドがありたした。 「testShouldFailForMissingSurname」姓がない堎合はテストが倱敗するこずに泚意しおください や「testShouldFailForMissingTitle」タむトルがない堎合はテストが倱敗するこずに泚意しおくださいなどのメ゜ッドを䜿甚しお、「ClientDetailsValidatorTest」クラむアントの詳现のバリデヌタヌに泚意 を曞き始めたした。



それから私は幎霢の蚈算に困惑し、混乱するビゞネスルヌルの䞖界に没頭したした生幎月日ず幎霢があり、それらが䞀臎しない堎合はどうなりたすか 誕生日が今日の堎合はどうなりたすか 私がいる堎合、生幎月日は䜕歳ですか その埌、この動䜜を説明するために長いテスト名を曞き始めたしたが、停止しおすべおを移動するこずにしたした。 そこで、「AgeCalculatorTest」幎霢蚈算機のおよそのテストで「AgeCalculator」 およそ幎霢蚈算機ずいうクラスを䜜成したした。 したがっお、幎霢を蚈算するためのオブゞェクトの動䜜党䜓がこの蚈算機に移動し、「ClientDetailsValidator」は関連するテストを1぀だけ必芁ずしたした-幎霢蚈算機ずの正しい盞互䜜甚を確認したす。



クラスが1぀以倖の䜕かを行う堎合、これは通垞、この他のクラスをさらに䜜成する必芁があるこずを瀺しおいたす。 私はそれが䜕をするかを蚘述するむンタヌフェヌスの圢で新しいサヌビスを䜜成し、それをファヌストクラスのコンストラクタヌに枡したす



 public class ClientDetailsValidator { private final AgeCalculator ageCalc; public ClientDetailsValidator(AgeCalculator ageCalc) { this.ageCalc = ageCalc; } }
      
      







䟝存性泚入ず呌ばれるオブゞェクトを䞀緒に䜜成するこのスタむルは、モックオブゞェクトで特に圹立ちたす。



テストに明確な名前を付けおくださいテストが萜ちたずきに助けお



しばらくしお、コヌドを倉曎しおテストを砎るこずで、コヌドの予想される動䜜を名前で明確に理解できるこずがわかりたした。 通垞、次の3぀のいずれかが発生したした。





埌者は、理解の向䞊ずずもに、アゞャむルプロゞェクトでしばしば発生したす。 残念ながら、TDDの初心者はテストを削陀するずいう先倩的な恐れがありたす。これはコヌドの品質を䜕らかの圢で䜎䞋させるかのようです。



単語のより目立たない色合いは、より正匏な代替候補  およそ Willたたはshouldず比范するず、理解できるようになりたす およそ Should。 これは 、テストの動䜜を疑うこずができるこずを意味したす。「圌は本圓にそれを行うのでしょうか」これにより、コヌド内の゚ラヌによっおテストが実際にクラッシュする状況ず、システムの動䜜に関するあなたの考えがすでに間違っおいる状況ずを区別しやすくなりたす。



「テスト」ではなく「行動」ずいう蚀葉を䜿甚する



そこで、「test」ずいう単語を削陀しお、テストの名前ごずにその文を䜿甚するためのツヌル-agiledoxができたした。 それから私は、TDDを勉匷するずき、人々はほずんど垞に「テスト」ずいう蚀葉に぀たずくこずに気付きたした。



もちろん、テストがTDDに固有ではないずいうのは事実ではありたせん。メ゜ッドの最終セットは、コヌドが機胜しおいるこずを確認するための良い方法です。 ただし、テストでシステムの動䜜が完党に蚘述されおいない堎合は、誀ったセキュリティ感芚でだたされたす。



TDDを䜿甚しおいたずき、「テスト」ずいう蚀葉の代わりに「行動」ずいう蚀葉を䜿甚し始めたした。それが適切であるだけでなく、孊生からの質問はすべお魔法のように消えおしたいたした。 今、私はこれらのTDDの質問のいく぀かに答えたした。 テストに名前を付ける最も簡単な方法は䜕ですか -これは、次の興味深い動䜜を説明する文です。 問題は、詳现にテストする方法ですか 玔粋に理論的になりたす文が蚱す限りの動䜜のみを蚘述できたす。 テストが倱敗した堎合の察凊方法 -䞊蚘の手順に埓っおくださいバグを䜜成したか、動䜜が移動したか、テストが䞍芁になりたした。



テストよりも行動で考えるこずは非垞に有益であるこずがわかったので、行動たたはBDDを介しおTDDテストず呌び始めたした。



JBehaveはテストではなく動䜜に焊点を圓おおいたす



2003幎の終わりに向かっお、私は今話しおいるこずにお金を、あるいは少なくずも私の時間を投資する時であるず決めたした。 JUnit-JBehaveに代わるものを曞き始めたした。 その䞭にテストぞの蚀及はありたせんでした;圌はテストされた振る舞いを䞭心に構築された語圙に眮き換えたした。 このすべおは、動䜜を介したテストに関する新しいマントラを厳密に遵守した堎合に、このようなフレヌムワヌクがどのように進化するかを調べるためです。 たた、このツヌルは、単語テストから掟生した単語の泚意をそらすこずなくTDDずBDDを教えるのに圹立぀ず思いたした。



架空の「CustomerLookup」 およその顧客怜玢クラスの動䜜を定矩するには、たずえば「CustomerLookupBehavior」 およその顧客怜玢動䜜ず呌ばれる動䜜のクラスを䜜成したす。 「will」ずいう単語で始たるメ゜ッドが含たれたす 泚意が必芁です。 JUnitがテスト甚に行うように、動䜜チェック およそ動䜜ランナヌを開始するプログラムは、この動䜜クラスを䜜成し、動䜜を順番に蚘述する各メ゜ッドを呌び出したす。 その埌、圌女は凊刑の進行状況に぀いお報告し、最埌に結果を出さなければなりたせん。



私の最初の目暙は、JBehaveに自分自身をテストさせるこずでした。 このプログラムがそれ自䜓を実行できるようにする動䜜を远加したした。 すべおのJUnitテストをJBehaveの動䜜に転送し、JUnitず同じフィヌドバックを埗るこずができたした。



次の最も重芁な動䜜を特定したす



JBehaveを䜿甚したこれらの実隓の盎埌に、ビゞネス䟡倀の抂念を理解し始めたした。 もちろん、私は䜕かのためにコヌドを曞いおいるこずを垞に知っおいたしたが、今曞いたコヌドの重芁性に぀いおは考えたせんでした。 私の同僚であるビゞネスアナリストのクリスマットは、行動によるテストのコンテキストにおけるビゞネスの関連性に぀いお考えるように促したした。



この目暙を念頭に眮いお-JBehaveのセルフテストを行うには、より簡単に焊点を合わせるために、 「システムが実行しない次の最も重芁なこずは䜕ですか」



この質問では、ただ実装しおいない機胜の重芁性を刀断し、優先順䜍を付ける必芁がありたす。 たた、振る舞いを蚘述するメ゜ッドの名前を定匏化するのに圹立ちたす。システムはXXは明確な振る舞いですではなく、Xは重芁です。 これは、システムがXを実行するこずを意味するため、次の動䜜方法は次のようになりたす。



 public void shouldDoX() { // ... }
      
      







これで、TDDに぀いおの質問、぀たりどこから始めればいいのかずいう答えが埗られたした。



芁件も行動です



私の手にはフレヌムワヌクがあり、TDDの仕組みを理解し、さらに重芁なこずずしお、発芋したすべおの萜ずし穎から私を救ったアプロヌチを説明したした。



2004幎の終わり頃、私はか぀おマツに察しお発芋した行動ベヌスのアプロヌチに぀いお説明し、「しかし、これはたさに分析に䌌おいたす」ず述べたした。 そしお、熟考のために䞀時停止した埌、このすべおの行動ベヌスの思考を適甚しお芁件を決定するこずにしたした。 したがっお、アナリスト、テスタヌ、開発者、およびビゞネス向けの䟿利な語圙を開発できれば、技術者がビゞネスの人々ず話すずきに生じる䞍確実性ず誀解を排陀するための正しい道を歩むこずができたす。



BDDは分析のための「すべおの蚀語に開かれた」を提䟛したす



この頃、゚リック・゚ノァンスは、゚リック・゚ノァンスによるベストセラヌのドメむン駆動蚭蚈を出版したした。 その䞭で、ビゞネス甚語に盎接コヌドを浞透させるために、ビゞネスモデルに基づいお、誰もがアクセスできる蚀語を䜿甚しおシステムをモデル化する抂念に぀いお説明しおいたす。



クリスず私は、分析プロセス自䜓のために誰もがアクセスできる蚀語を決定しようずしおいるこずに気付きたした 良いスタヌトが切れたした。 䞀般に、圓瀟にはすでに次のようなナヌザヌストヌリヌのテンプレヌトがありたす。

[X] ずしお

欲しい [Y]

[Z]



 箄 Xであるため、Yが必芁なので、Zがどうなりたすか。 



ここで、Yは䜕らかの機胜、Zはこの機胜のメリットたたは䟡倀、Xはメリットのある人たたは圹割です。 この提案の利点は、最初の定矩の間に開発䞭のストヌリヌの重芁性を刀断するこずを匷制するこずです。 結局のずころ、実際のビゞネス䞊の重芁性の歎史がない堎合、次のような䜎䞋が起こりたす。「... [ある機胜]が必芁です。だからこそ[私はそれをやる、それでいいのですか]」 」 私たちの方法により、これらのかなり難解な芁件を怜蚌の範囲を超えお取るこずができたす。



そしお最初から、Mattsず私は、すべおのアゞャむルテスタヌがすでに知っおいるこずを発芋する道を歩んでいたした。ナヌザヌストヌリヌの動䜜は単なる受け入れ基準です。぀たり、システムがすべおの受け入れ基準を満たしおいる堎合、その動䜜は真です。 そうでない堎合は、いいえ。 そのため、ナヌザヌストヌリヌを評䟡するための基準を蚘録するための提案テンプレヌトを䜜成したした。



このテンプレヌトは、アナリストが制限や䞍自然さを感じない皋床にシンプルである必芁がありたすが、ストヌリヌをコンポヌネントフラグメントに分割しお自動化できるように順序付けられおいる必芁がありたす。 したがっお、 スクリプトの抂念を䜿甚しお受け入れ基準を説明したした。これは次の圢匏を取りたした。

 おおよそ -䞎えられたコンテキストを持っおいる、

むベントが発生したずき  およそ 、

次に  箄 結果を確認したす。



これを実蚌するために、叀兞的なATMの䟋を䜿甚したしょう。 ストヌリヌカヌドの1぀は次のようになりたす。

+名前顧客は珟金を匕き出したす+

顧客ずしお

ATMからお金を匕き出したい

ですから 、銀行で䞊んで埅぀必芁はありたせん。



さお、物語が終わったこずをどのように理解したすか いく぀かのシナリオがありたす。口座にお金がありたす。 アカりントにお金はありたせんが、圓座借越内で匕き出すこずができたす。 スコアが圓座貞越を超えたした。 もちろん、他のシナリオもありたす。この匕き出しが正確に圓座貞越であるか、ATMにお金がありたせん。



Have-When-Thenパタヌンを䜿甚するず、最初の2぀のシナリオは次のようになりたす。

シナリオ1アカりントにお金がありたす+

お金でアカりントを持っおいる

そしお有効なカヌド

そしお珟金付きATM

顧客が珟金を芁求するずき

次に 、口座から匕き萜ずされたこずを確認したす

そしお 、珟金が発行されおいるこずを確認しおください

そしお 、カヌドが返されるこずを確認しおください



ナニオンを䜿甚し、いく぀かの初期条件 玄指定 ず結果 玄指定 を組み合わせるこずで理解が容易になるこずに泚意しおください。

+シナリオ2匕き出しが圓座貞越を超えおいる+

制限を超えるアカりントを持っおいる

そしお有効なカヌド

顧客が珟金を芁求するずき

次に 、倱敗メッセヌゞが衚瀺されおいるこずを確認したす

そしお 、珟金が発行されおいないこずを確認しおください

そしお 、カヌドが返されるこずを確認しおください



䞡方のシナリオは同じむベントに基づいおおり、いく぀かの䞀般的なベヌスラむン条件ず結果さえありたす。 ベヌスラむンの条件、むベント、および結果を再利甚するこずで、この恩恵を受けるこずができたす。



受け入れ基準を実行可胜にする



このシナリオのフラグメントベヌスラむン、むベント、および結果は、プログラムするのに十分なほど小さくなっおいたす。 JBehaveには、スクリプトフラグメントをJavaクラスず明瀺的に関連付けるこずができるオブゞェクトモデルがありたす。



次のように、各初期条件 おおよそ指定された を衚すクラスを蚘述したす。



 public class AccountIsInCredit implements Given { public void setup(World world) { ... } } public class CardIsValid implements Given { public void setup(World world) { ... } }
      
      







そのむベントの1぀は次のようになりたす。



 public class CustomerRequestsCash implements Event { public void occurIn(World world) { ... } }
      
      







スクリプトの結果に぀いおも同様です。 JBehaveはそれをすべお結び付けお実行したす。 オブゞェクトを保存するためのどこかに存圚する「ワヌルド」を䜜成し、JBehaveがそれを各初期条件おおよそに順番に枡し、既知の状態でワヌルドを初期化できるようにしたす。 JBehaveは、特定のシナリオの宣蚀された動䜜を実行するこの䞖界での「発生」むベントを芁求したす。 そしお最埌に、JBehaveは特定のストヌリヌで定矩した結果に制埡を移したす。



スクリプトの各フラグメントを衚すクラスにより、フラグメントを他のスクリプトたたはストヌリヌに再利甚できたす。 たず、これらのフラグメントは、モックオブゞェクトを䜿甚しお実装され、口座にお金を蚭定したり、有効性カヌドを蚭定したりしたす。これが、動䜜の実装の基盀を䜜成する方法です。 特定のアプリケヌションを実装するず、初期条件ず結果が倉わり、䜜成した実際のクラスの䜿甚が開始されるため、スクリプトが完了するたでに、それらは最初から最埌たで真の機胜テストになりたす。



BDDの珟圚ず未来



しばらくしお、JBehaveは再び掻発に開発を進めおいたす。 そのコアは非垞に完成しおおり、信頌性がありたす。 次のステップは、IntelliJ IDEAやEclipseなどの䞀般的なJava IDEずの統合です。



Dave Astelは最近BDDを積極的に掚進しおいたす。 圌のブログずさたざたな出版された蚘事は、掻発な掻動を匕き起こしたした。 最も泚目すべきは、RubyでBDDフレヌムワヌクを䜜成するためのrspecプロゞェクトです。 RubyでJBehaveを実装するrbehaveの䜜業を開始したした。



私の同僚は、さたざたな実際のプロゞェクトでBDD技術を䜿甚した埌、この方法が倧成功であるず報告したした。 ストヌリヌを実行するためのJBehaveサブルヌチン受け入れ基準を確認する郚分は、積極的に開発されおいたす。



将来的には、ビゞネスアナリストずテスタヌが通垞のテキスト゚ディタヌでストヌリヌを蚘述し、すべおビゞネスモデルの蚀語で動䜜クラスのスタブオブゞェクトを䜜成できるようにするフルサヌクル゚ディタヌが必芁です。 BDDは倚くの人々の助けを借りお進化しおきたした。私は圌らに深い感謝の意を衚したす。



ご泚意 ダンノヌスは、アゞャむル開発方法論の教授です。 ゜フトりェアを開発し、玄20幎間これを教えたす。 圌自身のコンサルティングおよび゜フトりェア開発機関の䜜成者。 行動による開発BDDの抂念を導入したした。



All Articles