「合格/破損ビルド」インジケータの代替手段


14

コミットごとにテストを実行する継続的な統合を行う場合、一般的なベストプラクティスは、すべてのテストを常にパスすることです(「ビルドを中断しないでください」)。

私はそれに関するいくつかの問題を見つけます:

たとえば、チケットに対応するテストを作成して、オープンソースプロジェクトを支援することはできません。失敗したテストを含むオープンソースプロジェクトにプルリクエストを提案した場合、ビルドは失敗としてマークされ、プロジェクトは「ビルドを壊す」ためリポジトリにマージされたくないでしょう。

そして、レポテストに失敗するのは悪いことではないと思います。それは、トラッカーに未解決の問題があるようなものです。これらは修正されるのを待っているものです。

同じことが会社にも言えます。TDDを使用している場合、テストを作成し、コミットしてから、テストを満たすロジックコードを作成することはできません。つまり、ラップトップで4〜5個のテストを書いた場合、休日に行く前にテストをコミットすることはできません。誰も私の仕事を取り戻すことはできません。たとえばメールで送信する場合を除き、同僚と「共有」することさえできません。また、テストの作成者とモデルの作成者との作業も妨げられます。

言うまでもなく、私はビルドプロセスを誤用/誤解しているか、継続的な統合を行っていますか?「通過する」/「通過しない」という指標は狭すぎるように思えます。

継続的な統合とTDD互換性を実現する方法はありますか?

「新しいテスト」(失敗する可能性がある)と「回帰テスト」(以前機能していたため失敗するべきではない)を区別するための標準的なソリューション/プラクティスがあるかもしれません。


1
過去1時間以内に失敗したテスト数が増えた(赤)か落ちた(緑)かを示すインジケーターを用意します。
ヨアヒムザウアー

2
私はTDD / ALMのスペシャリストではありません(したがって、答えではなくコメントです)が、あなたの問題はプライベートブランチ/機能ブランチで解決できると思います。機能Aに取り組んでいますか?それを分岐させ、(同僚と)分岐に取り組み、完了したら、それを継続的に統合されたトランクにマージします。
アヴナーシャハルカシュタン

@JoachimSauerはい、ただし、そのようなメトリックは、主要プロジェクトで標準化/使用されていますか?ほとんどのプロジェクト(およびCIツール)がそのように機能する理由を理解しようとしています。
マチューナポリ

「失敗する可能性のあるテスト」の正しい基準は「新しいテスト」ではなく、「既知の未解決の問題のテスト」だと思います。それらのテストがどのように役立つかを見ることができます-それらがテストの成功/失敗の意味を汚染するため、それらのテストがCIビルドでどのように役に立たないかを見ることができます(誰かが実際に時間を費やしたテストのみを実行したい合格させるため)。
ジョリスティマーマンズ

@MadKeithV正確に
マチューナポリ

回答:


12

あなたがどこに着いているのかわかりますが、これらのタイプの問題は通常、他の方法で解決されます。これが標準プロトコルであるのには十分な理由があります。誰かがコンパイルされないコードを送信すると、コードを更新する全員がコンパイルされないプログラムを持ちます。これには、現在完全に異なるものに取り組んでおり、作業中の内容をコンパイルしてテストできるようになるまで待つ必要がある状況に何らかの形で気づくプログラマーが含まれます。

標準プロトコルでは、プログラマが必要に応じて毎日コードを更新できるようにコンパイルされている限り、完全な作業または不完全な作業でも変更をコミットできます。

しかし、私はまだあなたが何を得ているのか見ています。コードを単純に保存するためにコミットしたい場合があります。このため、ほとんどのソースリポジトリは分岐をサポートしています。これにより、プライベートブランチを作成し、他のユーザーに影響を与えずに作業し、作業が完了したときにトランクにマージできます。これにより、ビルドの中断に関連するバックラッシュなしで、必要なときにコミットできます。

それが適切でない場合、GITを使用すると、ローカルマシンのリポジトリにコミット(プッシュ)できますが、リポジトリはどこにでもある可能性があります。潜在的に部分的/不完全な作業用のリポジトリと、完成した作業用の別のリポジトリを作成し、そのリポジトリにナイトリービルドを追加できます。

