web-dev-qa-db-ja.com

自社で自動テストが失敗し続けるのはなぜですか?

私の会社では、開発者の自動テストを何度か紹介しようとしました。私たちのQAチームはUIテストを自動化するためにSeleniumを使用していますが、私は常にユニットテストと統合テストを導入したいと思っていました。以前は、私たちがそれを試すたびに、最初の1〜2か月はみんな興奮していました。その後、数か月後、人々はそれをやめるだけです。

いくつかの観察と質問:

  1. 自動テストは実際に機能しますか? 他の会社で働いていた私の同僚のほとんどは、自動テスト戦略を実装しようとして失敗しました。私は実際にそれを使用し、それについて話すだけではない現実のソフトウェア会社を見たことはありません。多くの開発者は、自動テストを理論的には優れているが実際には機能しないものと見なしています。私たちのビジネスチームは、30%の余分な時間のコストでさえ、開発者がそれを行うことを望んでいます(少なくとも彼らはそう言っています)。しかし、開発者は懐疑的です。

  2. 自動化されたテストを適切に行う方法を実際に知っている人はいません。 はい、インターネットで単体テストの例をすべて読みましたが、大きなプロジェクトでそれらを使用することは、まったく別のことです。主な犯人は、データベースまたは重要なものをモック/スタブすることです。実際のテストを書くよりも、あざけることに多くの時間を費やすことになります。次に、コードの記述よりもテストの記述に時間がかかるようになったとき、それはあきらめたときです。

  3. 何か良いものはありますか  なデータ中心のWebアプリケーションで使用される単体テスト/システム統合テストのどれですか?オープンソースプロジェクトはありますか?私たちのアプリケーションはデータ中心ですが、ドメインロジックもたくさんあります。ある時点でリポジトリアプローチを試したところ、ユニットテストにはかなり良いとわかりましたが、データアクセスを簡単に最適化できるという代償があり、さらに複雑なレイヤーが追加されました。

20名の経験豊富な開発者が取り組んでいる大きなプロジェクトがあります。これは、単体テスト/統合テストを導入するための理想的な環境のようです。

なぜうまくいかないのですか?どうやってそれをあなたの会社で機能させたのですか?

182
Mag20

単体テストを行う際の最も難しい部分は、最初に/早い段階でテストを作成するための規律を得ることです。ほとんどの開発者はコードに飛び込むことに慣れています。また、コードのテストを作成する方法を理解しようとしているため、開発プロセスが早い段階で遅くなります。ただし、テストが上手くなると、これはスピードアップします。また、テストを記述しているため、コードの初期品質は高くなっています。

始めるときは、テストを書くだけにしてください。最初は物事をモック/スタブすることについてそれほど心配する必要はありません。テストは単純にしてください。テストはコードであり、リファクタリングできる/すべきです。何かテストするのが難しい場合はそれらの線に沿っていますが、それもデザインである可能性があります。 TDDは、ほとんどのデザインパターン(私の経験では、特にFactoryパターン)を使用することを目指しています。

テストがある程度の可視性を備えていることを確認してください。それらをリリースプロセスに統合し、コードレビュー中にそれらについて尋ねます。見つかったバグはテストを受ける必要があります。これらは、TDDが優れている点です。

ここに私が便利だと思ったいくつかのリソースがあります:

http://misko.hevery.com/attachments/Guide-Writing%20Testable%20Code.pdf

http://www.agitar.com/downloads/TheWayOfTestivus.pdf

編集:

テストを作成するときに留意すべき1つのこと。コードの実装については何も指定せず、動作のみを指定します。コードを書くときは、常にそれをテストします。デバッグステートメントなどで実行しようとしています。テストを書くことはこれを形式化し、あなたが持っているテストの記録を提供します。これにより、開発プロセスの途中で覚えていたテストケースを誤ってスキップすることなく、機能を自信を持ってチェックできます。

90
Schleis

多くの点で私はあなたのチームに同意します。

  1. ほとんどの単体テストは価値に疑問があります。テストの大部分は単純すぎるようです。

  2. 優れたテスト可能なコードを作成することは、実際に機能するコードよりもはるかに困難です。コード/デザインの品質そのものではなく、単に機能することを信じている開発者コミュニティの大部分がいます。そして、品質コードが何であるかさえ知らない、さらに大きな割合。

  3. 単体テストコードの記述には、実際のコード自体よりもはるかに長い時間がかかる場合があります。

  4. より複雑なコードを適切にテストする方法(つまり、実際に徹底的にテストしたいもの)を理解することは、多くの開発者の能力を超えています。

  5. 単体テストの維持には時間がかかりすぎます。小さな変更は大きな波及効果をもたらす可能性があります。自動化された単体テストの主な目的は、変更によってコードが破損していないかどうかを確認することです。ただし、99%の確率で壊れるのはテストであり、コードではありません。

