テストに時間がかかる場合にトランクを安定させる方法は?


9

3組のテストスイートがあります。

  • 実行に数時間しかかからない「小さな」スイート
  • 複数時間かかる「中」のスイートで、通常は毎晩(毎晩)実行されます
  • 実行に1週間以上かかる「大きな」スイート

短いテストスイートもたくさんありますが、ここではそれらに焦点を当てません。

現在の方法論は、トランクへの各コミットの前に小さなスイートを実行することです。次に、ミディアムスイートが毎晩実行され、午前中に失敗したことが判明した場合は、昨日のコミットのどれが原因であるかを特定し、そのコミットをロールバックして、テストを再試行します。大規模なスイートでは、同様のプロセスが、毎晩ではなく毎週のみ行われます。

残念ながら、ミディアムスイートはかなり頻繁に失敗します。つまり、トランクが不安定になることがよくあります。これは、変更を加えてテストするときに非常に煩わしいことです。トランクからチェックアウトするとき、それが安定していることを確実に知ることができず、テストが失敗した場合、それが私のせいかどうかを確実に知ることができないので、それは迷惑です。

私の質問は、トランクを常に最高の状態に保つような方法でこれらの種類の状況を処理するためのいくつかの既知の方法論がありますか?例:「特別な事前コミットブランチにコミットし、夜間が経過するたびにトランクを定期的に更新する」。

そして、それがSVNのような集中化されたソース管理システムであるか、gitのような分散型システムであるかは重要ですか?

ちなみに、私は物事を変更する能力が限られているジュニア開発者ですが、私が経験しているこの痛みに対処する方法があるかどうかを理解しようとしています。


6
どのソフトウェアに取り組んでいるのかはわかりませんが、実行に数時間かかる小さなテストスイートはWTFです。彼らがより速く走るなら、これはより簡単でしょう、あなたのテストを合理化する方法はありませんか?
Benjamin Bannier

2
トランクが不安定になることについて、「非常に迷惑」なのは何ですか。ご存じかどうかはわかりませんが、最も人気のある分岐戦略の 1つは不安定トランク
gnat

1
テストスイートを最適化する方法はたくさんあります(他のソフトウェアと同様)。なぜこれほど時間がかかるのかはわかりませんが、たとえば、テスト環境の一部を再利用したり、実行時により優れたアルゴリズム/データ構造を使用したりできる場合があります(プロファイリングが役立ちます)。また、代表的なサンプルを特定するのに誰も時間がかかっておらず、参照に対してあらゆる可能な入出力をテストするだけである可能性もあります。ビルドシステムでコードテストの依存関係をエンコードできるので、フルセットを実行する必要はありません。これはあなたの質問ではなかったので、答えではなくコメントにしました。
Benjamin Bannier

1
...うーん、あなたのより良いオプションは、失敗の理由を見つけやすくするためにテストとアプリケーションのロギングを改善する可能性があります。そうすれば、人は見つけて修正する必要があり、原因を探して、「探偵調査」上の努力を無駄にすることの失敗の代わりに誰が、なぜコードの特定の行...変更
ブヨ

1
@honk一部のテストは実行に時間がかかるだけです。私はデータ収集機器を製造する会社で働いており、「部分的な」テスト実行には約1時間かかります。テストはさまざまなタイプの測定を行う必要があり、それには時間がかかります。
ヴェロキラプトルズ

回答:


1

他の回答が示唆しているように、不安定性の根本原因を修正する唯一の方法は、コードを分離して変更をより分離することです。

ただし、個人の開発者として、個人的に作業するためのより安定したビルドが必要な場合は、比較的簡単に解決できます。ヒントから作業するのではなく、夜通しのテストスイートに合格した最後のビルドのみを作業ツリーにプルします。変更ごとに機能ブランチを作成できる場合は、最後の安定したビルドからブランチします。

はい、あなたのツリーは数日遅れますが、ほとんどの時間は重要ではありません。安定したビルドに対して作業を行い、変更がテストに違反したものであることを確認してから、チェックインする前に最新のものに更新し、通常の統合を行ってください。その後、チェックインした後、最後の安定したビルドに再度バックアップします。