繰り返しますが、私はその重要性を十分に強調することはできません。 壊れたコードをトランクにコミットしないでください! あなたの貢献は他のプログラマの仕事に影響を与えることはできません。

編集

あなたは壊れたテストを意図していたと思いますが、私の謙虚な意見では、ほとんど違いはありません。テストの重要なポイントは、プログラムの特定の側面が成功するか失敗するかを判断することです。常に失敗し、何もしない場合、単体テストの従来の使用法では、テストは何の役にも立ちません。そのようなテストの1つが失敗しても「失敗した」コミットを必ずしも必要としない他のメトリックを実行する場合、同じことを行う別の方法を見つけることを強くお勧めします。

そうしないと、テストが考慮されないことや、ビルドが失敗する場合、仲間のプログラマーが失敗したビルドを無視する危険があります。プログラマーがビルドを壊したときに気付くのは、実際の洞察を提供せず、悪いプラクティスにしかならないテストを実行するよりも重要です。


1
確かに、トピックの分岐でポイントを作ります。しかし、私は壊れたコードをコミットすることではなく、単にテストに失敗することについて話しているのではありません。たとえば、受信チケットの修正方法がわからなくても、受信チケットのテストを作成することで、オープンソースプロジェクトを支援できます。これにより、メンテナーの時間を節約できます。
マチューナポリ

私があなたと同じプロジェクトに取り組んでいて、失敗したテストをアップロードすると、失敗したテストを含むビルドができます。その機能はまだ実装されていないため、テストを削除してしまう可能性があります。または、機能を実装してコードを踏み込んで時間を浪費することにします。これを行う文化がある場合、そのような応答は回避できますが、その後は誰もがそれを行うため、すべてのテストが合格した場合でも、私のすべてが応答するわけではありません。その場合、ビルドのテストは常に失敗します。私は逆さまを見ていません。
マイケルショー

the build would always have failing tests正確に!しかし、それはそんなに悪いことですか?私たちの唯一の測定基準は「ビルドが壊れているかどうか」ですが、コードには既知のバグがたくさんある可能性があります。そのため、リグレッションがない場合以外は何も意味しません。完璧な世界では、すべてのトラッカーの問題にテストがあります(再現することは修正するより簡単です)。したがって、利点は、35テスト/すべてのテストの70%が合格していること、Branch-Aが40テスト(80%)に回帰なしで改善し、Branch-Bに回帰があることです。今日、マスターとブランチAは問題なく、ブランチBは壊れているとしか言えません。
マチューナポリ

@Matthieuあなたが何を得ているかわかります。特別なカテゴリまたは「このテストが失敗した場合、それは問題ありません。私たちはそれを知っています。しかし、私たちはそれを実行したいので、合格したらさらに良いので、特別なカテゴリを削除する必要があります今は壊れるかどうかを気にしています」
アールズ

@Earlzまさに!私が疑問に思っているのは、「誰かによって行われているのか、それをサポートするツールがありますか(CIおよび単体テストライブラリですか?)」ということです。とにかく失敗し、私はどのテストが失敗したかの違いを見ることはありませんので、それは有用ではありません:/
Matthieu Napoli

4

テストに失敗したマスターブランチがある場合、そのリストを以前のビルドと比較せずに、バグを導入していないことをどのようにして確認できますか?

失敗したテストの数を単に追跡するだけでは不十分です。あるテストを修正し、別のテストを中断する場合があります。また、休暇中の場合、失敗したビルドを見ている他の人にはわかりません。

マスターブランチを常に清潔で緑色に保ちます。ブランチで働きます。ブランチをCIの下に別のジョブとして保存し、失敗したテストを心ゆくまで実行します。マスターを壊さないでください。

ブランチのレビュアーがすべてのテストに合格した場合にのみブランチをマージするようにします。(より強く:ブランチをマスターにマージした結果がすべてのテストに合格した場合にのみ、レビュアーがブランチをマージできるようにしてください!)