上記のすべての問題があるにもかかわらず、コードを変更して、何かが予期せず壊れることがないというある程度の自信を持ってテストを自動化する方法よりも優れた方法はありません。

上記のいくつかは、単体テストの教科書を読まないことである程度軽減できます。

多くのタイプの設計/アプリケーションは、モジュール/パッケージレベルでテストを自動化することにより、より適切にテストされます。私の経験では、ほとんどのコーディングエラーは、クラスのコードが誤ってコーディングされたためではなく、コーダーがクラスが他のクラスでどのように機能するかを理解していなかったことが原因です。この種のテストでは、多額の投資が見られます。しかし、繰り返しになりますが、これらのテストは、ユニット(クラスレベル)テストよりも書くのが困難です。

結局のところ、開発者がプロ​​セスを信じるかどうかにかかっています。もしそうなら、彼らは良いユニットテストを書き、エラーを早期に発見し、支持者になるでしょう。そうでない場合、それらの単体テストは概して役に立たず、エラーも検出されず、単体テストが役に立たないという彼らの理論は(彼らの心の中で)証明されます。

結論として、私は自分で2か月以上にわたって完全な自動単体テストアプローチが機能するのを見たことがありませんでしたが、自動単体テストのアイデアは、実際にテストが必要なものを選択しているにもかかわらず、まだ続きます。このアプローチは批評家がはるかに少なくなる傾向があり、ほんの数人ではなくすべての開発者に受け入れられています。

77
Dunk

主な原因は、データベースまたは単純ではないもののモック/スタブです。

そしてあなたの問題があります。

ユニットテストを環境に統合する方法については、誰もが良い点を指摘しています。どのように人々にそれを十分に強制して、彼らが実際的な価値とそれが「固執する」かを見るように強制する方法しかし、それが非常に苦痛であり、および/または利益をもたらさない場合、それは固執しません。

データベースのスタブは非常に簡単です。インターフェースが結果を提供するために何らかのDBバッキングに行く代わりに、単純なハードコーディングされたオブジェクトを配置します。それができない場合は、設計/アーキテクチャに問題があります。あなたのコードはそれがデータベースに行くことを想定しているか、それを変えるためのインターフェースの抽象化を持っていません。

これは単にテストや品質の問題ではありません。 DBプロバイダーを変更したり、代わりにクラウドに移動したり、接続されていないモバイルアプリをサポートしたりするとすぐに、デザインは失敗します。最も単純な柔軟性のケースをサポートできない場合、ビジネスが必然的に必要とするより複雑なものをサポートすることはできません。

34
Telastyn

小さく、自動化が簡単で、価値の高いものから始める必要があります。甘い、ぶら下がっている果物をいくつかおろすと、そのプロセスを売ることができます。深夜や週末の電話でどのように救われたかを示します。その後、そこから拡張できます。

自動テストをうまく行うには、リソースと伝道者であり、より高いレベルの経営陣から賛同してくれる人が必要です。

自動テスト開発を他のアジャイルプロジェクトと同様に扱います。完成したテストを定期的に作成します。

コメントからの追加:それは管理上の問題です。ドキュメント化される前に、コードは「完了」と見なされますか?チェックインする前ですか?単体テストを含めて合格する前に?

これにどのように取り組むかは、実際にはあなたの役割に依存します。あなたは仲間ですか?その場合は、コードを再利用して維持しやすくする方法を他の人に示してください。あなたはリードですか?コードの問題が最も多いプログラマを選び、それらの問題を回避するためのテストの追加を支援します。あなたは上司ですか? 「ユニットテストが開始されて合格するまでコードは実行されないことを、標準として設定します。

21
Skip Huffman