まだ面倒な統合作業を行う必要がありますが、この方法で気に入っているのは、統合作業を自分にとって都合のよい時間に分離し、都合の悪いときに開発用の安定したコードベースを提供することです。自分の変更が他の誰かのものと比べてビルドを壊した可能性が高いとき、私ははるかに良いアイデアを持っています。


1
-1ブランチから作業することは実行可能なオプションですが、テストすることを提案せずに推奨することは、良いことよりも害を及ぼす可能性があります。特定のプロジェクトで実現可能かどうかを示すのはテストだけです。たとえば、約2年前に行ったプロジェクトでは、このようなテストにより、ブランチからの作業は不安定なトランクに比べて約7倍の労力を費やしていることが
わかりました

カール、ありがとう!これは私が学びたいと思っていたものではありませんが、これは当面の問題を解決するのに役立つ非常に実用的なアプローチです。トランクの数日遅れて作業しても、統合の問題が発生することはめったにありません。
オーク

12

あなたがこれを避けようとしているのはわかっていますが、ここでの真の洞察は、コードベースに深刻な問題があることを認識することです。

この問題を修正する最も有利な方法は、コードベースとテストを(独立した)サブユニットに分離することです。
これには大きな利点があります。

  • これらの各ユニットのテストはより高速に実行され(単純にそれらの数が少なくなります)、独立したユニットまたはダウンストリームユニットのいずれかで問題が発生しても、テストは中断しません。
  • 失敗したテストは特定のユニットに特定されるため、問題の原因をより簡単に見つけることができます。
  • さまざまなユニットのVCSの場所を分離して、「安定した」ブランチが各ユニットの正常にテストされた最新のビルドのピックアンドミックスになるようにして、壊れたユニットまたは2つが「安定した」バージョンを不安定にしないようにすることができます。 。

VCS構造の裏返しの管理はより複雑になりますが、完全なテストの1週間で、あなたは苦痛を感じることができると思います!

私はまだ何らかの形で「安定した」および「開発」ブランチ戦略を使用することをお勧めしますが、それに対処する多くの方法があり、組織に最適な方法を選択できます(修正されたリビジョンを指すメタリポジトリ)各ユニットの個別のリポジトリ、安定ブランチと開発ブランチ、機能ブランチ...)


1
大規模なテストがアトミックテストであるとは言っていません。これはテストスイートです。個々の開発者が要素Xに変更を加えると、どのテストスイートから作成されたかに関係なく、Xに関連するテストを実行します。これは、ある場所での変更が別の場所に予期せぬ影響を及ぼさないことを確認するために実行される週次テストに追加されます。しかし、少なくともこのように分離することで、リスクをほぼ同じレベルに保ちながら、特定のモジュールのテストを高速化できるという興味深い点を指摘します。
Oak

2
@oak-まあ、すべてが実行されている場合にスイートがアトミックであるという点で、コードが安定していることを実際に確信できる唯一の方法ですが、あなたは良いポイントを作るので、私の回答を編集しました。
Joris Timmermans

4
コンパイラーには巨大なテストスイートがあり、そのうちのいくつかは実行に数日かかりますが、C ++コンパイラーほど複雑なソフトウェアでは珍しいことではないと思います。スイートが「安定」と見なされるものを定義するのではなく、毎日何百ものテストを実行することが不可能であるコード生成の数百万の異なるコーナーケースが存在します。
JesperE

1
@JesperE-巨大なテストスイートが「安定」を定義していないが、巨大な健全性テストである場合、それは理解できます。完全なスイート(または中規模のスイート)が頻繁に失敗することはないと思います。
Joris Timmermans

1

SVNの場合、「プリコミット」のようなことは知りません。テストが失敗すると、コミットとロールバックが発生する可能性が高いと思います。doc-brownが言うように、一時的なブランチでコミットして、後でトランクとマージする唯一の方法があります。

gitやmercurialのような分散型のものを使用すると、それは可能だと思います。「テスト」リポジトリと「安定」リポジトリの使用。テスト担当者をプッシュし、毎晩テストします。すべてが正常に実行された場合、テストから安定版にプッシュします。それ以外の場合は、テスト担当者をロールバックします。テストから安定版にプッシュしたときのバージョン履歴がどのように見えるかは少しわかりませんが、そうすることで壊れたロールバックされたものを除外することは可能だと思います。最初に少し実験するのが最も安全でしょう。