2
Simply tracking the number of failing tests is insufficientそれが唯一の可能な指標ではありません。例:Branch-A improves it to 40 tests (80% passing) with no regression。回帰は、以前に合格したテストが常に合格することを意味します。要するに、一度も合格していなければ、テストは失敗することが許されます。主要なブランチでのテストの失敗を禁止するように制約することで、良いことを見逃しているように思えます。(もちろん、異なる動作をするツールが必要になります:単体テスト、CI、...)
Matthieu Napoli

私は今でも私の立場に立っています:マスターは常に緑である必要あります。なぜなら、それは明確で明確だからです。機能ブランチでのマーカーテストの失敗... CIは、未解決のバグを人々に思い出させ続けることができます。
フランク・シーラー

マシューが提案しているのは、「グリーン」の定義がわずかに異なることであり、常にグリーンであるマスターから逸脱するものではないと思います。それが意味をなさないことは私には明らかではありません-もちろん、追跡のために完全に些細なツールではない必要があります。(そのテストに合格した変更をロールバックする必要がありますか?それは状態が突然赤であることを意味する場合は厳しい運...)
クリストファー・クロイツィヒ

NUnitには、無視されたテストの概念があります。それは代替案かもしれません:それらは実行されないので失敗しませんが、それらはまだ無視されていると報告されています。
フランク・シーラー

2

継続的インテグレーションに関するよく理解され、受け入れられている慣行を捨てることなく、問題を解決する方法があります。

チケットに対応する「壊れたテスト」をコミットする問題から始めます。1つの解決策は、問題を公開する1つ以上の破壊テスト作成し、実際に問題を修正して、それらをメインコード行にマージして戻すことです。2番目の解決策は、テストが壊れいるが、実際には実行されずビルドが壊れないように、無視フラグを使用することです。コメントまたは特別な注釈追加して、これがの壊れたテストであることを非常に明確にしTicket#Nます。また、無視されず実行されるのを待っている作成済みのテストを参照するメモをチケット自体に添付します。これは、チケットを修正する人を助けますが、テストに出くわした人にとっては危険ではありません。

そして、TDDの次の問題について。TDDは、小さなテストを作成し、そのテストに合格するために小さなコードの塊を作成することです。その後、小さな機能モジュールができるまで繰り返し続けます。4〜5回のテストを書いてから休暇に行くと、間違っているかもしれません。誰かがテストを書き、もう一方が対応するコードを書くという方法で、プログラムを誰かとペアにすることができます。ただし、完成したモジュールをコミットする準備ができるまでは、メインコードラインリポジトリを使用してこのコードを共有しないでください。他の人が示唆したように、共有ブランチはそこで問題を解決します。

継続的インテグレーションのマントラを破ろうとすると、予想外の恐ろしいパスに至る可能性があります。たとえば、このタイプの環境でコードカバレッジは何を意味しますか?開発者は、システムに壊れたウィンドウがたくさんあると感じないでしょうか?どのように変更を加え、テストを実行し、実際に新しい何かを壊しているか、それとも単に古いものを壊しているかを知るでしょうか?


ペアプログラミングの相手と共有するためのツールは必要ありません。キーボードを渡すだけです。別のコンピューターを使用している場合、それは問題ありません。「ペアプログラミング」ではありません。
クリストファー・クロイツィヒ

1

あなたの根本的な問題は、ビルドの一部としてテスト結果を含めることだと思います。明らかにあなたに同意する人もいれば、そうでない人もいます。ビルドを壊さないのは、ビルドしないときです。エラーなしでビルドしないときではありません。

WindowsやLinuxのような主要なプロジェクト、またはFirefoxのようなプロジェクトを考えてみてください。バグのない出荷をしていると思いますか?もちろん違います。現在、これらのプロジェクトはTDDを実行していませんが、それは本当に無関係です-TDDは2つの基本的な事実を変更しません:バグが存在し、それらを修正するのに時間がかかります。プロジェクト(オープンソースかどうか)が優先度の低いバグを無駄にする余裕がない時間。KDEには最近10年以上前に修正されたバグがありました。「プロジェクトを出荷するのに10年待っていてよかった」と誰かが言ったのを最後に聞いたのはいつですか?