これらの基本ルールに従ってください。テスト:

  1. 定期的に実行する必要があります!すべてのビルドで、すべてのチェックインの前後に、または毎朝テストを実行できます。自動トリガーは手動でトリガーするよりも非常に望ましいです。理論的には、チームの全員がテストを確実に実行する責任を負うことができるので、自動化されていない場合、おそらく十分な頻度で発生しません!また、テストを頻繁に実行しないと、どちらもバグを発見するのが遅すぎて、多くの壊れたテストが奨励され、ポイント2につながります。

  2. これらのテストが定期的に実行されているのに、邪魔をしない場合にのみ、引き続き成功します。テストとは、

    a。彼らが提供する価値のために(主観的に)実行するのにあまりにも長くかかってはいけません!あなたのテストを速く燃え上がらせます。 実行を許可するのに時間の無駄になるテストをチェックインさせないでください!

    b。信頼できてはいけません。可能であれば、マルチスレッドテストを避けてください。他のコードと同じように、エンジニアリング手法をテストに適用します。特に、コードのテストを確認してください!

    c。テストされた実際のコードよりも修正と保守が難しくないはずです。コードベースのごくわずかな1行の変更で10の異なるテストを修正する必要がある場合、コーディング速度は本当にうんざりします。

そして最後に、ルール番号3です。テストは、ルール2のように、負の値を提供するだけでなく、正の値を提供する必要があります。テスト...

  1. 彼らが失敗したとき、実際にはあなたが気にかけていることを伝える必要があります! (あいまいなエラーメッセージを含むテストはありません、または単に「Windows 2008マシンでテストを実行するのを忘れた」などとんでもない不満を与えてください!).

ルール#3に違反する一般的な方法の1つは、間違ったものをテストすることです。これは、テストが大きすぎるか、焦点が合っていないことが原因である場合があります。しかし、それは通常、顧客が気にかけるものをテストしないことと、無関係な実装の詳細をテストすることから生じます。 (ただし、実装の詳細をテストすると、効率的なテストになることもあります。IMOでは、どれを決定するかを練習するだけです。)

結論:これらの基本ルールは、sustainableテストの一般的な方向性を示しています。これは、切望していることです。テストするときは、このテストが本当に持続可能で保守可能かどうかを自問してください。覚えておいてください:

  • テストが持続可能でない場合、テストは使用されなくなり、無駄な作業になります。
  • テストが持続可能でない場合、テストの実行を停止し、チームはテストの改善を停止します。そして最後のポイント:

テストは実際には難しいです。あなたはあなたがチームのテストがあなたがテストを書き始めるとき、基本的に下がることを期待するべきです。落胆しないでください。 Do古いテストを破棄します。これは、それらが不快で持続不可能であることに気付いたときはいつでも。

15

1.本当に機能しますか?

はい、そうです-適切に行われれば。重要なのは、エンジニアが新機能を実装した後、テスターは自動スクリプトを調整および拡張する必要があるということです。

2.誰も実際に経験がなく、自動テストを適切に行う方法を知っていません。

コンサルタント(適切に行われる方法を知っている人)を取得します。または、より多くの時間を投資します。もう1つの方法は、同じテストを手動で行う大きなテストチームを用意することです(エラーが発生しやすくなります)。

3. 20の優れた経験豊富な開発者が取り組んでいる大きなプロジェクトがあります。したがって、単体テスト/統合テストを導入するのに最適な環境になるはずです。なぜうまくいかないのですか?どうやってそれをあなたの会社で機能させたのですか?

ユニットテストを拒否する場合は、「経験豊富な開発者」とは呼びません。テスト(ユニットテストと統合テストの両方)の有益な利点については多くの優れた記事があり、最終的には バグがどれだけあなたの会社にかかるか に要約されます。たとえば、私は品質が重要な会社で働いているため、単体テストと統合テストは避けられません。単体テストだけでバグの数が30%削減されていることを示す多くの記事を簡単に見つけることができます! (実際には、20〜90%の範囲で、平均30%ですが、それでもまだ多くあります。)

あなたの会社でそれを機能させるには、コンサルタントを雇うか、このタスクを上級エンジニアに割り当てます(それを行うには少し時間がかかります)。そして、全員にルールを守るように強制します。

12
BЈовић

上記の回答で明確に取り上げられていないことの1つは、単体テストは本質的に公共財であり、私費です。私はそれについてブログ投稿を書きました ここ

つまり、一連のテストがチームまたは個々の開発者にメリットをもたらす一方で、テストを作成するということです。 は、ほとんどの場合、それを実行する人のコストです。