代わりに、各人の地元のトランクを毎晩テストすることもできます。その後、テストに合格したユーザーは、午前中にテストを中央サーバーにプッシュすることができます。


1

私見これはあなたが使っているVCSとは何の関係もありません。「テスト中」のブランチを使用することが解決策になる場合があります。これは、集中型または分散型のVCSでも実現できます。しかし、正直なところ、私はあなたの状況で最良のものは中程度のテストスイートを最適化して(最も重要なテストが含まれているようです)、はるかに高速に実行できるようにして、プリコミットからトランクに使用できるようにすることだと思いますテスト、ちょうどあなたが今あなたの「小さなスイート」でそれを行うように。


私は主にここで方法論について尋ねています-つまり、そのような状況に対処する一般的な方法はありますか。少なくともこの議論のために、テストがすでにあるものを超えて最適化できないと仮定しましょう。
Oak

@オーク:ここにいる誰か(あなたは?)あなたの質問の下の議論でわかるように、他の人が同じことを提案したので、私の提案はそれほど悪くないようです。
Doc Brown

+1、これが正しい答えです。OPの本当の質問は、「ヘルプ、私はがらくたに溺れています。自分を助けるためにどのような方法論を使用できますか?」答えは、本当に方法論はあなたが心配すべきものではないということです。
MrFox、2012年

1

失敗する中程度のテスト:ほとんどの場合、同じテストが失敗するのは本当ですか?

失敗した場合、失敗した同じ関連テストが常にありますか?

trueの場合:失敗することが多い中程度のテスト(エラーのクラスごとに1つのテスト)を選択して選択し、小さなセット内で実行できます。

ほとんどのテスト統合テストは実際のデータベースを使用していますか?もしそうなら、それらをモック化されたデータベースを持つユニットテストで置き換えることは可能ですか?


1

テストをより高速に実行する必要があります。この円を二乗する他の方法はありません。

問題を検討してください。チェックアウトするときに、コードが機能していることを確認してください。確かに、リリースの前までコミットと分岐を遅らせることができますが、それは統合までの問題の発生を遅らせるだけです。同様に、すべてのマージ後に1週間のスイートを実行する必要がありますか?方法論は解決策ではありません。解決策は純粋に技術的なものです。

これが私が提案するものです:

1)テストをできるだけアトミックにし、環境の再利用を最大化します。

2)それらを実行するためのテストスイートファームを取得します。8つの大きなモジュールではなく50になる場合、Amazon EC2スポットインスタンスの束をスピンアップして、スイート全体を並行して実行できます。これにはいくらかお金がかかると思いますが、開発者の時間を大幅に節約できます。


0

あなたの質問で当たり前になっている重要なことは、すべてのコミットがテストに合格する必要があるということです。これは従うべき良いルールであり、ある程度の意味があるようですが、実用的でない場合もあります。あなたのケースは一例であり(MadKeithVは重要ですが)、開発者間の十分な協力がない場合、VCSブランチを維持して、初期状態を維持することは想像できます。

実際には、どのコミットが成功するか失敗するかをどうにかして知りたいのです。提案した「プリコミットブランチ」は機能しますが、開発者がコミットを行うときに余分な労力が必要になる場合があり、販売が難しい場合があります。

より簡単な同様のアプローチは、トランクをユーザーが自由にブレークできるようにしておき、ブレークされないコミットのためのブランチを用意することです。自動化されたスクリプトは、トランクに対して行われたコミットを通過し、それらに対してテストを実行し、合格したらブランチに追加することができます。

または、ばかげて単純化して、テキストファイル(渡されたコミット自体がバージョン管理されている場合とそうでない場合がある)に渡されたコミットを一覧表示するスクリプトを作成することもできます。

または、テストするブランチ/リビジョンの要求を受け入れ(ツリーの任意の場所から)、それらをテストし、それらがパスした場合はそれらをトランク(または別のブランチ)にコミットするバッチシステムを使用します。

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