食べる、寝る、呼吸する単体テスト/ TDD / BDD [終了]
-
06-07-2019 - |
質問
APIとコア機能を作成する際に、ユニットテストを作成します。しかし、私はTDDとBDDを食べ、眠り、呼吸するクールなファンボーイになりたいです。 TDD / BDDを正しい方法で始めるための最良の方法は何ですか?書籍、リソース、フレームワーク、ベストプラクティスはありますか?
私の環境は、Grailsフロントエンドを備えたJavaバックエンドであり、いくつかの外部Webサービスおよびデータベースと統合されています。
解決
開始するのに適した場所は、ブログを読むことです。次に、ブログを書いている人の本を購入します。強くお勧めします:
<!> quot;ボブおじさん<!> quot;マーティンとObject Mentorのメンバー: http://blog.objectmentor.com/
PS Bobs book Clean Codeを取得:
http://www.amazon.com/Clean-Code-Handbook-Software-クラフツマンシップ/ dp / 0132350882
友人のティムオッティンガー(元オブジェクトメンター男) http://agileinaflash.blogspot.com/ http://agileotter.blogspot.com/
Jetbrainsの皆さん: http://www.jbrains.ca/permalink/285
私はこれを拡張する必要があると感じました。他の人は皆、TDDについて自分の意見を伝えたいだけで、ジェダイニンジャになるための探求に役立たないようです。 TDDのマイケルジョーダンはケントベックです。彼は本当にそれについて本を書いた:
http://www.amazon.com/Test-Driven-Development-Kent-ベック/ dp / 0321146530
彼は次のブログにも投稿しています:
http://www.threeriversinstitute.org/blog/?p=29
other <!> quot; famous <!> quot; TDDのサポーターは次のとおりです。
全員がフォローするのに最適な人物です。また、Agile 2010やSoftware Craftsmanship(今年はシカゴで同時に開催された)などのいくつかのカンファレンスへの参加を検討する必要があります
他のヒント
人々が<!> quot;と言うとき、私はそれが好きではありません。練習Xは決して悪くありません。機能しない場合は、正しく機能していません。<!> quot;申し訳ありませんが、それは他の熱心な宗教教義と同じ感触を持っています。買わない。
あなたの時間とお金が許す最善の解決策が目標であるべきだと言う人々に同意します。
TDDに反対する人は、品質を無視していると非難されるべきではありません。 (<!> quot;それで、いつ妻をbeるのをやめたのですか?<!> quot;)事実、ソフトウェアにはバグがあり、それらすべてを排除するコストは利益と比較検討する必要があります。
同じことが製造業にも当てはまります。寸法の公差と表面の仕上げはすべて同じではありません。これは、厳密な公差と鏡面仕上げが保証されない場合があるためです。
はい、クラスを書く前に頻繁にではありませんが、ユニットテストを書きます。設計に対するテストの効果を見てきました。コードカバレッジを測定し、監視します。カバレッジが受け入れられないと判断した場合は、さらにテストを作成します。リファクタリングのための単体テストのセーフティネットの利点を理解しています。私は一人で仕事をしているときでさえ、これらのプラクティスに従います。なぜなら、私は直接その利点を経験したからです。わかりました。
しかし、私は<!> quot;ユニットテストとTDDを食べ、眠り、呼吸することについて私を悩ませ始めたチームメイトに頼みを見ます。<!> quot;
マネージャーは、プロモーションを獲得する唯一の方法は、チームをTDD / BDDに導くことができることだと言います。
これはおそらくあなたがうんざりしているように聞こえると思いますか?あなたのしつこさがあなたのチームの残りを疎外していることを発見しましたか?
この応答は、いくつかの評判ポイントを失う可能性がありますが、言わなければなりませんでした。
より良いアプローチは、自分でそれを実践し、他の人に利益を見せることだと思います。例でリード。口を動かすよりも説得力があります。
Geez、Grailsにはテスト生成が組み込まれています。 Grailsを使用しているチームで作業している場合、さらに多くの販売が必要ですか?
ベストプラクティスIMHO:プロセスであるという理由だけでなく、実用的なことを行います。アプリケーションを記述する目標が何であるかを忘れないでください。ビジネスの世界では、テストを書くことではありません。誤解しないでください、彼らは彼らの場所を持っていますが、それは目標ではないはずです。
TDD / BDDを行っている人を見つけ、それらとプログラムをペアリングします。
メトリックは、私見、ここからそこに到達するための最良の方法です。コードがどの程度カバーされているかを追跡し、コミットごとにコードの複雑さのデルタを保持し、コードの変更を監視するテストランナーを使用して、対応するテストを絶えず再実行します。すべてのツールが正常に機能するように、テストの長さが数行を超えないようにしてください。そして、月に1回、1日休みを取って突然変異テスターでコードを実行することをお勧めします。その日はテストの作成のみに専念する必要があります。あなたがまだ良いTDDをやっていないなら、これらすべてはあなたに痛みをもたらします。痛みから学びましょう。あっという間にあなたは正しいことをするでしょう。
また、テストの目的を見失うことはありません。目的の動作を説明するため。これらは実行可能な仕様です。 (これが Cucumber を好む理由でもあります。PHBにテストを書いてもらうことができます!かなり良いが、近い!)
<!> quot; PS:私のマネージャーは、昇進を得る唯一の方法は、チームをTDD / BDDに連れて行けるかどうかだと言います。<!> quot;
(プロセスであなたを殺さずに)チームに何かをさせる唯一の現実的な方法は、彼らの習慣を変えることが彼らに利益をもたらすことを彼らに明確に示すことです。つまり、コードを記述します。たくさんのコード。大量のコード。そして、仕様を根本的に変更する重要なメールが届いたら、リファクタリングでコードを簡単に変更できることと、テストを実施して準備ができているのでさらに悪いことを伝えます。バーは緑色で、ハックハックハック、レッドバー!!!!、ハックハックハック、グリーンバー、家に帰ります。
Kent Becksのテスト駆動設計に関する本を読んでください。テストから始めて、コードを実行します。テストを実行するビルドサーバーを実行します!あなたはチーム全体でそれを持っている必要はありません-あなた自身のためにそれをして、それが役立つことを彼らに見せてください。
宣べ伝えるだけでネイティブを悩ます:)
私はここ数年TDDをやっていますが、最近、設計と開発を推進するBDDの方法をもっと検討し始めました。私がBDDの使用を開始するのに役立ったリソースは、ダンノースのブログ(BDDの「創始者」)の中で最も重要でした。 BDDの紹介をご覧ください。また、 behaviour-driven.org に「公式」BDD Wikiがあり、読む価値のある良い投稿があります。
BDDを始めたときに本当に難しいと感じた(そしてまだ少し難しいと思う)ことは、BDDに適したシナリオを作成する方法です。スコット・ベルウェアは、BDD(または、彼がそれを造るのを好むコンテキストスペシフィケーション)に熟練した男であり、彼の記事行動主導型開発は、BDDの考え方とユーザーストーリーの定式化を理解するのに大いに役立ちました。
Rob ConeryによるTekPubスクリーンキャスト Specflowを使用した動作主導設計もお勧めします。 C#でBDDを実行するのに非常に適したBDDおよびツール(SpecFlow)の優れた紹介。
TDDリソースについては、すでに多くの推奨事項があります。しかし、私が本当にお勧めできる本をいくつか指摘したいだけです。
- レガシーコードを効果的に使用する、マイケルフェザーズ。レガシーコードに取り組んでいて(私たち全員ではありませんか)、テスト対象にしたい場合は必読です
- ユニットテストの技術:.Netの例を使用 by Roy Osherove ;ユニットテストを初めて使用する場合、これは開始するための 本です
- テスト駆動開発:例による Kent Beck TDDを学習している場合は、ソース自体からTDDを取得してください。良い本-読みやすく、ユーモアと素晴らしい考え。
- クリーンコード:アジャイルソフトウェアクラフツマンシップハンドブック by Robert C. Martin ;ケントベックがTDDの方法を説明している場合、ボブおじさんはなぜを説明しています。
ユニットテストを開始するには、最後にチームにTDDを教えて参加させる方法を読んでください-私の経験では、チーム全体でユニットテストを行うことほど重要ではありません。
適切なビルドプロセスも必要になります-コードをビルドしてテストを実行するビルドサーバーを使用して、TeamCityを使用することをお勧めします(制限なしで無料)。
優れた単体テストを正しく行う方法を学ぶことは難しい部分です-一部は単体テスト(単体テストを続ける限り)で学習し、残りはインターネットの検索から学習できます。
開発の一部があなたに間違っているように見えるので、ユニットテストを書かないとき、あなたはあなたの目標に到達したことを知るでしょう。
アジャイルとは、特定の方法で完全に売り切れていないことを意味します。 TDDの利点が価値のないものに取り組んでいる場合(Swingインターフェースで試行錯誤の編集を行うなど)、TDDを使用しないでください。
TDDはテストに関するものではないことを本当に表明している人は誰もいません。 TDD-ingは、小さな振る舞いを変える変更を行う前に、予想される動作を表現することです。これによりデザインが大幅に改善され、これまで経験したことのない方法で焦点を合わせることができます。将来のリファクタリングと90%のカバレッジを無料で保護するテストを取得できます。
それを学ぶには、他の人が言ったことを要約し、自分のいずれかを追加することをお勧めします:
- ブログにアクセスして上記の本を読む
- TDDに習熟した誰かとペアを組む
- 練習
ボウリングのカタ(運動)を自分で約20回(1回約30分)練習してから、光が見え始めました。まず、ボブおじさんの説明をこちらで分析しました。 codingdojo.orgサイトには、ソリューションとディスカッションを含む多数のカタがあります。それらを試してください!
Nikeからの引用:JUST DO IT。
2番目のアドバイス-他人のインターフェースに頼らないでください。常に、各クラスのレベルで、存在したいインターフェイスに書き込みます-必要に応じて、実際の実装にアダプタを書き込みます。
また、メソッドの戻り値を避け、関数呼び出しではなくメッセージの受け渡しの観点からコードを考えると便利です。
YMMV。
一年前、私はTDDのやり方をほとんど知りませんでした(しかし、本当に(どのようにイライラする))、BDDのことを聞いたことがありませんでした。私はJavaではなく.Net開発環境にいましたが、<!> quot; F5-Run <!> quot;も置き換えました。それが機能/シナリオまたは仕様であるかどうかに応じて、Cucumber(BDD)またはMBUnit(TDD)を実行するマクロ付きのボタン。可能な限りデバッガーはありません。デバッガーを使用する場合は、jarに$ 1(JOKING(sort of))。
このプロセスはとても素晴らしいです。私たちが追加で使用しているフレームワークは、私が出会って恵まれたThe Oracleによるものであり、そこから情報を吸収しています。彼/私たちが使用しているフレームワークはMavenThoughtです。
すべてはBDDで始まります。 BDDは鉄ルビーの上にキュウリをまっすぐに並べたものです。
機能:
シナリオ:....
私がなんとかすると...
私が何かをするとき...
その後、素晴らしいことが起こります...
シナリオ:...
それは単体テストではありませんが、機能、シナリオごとのシナリオ、さらにユニット(テスト)仕様を駆動します。したがって、シナリオを開始し、シナリオで完了する必要がある各ステップでそれを実行しますTDDを駆動します。
また、使用しているTDDは、ある意味でBDDです。SUT(テスト対象システム)が必要とする動作を調べ、仕様ごとに1つの動作が指定されているためです(クラス<!> quot; test <!> quot; file)。
例:
1つの動作の仕様は次のとおりです。テスト対象システムが作成されたとき。
プロパティが変更されたときの別の動作に関する仕様(C#When_blah_happensクラスファイル)がもう1つありますが、それは別のファイルに分離されます。
using MavenThought.Commons.Testing;
using SharpTestsEx;
namespace Price.Displacement.Module.Designer.Tests.Model.Observers
{
/// <summary>
/// Specification when diffuser observer is created
/// </summary>
[ConstructorSpecification]
public class When_diffuser_observer_is_created
: DiffuserObserverSpecification
{
/// <summary>
/// Checks the diffuser injection
/// </summary>
[It]
public void Should_return_the_injected_diffuser()
{
Sut.Diffuser.Should().Be.SameInstanceAs(this.ConcreteDiffuser);
}
}
}
これはおそらくSUTの最も単純な動作です。この場合、作成されるとき、Diffuserプロパティは注入されたディフューザーと同じである必要があるためです。この場合、Diffuserはコア/ドメインオブジェクトであり、インターフェイスのプロパティ通知がないため、モックではなく具象ディフューザーを使用する必要がありました。 95%の時間、本物を注入するのではなく、Dep()などのすべての依存関係を参照します。
多くの場合、複数の[It] Should_do_xyz()があり、場合によっては最大10行のスタブのようなかなりのセットアップがあります。これは、その仕様にGivenThat()またはAndGivenThatAfterCreated()がない非常に単純な例です。
各仕様のセットアップでは、通常、仕様のいくつかのメソッドをオーバーライドするだけです。
GivenThat()== <!> gt;これは、SUTが作成される前に発生します。
CreatSut()== <!> gt;構造マップを使用してsutの自動モック作成を行い、90%の時間でこれをオーバーライドする必要はありませんが、Constructorをコンクリートに注入する場合は、これをオーバーライドする必要があります。
AndGivenThatAfterCreated()= <!> gt;これは、SUTが作成された後に発生します。
WhenIRun()= <!> gt; [ConstructorSpecification]でない限り、これを使用して、SUTに指定する動作である1行のコードを実行します
また、同じSUTの2つ以上の仕様に共通の動作がある場合、基本仕様に移動します。
仕様を実行するためにやらなければならないのは、その名前を強調表示することです。例<!> quot; When_diffuser_observer_is_created <!> quot; F5を押してください。覚えているのは、私にとってはF5がRakeタスクを実行するのは、cucumberの場合はtest:feature [tag]、またはtest:class [SUT]のいずれかだからです。デバッガーを実行するたびにスローされるので、コードは作成されません(ああ、1ドル(冗談)がかかります)。
これは、TDDで動作を指定し、実際に非常に単純なSUTと単純な仕様を指定する非常にクリーンな方法です。カウボーイコーダーになってハードな依存関係などでSUTを作成する場合、TDDを実行してうんざり/あきらめるか、弾丸を噛んで正しいことをしようとするのが痛いでしょう。
実際のSUTは次のとおりです。私たちは少し空想を得て、PostSharpを使用して、Difで変更されたプロパティ通知を追加しますしたがって、Post.Cast <!> lt; <!> gt;です。繰り返しになりますが、それがモックではなくコンクリートを注入した理由です。とにかく、別の仕様で定義されている欠落した動作を見ることができるように、ディフューザーで何かが変更されたときです。
using System.ComponentModel;
using MavenThought.Commons.Events;
using PostSharp;
using Price.Displacement.Core.Products;
using Price.Displacement.Domain;
namespace Price.Displacement.Desktop.Module.Designer.Model.Observers
{
/// <summary>
/// Implementation of current observer for the selected product
/// </summary>
public class DiffuserObserver : AbstractNotifyPropertyChanged, IDiffuserObserver
{
/// <summary>
/// gets the diffuser
/// </summary>
public IDiffuser Diffuser { get; private set; }
/// <summary>
/// Initialize with a diffuser
/// </summary>
/// <param name="diffuser">The diffuser to observe</param>
public void Initialize(IDiffuser diffuser)
{
this.Diffuser = diffuser;
this.NotifyInterface().PropertyChanged += (x, e) => this.OnPropertyChanged(e.PropertyName);
}
/// <summary>
/// Gets the notify interface to use
/// </summary>
/// <returns>The instance of notify property changed interface</returns>
protected INotifyPropertyChanged NotifyInterface()
{
return Post.Cast<Diffuser, INotifyPropertyChanged>((Diffuser)Diffuser);
}
}
}
結論として、このBDD / TDDスタイルの開発はロックされています。 1年かかりましたが、私は生き方としての完全な改宗者です。これを自分で学んだことはなかっただろう。 The Oracle http://orthocoders.com/ からすべてを取り上げました。
赤または青の錠剤、選択はあなた次第です。