要するに、テストの作成が何らかの方法で強制されない限り、そして上記の回答にはそれを行うためのさまざまな方法がいくつかリストされています-理由はありませんこれを行うには、個々の開発者。

私が働いていたある会社では、単体テストを書くことが機能を提供するために必要な部分でした。ユニットテストがコミットまたは新機能の一部でない限り、新しいコードは受け入れられませんでした。開発者に与えられたすべての「タスク」について簡単なコードレビューがありました。職場で同様のポリシーを実装することは価値があるかもしれません。

11
Marco

これらは、自動テストの導入が失敗する多くの理由です。 結局のところ、プログラマーはコーディングの習慣を変えない傾向があり、単体テストを十分に受け入れることができないという事実に帰着すると思います。

自動テストを開始したい多くの人々は、既存のコードベースにそれらを導入しようとします。彼らは、既存のアプリケーションの多くの機能を一度にテストする統合テストを書こうとします。このような統合テストは、保守が困難で高額であることで有名です。 アドバイス:新しいコードベースの自動テストを導入します。

単体テストは自動化に適したテストです。上記のすべて(統合テスト、コンポーネントテスト、システムテスト)も自動的にテストできますが、一度にテストする機能が増えるほど、費用便益比は急速に低下します。単体テストが不十分な機能でそのようなテストを構築すると、この悪影響が増幅されます。 アドバイス:ユニットテストレベルで自動テストを導入し、ユニットテストの強固な基盤で自動統合テストを構築します

上記の点から、自動テストの成功の大部分は、単体テストの効果に依存しています。単体テストで生産性を感じた場合は、効果的な単体テストがあります。人々がユニットテストを始めるとき、彼らは既存のコードとコーディング習慣をユニットテストに改造する傾向があります。皮肉なことに、これは単体テストを学ぶ最も難しい方法です。また、単体テストでは、コーディング方法を変更する必要があります(たとえば、 SOLID原則 を適用する)。ほとんどのプログラマーはすぐに単体テストの作成をやめます。これは、リーリングカーブが急であると考え、単体テストをそれほどテストできない設計されたコードにラップするのが厄介であることに気付くからです。 アドバイス:新しいコードを使用して最初からユニットテストを学び、コーディングの習慣を変える必要があるという事実に対処してください。

他にもたくさんの要素がありますが、ほとんどのプログラマにとって、コードへの方法を変更するのは面倒なことです。テストなしで書かれたコードは、見た目が違うだけです。コードをテスト可能な設計にまとめることができない場合、効果的な単体テストを作成できなくなる可能性が非常に高くなります。これは、効果的な自動テストの基盤を破壊します。

私はそれを自分で体験し、自動テストの導入に成功した会社で働くことができて幸せです。他の要素についてはもっと詳しく書くことができますが、コーディングの習慣と単体テストが最も重要だと思います。幸運なことに、私よりも多くの経験を持ち、ノウハウで本を書いている人がいます。これらの本の1つは 。NETのブラウンフィールドアプリケーション開発 です。これは、Microsoftテクノロジスタックを使用しているため、私が本当にお勧めできるものです。

10
Theo Lenndorff

ビジネスが開発者よりもプロテスト的であるのは興味深いことです。あなたの最大の課題は、開発者の変化に対する抵抗を克服することだと私には思えます。ユニットテストを含めるには、自分の仕事に対する理解を再定義する必要があります。

開発者がこれらのテストを書くことへの抵抗を克服するのを助けるために、初期の単体テストの成功以上に役立つものはありません。何か新しいことをするようにプッシュする場合は、報酬がほぼ保証されている何かを最初にプッシュするようにしてください。