TDDは、ある意味では、おそらくバグを含めて出荷するのが容易になります-欠陥とは何かをよりよく理解しているからです。バグの原因を正確に定義できる場合、それを修正するコストを評価するための優れた基盤があります。

私の推奨事項は、緑と赤の組み合わせを気にしないプロジェクトを見つけることです。


1
 > a common best practice is to have all the tests passing (green) at all times.

すべてのテストが失敗しない(赤ではない)ことを好みます。

このわずかに異なる定義を使用して、次のテストを定義することもできます。

  • まだ実装されていません(NotImplementedExceptionがある場合、nunitで灰色)
  • テストを無視/マーキング(黄色)することにより、failing = "する必要がある"ことがわかっている

これらをリポジトリにチェックインすると、継続的なビルドが破損せず、したがって有効になります。


0

2つの異なるCIビルド「概念」を検討できます。

  1. 通常のCIビルド。通常のCIビルドは、コードが記述されたテストのみをコンパイルして実行する必要があります。そのため、テストの合否のCIレポートは、以前に受け入れられたコードの状態に対する回帰の明確で明確な指標です。
  2. 「将来の」CIビルド。このビルドは、特にパスするためのコードが記述されていないテストのみをコンパイルして実行します。このようなテストを行う理由はいくつかあります。

    • まだ修正が試みられていない課題トラッカーからの特定の障害ケースに対してテストを追加できます。修正を行わなくても、問題の成文化された実行中のテストを既に持っていることは明らかに便利です。

    • まだ実装されていない新しい必須機能のために追加されたテスト。

    • 多くの場合、機能または修正を実装する方法を知るよりも、障害または機能をテストする方法を知る方が簡単であり、テストをソース管理にコミットして2つのステップを分離することは、情報が失われないことを保証するのに役立ちます。

「標準」CIの場合と同様、通常の開発体制では、チームは通常のビルドの毎日のビルド結果のみを確認します。

また、チームは「将来の」CIビルドからのテストケースの進化に注目することができます。特に、通常のCIに加えられた変更が実際に「将来の」ビルドの問題を修正するかどうかを確認できます。根本的な問題または設計の改善。

最後に、チームメンバーが余分な時間を持っている場合は、「将来」の問題の1つを修正し、問題を「通常」に移行することができます(問題トラッカーステータスの更新中)。


0

また、レポでテストに失敗すると悪いことではないと思います。トラッカーに未解決の問題があるようなものです。これらは修正されるのを待っているものです。

問題はテストに失敗することではなく、単純な、コンテキストの少ない回帰の指標です。別名:開発者として、単一のインジケーターをチェックし、回帰または破壊コードを導入したかどうかを知ることができます。

「ソフト」障害の概念を導入した瞬間(大丈夫です、私たちはそれに取り組んでいます/まだ実装されていません/新しいバージョンを待っています/この他のビルドが修正されると再び通過します)、あなたは必要です予想される状態を知るために、テストを実行したり調べたりする可能性のある全員。これは、十分な規模のチームでは1時間ごとに変化します。インジケーターは無意味になります。小規模なコンテキスト(たとえば、チームプライベート統合テスト)では、技術的な負債のようなもので、問題はないと思います-管理するだけです。

ほとんどのツールが「グリーン/パス」は、コードが機能していることではなく、期待される結果を反映していることを示しています。

  • フィットネスには、予想される失敗の概念があります。
  • JUnitには@Ignored / @Test(expect =)があります
  • キュウリのステータスは「まだ実装されていません」(または呼ばれているもの)です

それらには独自の問題があります(「はい、壊れて動作していることを知っています」と「正しい動作は例外です」をどのように区別しますか)-しかし、彼らは助けます。


0

スキップされたテストを使用します。

私が使用する特定の単体テストフレームワークでは、SkipTest例外を発生させることができます。テストは実際には実行されず、失敗してもビルドは中断されません。ただし、スキップされたテストの数を確認し、その領域で実行すべき作業があるかどうかを確認できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.