@SkipHuffmanはこれに触れましたが、私はそれを完全に言います。いくつかのものは他のものよりもはるかに自動テストに適しています。最初のパスでは、データベースまたはUIをテストします[〜#〜] [〜#〜]。データベースからの入力は、セットアップと破棄が非常に困難な場合があります。 UI出力テストは、テストにまったく関係のないルックアンドフィールの変更によってすぐに壊れる傾向があります。

私が「ミドルウェア」と呼ぶものは、単体テストに最適です。入力条件と出力条件を明確に定義したコード。 DRY原則(Do n't Repeat Yourself))に従っている場合、アプリケーションに固有の繰り返し発生する問題を解決するために、いくつかの小さなクラスまたは関数を記述していることになります。

単体テストは、既存の内部コンポーネントを変更するリスクを制限するための優れたツールです。長期間動作していた内部コンポーネントを変更する前に、単体テストを作成します。これらのテストは、現在機能している機能が保持されていることを証明します。変更を加えてすべての単体テストに合格すると、「下流」で何も壊していないことがわかります。ダウンストリームの問題が見つかった場合は、ユニットテストを追加してください。

Ron Heifitzはこう言います 「人々が持つ価値観の対立に対処する、または人々が支持する価値観と彼らが直面する現実との間のギャップを縮小する。 」変化に対する人間の抵抗を克服した後、必要に応じてより困難なテスト領域に分岐できます。

8
GlenPeterson

自動テストの1つは、テスト可能なコードを記述する必要があることです。これはそれ自体は悪いことではありません(実際には、原則として避けなければならない多くの習慣を思いとどまらせるので良いことです)が、ユニットテストを既存のコードに適用しようとしている場合は、そうではない可能性があります。テスト可能な方法で書かれています。

シングルトン、静的メソッド、レジストリ、サービスロケーターなどのようなものは、モックアウトするのが非常に難しい依存関係をもたらします。デメテルの法則の違反は、コードベースの多くの部分がコードベースの他の部分がどのように機能するかについてあまりにも多くを知っていることを意味し、破壊するのが難しい可能性のある隠れた依存関係をさらに導入します。これらすべてにより、モジュールを残りのコードベースから分離することが困難になり、モジュールを分離してテストできない場合、ユニットテストはその価値の多くを失います。テストが失敗するのは、テスト対象のユニットの障害、またはその依存関係の1つに障害があるため、または依存するデータソースを通じて取り込まれているデータが、テスト作成者が期待したものではないためです。 ?依存関係をモックに置き換えることができない場合、それらのいずれかが可能性があります。

単体テストを念頭に置いて構築されていないコードベースは、本質的にテスト不可能になる傾向があります。なぜなら、プログラマーは、疎結合と依存関係を明示的に保つために必要な作業を行うのではなく、期待どおりにコードを機能させることに集中する傾向があるためです。 。単体テストを念頭に置いて書かれたコードは、非常に異なって見える傾向があります。

多くの人々は、初めてユニットテストを開始するときに単純な方法でユニットテストを行います。彼らは、既存のコードベースに対して大量のテストを作成でき、すべてがうまくいくと思っていますが、それが理由でうまくいきません。上記の問題。彼らは、ユニットテストをまったく実行するために、セットアップの量を調整しなければならないことに気付き始めます。コードに分離がないと、テストの失敗の原因を追跡できないため、結果はしばしば疑わしいものになります。彼らはまた、システムがどのように機能するかの非常に抽象的な側面を示す「賢い」テストを書き始めようとする傾向があります。 「賢い」ユニットテストはそれ自体でバグの潜在的な原因であるため、これは失敗する傾向があります。テストされたモジュールのバグのため、またはテストのバグのため、テストは失敗しましたか?テストは非常に耐え難いほど単純であるべきで、バグがその中に隠れている可能性は明らかにありません。実際、最良のテストが2行を超えることはめったにありません。最初の行はテスト中のユニットに何かを実行するように指示し、2番目の行はそれが期待どおりだったことを主張しています。

チームがユニットテストの採用に真剣に取り組んでいる場合、既存のプロジェクトから始めるのは賢明ではありません。チームの既存のプロジェクトは、大規模なリファクタリングなしではおそらくテスト不可能です。単体テストについて学習するための基礎として新しいプロジェクトを使用するほうがよいです。シングルトン、レジストリ、その他の隠された依存関係よりも依存関係の注入を優先するように新しいコードベースを設計できます。実装などの代わりにインターフェイスに依存するようにコードを記述できます。また、テストを書き込むコードと一緒にテストを作成することもできます(後でテストを書き込むと、テスト対象のモジュールが意図したとおりに機能することを確認する単体テストが実行されます)仕様が何をすべきかを言う。

ユニットテストである程度の自信が得られると、チームはおそらく、ユニットテストの障害となる既存のコードの欠陥に気付き始めるでしょう。この時点で、既存のコードをリファクタリングしてテストしやすくすることができます。野心的ではなく、これを一度にすべて実行するか、まったく新しいシステムで動作するシステムを置き換えようとするか、簡単にテストできるコードベース(持っていないもの)のビットを見つけることから始めてください依存関係または依存関係が明らかな場合)、それらのテストを記述します。コードと一緒にテストを作成することは、後でテストを作成するよりも望ましいと言っていましたが、後で作成したテストでも、出発点としての価値はあります。テストは、クラスの仕様で規定されていることを除いて、クラスがどのように機能するかについて何も知らないかのように記述します。テストを実行してエラーが発生した場合、仕様または実装のいずれかが間違っています。両方を再確認してどちらが間違っているかを判別し、それに応じてテストまたはコードを更新します。

ぶら下がっている果物を選んだら、あなたの本当の仕事が始まります。コードベースの非表示の依存関係を見つけて、一度に1つずつ修正する必要があります。テストの障害が修正されて次のビットに進むことができるようになるまで、この時点で過度に野心的にならないでください。一度に1つのモジュールを実行するか、1つのモジュールで1つの問題を実行するようにします。

TL:DR:テストは簡単で、既存のコードにテストを簡単に改造できると多くの人が考えています。これらの仮定はどちらも間違っています。これらの両方の事実を念頭に置いて、プロジェクトにユニットテストを導入するプロジェクトに着手すると、成功する可能性が高くなります。

7
GordonM
  • 自動テストの経験が豊富な人はいますか?

そうでない場合、自動テストイニシアチブはおそらく失敗します。自動テストはプログラミングの他の多くのスキルと同様にスキルであり、それを実行した経験のある人がいない場合、自動テストが実際の価値のある自動テストであるかどうかを判断するのは簡単ではありませんgood自動テスト、またはランダムに失敗する/頻繁に更新する必要がある/実際に興味深いコードを実行しない不良なもの。

  • 誰かがリーダーシップ力を持っていますか?彼らは変化を要求することができますか?

誰も耳を傾けなければ、テストが良くないと言ってもかまいません。 (リーダーシップの力を形式化する必要がないことに注意してください。気遣うチームを持つことも良いことです。)

  • 自動テストを簡単に実装し、開発サイクルに統合するためのツールとプロセスを開発していますか?

開発者は怠惰です。あなたは彼らに彼らにしてもらいたいことを簡単に成し遂げさせ、あなたが彼らに望まないことを成し遂げることをより困難にする必要があります。テストライブラリを使用すると、テストのセットアップとティアダウンに関連するタスク、特にテストデータベースなどの環境関連のセットアップを簡単に実行できるようにする必要があります。 (データベースのモックは、これらのコメントの一部で説明されていますが、注意して使用する必要があります。実際のデータベースは簡単に起動でき、コンポーネントとプロセスのライフサイクルの相互作用をテストできます。多くの場合、ユニットテストよりも重要で効果的です。個々のデータアクセサー。)

また、IDEがテストスイートを起動する適切な方法を備えていることを確認する必要もあります。テストスイートを頻繁に実行して、テストスイートが失敗したときに、それを悲惨なままにさせるのではなく、気付くようにする必要があります。また、開発者はフィードバックにもよく対応します。テストに失敗した場合、変更を元に戻す自動統合システム。または、より良い、肯定的なフィードバック:バグをキャッチし、問題を回避する自動統合システム。

4
user2348

まず、開発者がテストの価値を認識しない場合、それはおそらく、開発者がその価値や一般的なテストの価値を知らないためではなく、テストが価値がないためです。その伝道者の中には、テスト駆動開発が失敗するわけではなく、単に怠惰な怠惰な開発者が失敗するだけであると信じる傾向があります。これは間違っていて逆効果だと思います。

私がテスト駆動開発に紹介されたとき、それは事実上、失敗することのないメソッドが決して失敗しないことを確認するテストを書くことを意味しました。素敵なグリーンチェックと達成感を得られるので、最初はどちらがいいですか。その後、コードをリファクタリングした後、何十もの赤いXesに苛立ちを感じました。どれも、コードが変更されたこと、テストが有効でなくなったこと、そしてそれらを書くのに多くの時間を費やしたこと以外には何も言いません。

あなたはそれを避けたいです。

それ以来、私はテストに対して別のアプローチをとってきました。 インターフェース実装ペア の代わりに、インターフェース、実装、テストトリプルがあります。インターフェースは動作を指定し、実装は動作を実行し、テストは動作をチェックします。

当たり前のように思われるかもしれませんが、私には、指定したとおりに機能することを証明する必要があるコードと、適切と見なす程度にテストするコードが区別されます。証明しなければならないコードは、外部に提供するインターフェースです。残りはあなたの心配事だけです。

この場合、開発者に、この種のテストが適切であるコードに自然な分割があるかどうかを尋ねます。チームAが実装し、チームBが使用するインターフェイスはありますか?その場合、インターフェイスが期待どおりに動作することを確認することは、チームBの利益になります。チームBにテストを記述してもらい、チームAに実装がテストに準拠していることを確認するように伝えます。または、そうでない場合、および意図的に行わない場合は、予期しない変更について他のチームと話し合って、彼らが準備できるようにします。

これはテストの価値を示していると思います。それ自体が目的ではなく、素敵な緑のチェックにもかかわらず。それは、ある開発者が行った約束を別の開発者に明示し、約束が両方の満足感に保たれることを保証するために存在します。

4
drew

長いゲームをしなければならないかもしれません。ある程度の受け入れを得るためにできることの1つは、作成する次の機能を徹底的に単体テストしてから、時間の経過とともにバグの数を追跡することです。できれば主要なバグが早い段階で発見され(特にこれをテスト駆動設計と組み合わせた場合)、回帰の数は非常に少ないはずです。一定期間、たとえば1年後、統計を単体テストされていない同様の複雑さの機能と比較します。新しいバグとリグレッションの数がかなり少ないことを示すことができる場合は、それに対する経済的正当性を提供しており、製品チームが無視するのが難しくなります。

TDDと単体テストを主要な機能に使用できる状況にありました。開発フェーズの終了後、5年以上の間に報告されたバグは1つもありませんでした。新しい、そしてリスクのある拡張が要求されたとき、私はそれを実装し、単体テストですべてのリグレッションをキャッチすることができました。

2
the_mandrill

既存の大規模プロジェクトに多数の単体テストを追加することは大変な作業です。あなたのために働く良いモックフレームワークをすでに見つけているなら、あなたは最も難しい問題を解決しているはずです。

機能を追加したりバグを修正したりするときに、テストを追加することをお勧めします。バグを修正するのが最も簡単です。バグが原因で失敗したテストを記述してから、バグを修正します。同時に、おそらく、合格したより簡単なテストをいくつか書いていることに気付くでしょう。もちろん、あなたは本当にこれのために小さくて簡単にテストされたコードのビットを使いたいです。

人々がより簡単なもののためのテストを書くことに慣れ始めたら、うまくいけば、彼らがよりテストしやすいコードを書いていることに気付くはずです。

また、テストのコードカバレッジを測定することをお勧めします(過去にJavaに cobertura を使用しました)。継続的な統合サーバーでテストを実行し、定期的に(毎日、チェックインごとに)メトリックを生成する必要があります。あなたの仲間の開発者が熱心であるならば、彼らは時間の経過とともにカバレッジが増加するのを見たいと思うでしょう、そして彼らはあなたのいくつかのギャップカバレッジホールを見ることができます

2
brain

単体テストの価値は、いくつかの要因のために多くのチームによって過小評価されていると私は強く考えています。

多くの場合、開発者は「物事を成し遂げる」というプレッシャーにさらされているため、コードブロックが機能することを証明することは、顧客にとって十分な証拠となります。これはほとんどの場合、コンサルティング会社と人間主導のQAに当てはまります。顧客が単体テストを必要とせず、十分なライブデモを検討している場合、障害を隠す可能性のあるコードの承認に署名することになるため、顧客は完全に不合格です。

多くの場合、開発者はイライラしています。プログラマーであることは大変な仕事です。タスクを完了して次のタスクに進むことは満足できるので、誰もが急いで終了したいと思っています。元のQAから数か月後に発生する大きなバグでバスに襲われるまで。このシナリオでは、自動化された継続的なQAは、開発者ではなく管理者の問題です(おそらく、残業代は支払われます)。

しかし、例外があります

自動テストモデルの受け入れは、実行されるテストの「人間らしさ」の関数であると私は強く信じています。フロントエンドでWebモジュールをテストしている場合、Seleniumなどのツールにもかかわらず、自分でフォームに入力し、結果を確認して決定論を信じる可能性が高くなります。後でテストを再実行するのを忘れるか、古いテストを再度実行するのが面倒なので、バグが後で発見されることがあります。これを活用するために、コードの強力なモジュール化と「古いコードの変更」に関する厳格なルールは、銀行業務環境で受け入れられることが証明されています(私の個人的な実務経験において)。

代わりに、開発者が高度に自動化された大量のデータモジュールの開発を担当している場合、完全な単体テストを作成してテストバッチに送信する可能性が高くなります。これは、大規模なXMLペイロードに外部データソース(モック化されているかどうかにかかわらず)から変換されたデータを入力することは、人間が行いやすい作業ではないためです。一部のテスト開発者は、最終的にこの特定の種類のテストのための小さくて面白いフロントエンドを構築します。修士論文では、1秒あたり6000以上のsyslogメッセージを処理するロギングバスに取り組んでおり、パケットの損失と破損を測定する必要がありました。ほとんどすべてのコンポーネント(特にSyslogパーサー)の単体テストとストレステストを自然に作成しました。

開発者をよりユニットテストしやすくするために

彼らは強制されなければならないと私は信じています。あなたが賢い顧客であれば、コンサルタントにすべてのQAで完全なテストスイートを実行するように要求します。あなたが優れたチームリーダーである場合は、次のタスクを賢い開発者に割り当てることを考えるかもしれません:内部テストプラットフォームの構築。これは、内部効果プラットフォームのアンチパターンでは何もわかりませんが、代わりに、ヘルパークラス、データベースモック、構成、パーサー、コンバーター、スイスアーミーナイフのセットであり、開発者がすぐにテストを構築できるようにします。

NUnitなどの現在のテストプラットフォームは汎用であり、一般的なアサーションを検証できます。依存関係注入とプロジェクト固有のファクトリーを正しく使用することで、開発者はテスト用のコードを減らし、より幸せになります。これを完全なプロジェクトで試す機会はまだありません。実際のフィードバックを提供することはできません。

自動テストはソフトウェア開発のようなものです。残念ながら、あなたがテストのために雇う人々は、もともとテストケース、計画、戦略を書き、レビュープロセスに従い、手動でテストしてバグを記録することを目的としています。

自動テストの責任が与えられるとすぐに、ある程度のソフトウェア開発が含まれます。ここでの問題は、使用するツールに関係なく(そして、天国のためにこの点について議論しないでください)、自動化されたテストには、毎日のメンテナンスと更新が必要なことです。開発者がコードを変更すると、

  • テストが実行され続けることを確認する必要があります。
  • テストが実行されなかったため、テストが削除されないようにする必要があります
  • テスト指標は、前回のビルドと今回のビルドで何を実行したかを示す必要があります。テストケースの数が減少していないことを確認するため。
  • 人々が混乱しないように、開発と同じようにテストケースをレビューする必要があります。数値を上げるために、1つのテストを2つに分割します(テストは外部委託される場合があるため、この追跡は重要です)。
  • 開発とテストの間のより「健全な」コミュニケーションが重要です
  • 保つ non-functionalテストは個別であり、毎日実行することを期待していません。これらを最新の状態に保つには時間がかかります。しかし、あきらめないでください。それらが維持されていることを確認してください。

これらの理由で失敗する

  • テストエンジニアは、分析スキルのない手動テストエンジニアです。彼らは、ifループとwhileループの違いを知りません。率直に言って、自動テストを教えるコースはないため、手動テストのみを教えています。
  • テストエンジニアがビルドを手動でテストし、バグをログに記録して、自動化されたテストを追跡できないほど忙しい
  • テストマネージャーは、(プロジェクトの開始時に)無効なデータを表示するという理由だけで、自動化されたテストからのメトリックを気にしません
  • 保存期間が非常に短いモバイルアプリケーションのテストを自動化することを選択します。作成するまでに、アプリケーション要件が変更する自動テストスイートを安定させます。代わりに、アプリケーションを実行するウェブサービスのテストに集中する必要があります
  • 自動テストチームが開発チーム、機能の完成、コードの完成、コードのロックダウン、コードのフリーズと同じマイルストーンに従っていることを理解していない。
  • 手動テスト担当者と自動テスト担当者を区別しません。
  • 彼らは両方とも同じ給与を支払われ、同じマネージャーに報告します。理想的には、開発マネージャーに報告する必要があり、給与は開発の給与と一致する必要があります。
  • あなたは実際にjunitが自動テストを開発するのに十分ではないと考え、信じています:).

これらは、自動テストを真剣に受け止め、自動テストエンジニアとしてdevが重要であることを理解している企業で働いた経験からのものです。そして、知らない人のために働いた私の経験から、あなたが彼らにいくら説明しても、違いを理解してください。

1
Siddharth