私はJavaで書かれた古いプロジェクトの開発に取り組んでいます。LOCは1,000万を超え、さらに悪いことに、4000を超える機能テストがあります。
Hudsonによってスケジュールされたテストは、大きなコード変更のたびに狂ったように失敗しています。テストの失敗の検証-製品またはテストに問題がある場合、数か月かかります。何をテストしているかわからないため、古いテストを削除することはできません!
私たちにできることは?そのような量のレガシーテストをどのように進めるのですか?
私はJavaで書かれた古いプロジェクトの開発に取り組んでいます。LOCは1,000万を超え、さらに悪いことに、4000を超える機能テストがあります。
Hudsonによってスケジュールされたテストは、大きなコード変更のたびに狂ったように失敗しています。テストの失敗の検証-製品またはテストに問題がある場合、数か月かかります。何をテストしているかわからないため、古いテストを削除することはできません!
私たちにできることは?そのような量のレガシーテストをどのように進めるのですか?
回答:
それらを放棄します。
明らかに多くの労力を費やしたものを手放すのは難しいことを知っていますが、テストはあなたのために機能していません、彼らはあなたに反対しています。テストスイートは、システムが本来行うべきことを実行するという自信を与えることになっています。そうしないと、資産ではなく負債になります。システムまたはテストに問題があるかどうかは関係ありません。テストスイートを実行すると大量のエラーが通知される限り、その目的を果たすことはできません。
ここで必要なのは、エラーなしで実行される新しいテストスイートです。つまり、最初はほとんどカバーされず、実際にはほとんどカバーされません。システムを修正するか、時間をかけてシステムに関する何かを完全に理解するたびに、テストでその知識を調整します。時間が経つにつれて、これにより、将来構築できる新しいセーフティネットが作成されます。古くて理解されていないセーフティネットにパッチを当てることは、ほとんど価値がないタイムシンクです。
古いスイートから新しいスイートにテストを転送することを支持することさえあります。確かに、それらのいくつかは今成功するかもしれませんが、彼らは彼らがテストすることになっているものを正確にテストしているから、または単にいくつかのランダムなショットが常にターゲットに当たるからですか?明らかに、あなたが費やすことができる努力でできることとできないことについて実用的でなければなりませんが、テストスイートがその仕事をするためにきれいに実行しなければならないという原則に妥協することはできません。
行ってテストを修正します。
あなたの最大の間違いは、テストが失敗することを許可し、明らかにそれをしばらく無視したことです。あなたが持っているのは「レガシーテスト」ではありません-あなたはレガシーコードに取り組んでいます。そして、テストなしで記述されたすべてのコードはレガシーであると考えています。
テストの失敗の検証-製品またはテストに問題がある場合、数か月かかります。古いテストを削除することはできません。テストの内容がわからなかったからです。
明確な要件で作業していないため、組織にはさらに大きな問題があるようです。あなた(または他の誰か)が正しい行動を確認できないことを理解できません。
テストは貴重です。少なくとも、彼らは誰かがそれらを書くのに時間を費やすべきだと考えたことを記録しているので、おそらく彼らは誰かに何らかの価値を持っていたと思われます。運が良ければ、チームがこれまでに取り組んだすべての機能とバグの完全な記録が含まれることになります。それらを見るまで、ここでどちらが当てはまるかわかりません。
ほとんどのテストがほとんどの時間をパスした場合は、弾丸を噛んで、失敗したいくつかのテストが何をしようとしていたのかを把握し、次回の仕事がより簡単になるように修正または改善するために時間をかけるだけです。その場合、少数の失敗したテストで何をすべきかについてのアドバイスについては、各テストの意図を決定するセクションに進んでください。
一方で、今は赤のビルドに直面しているかもしれませんし、数百または数千のテストがしばらくパスしていませんでした。ジェンキンスは長い間グリーンになっていませんでした。この時点で、Jenkinsのビルドステータスは役に立たなくなり、チェックインに関する問題の重要なインジケーターは機能しなくなりました。これを修正する必要がありますが、リビングルームの混乱を片付ける間、すべての前進を止める余裕はありません。
必要な考古学を実行しながら健全性を維持し、失敗したテストからどのような値を回復できるかを判断するには、次の手順をお勧めします。
あなたの環境に応じてこれを行うことができるいくつかの方法がありますが、それらは明確に説明していないので、特定の方法を本当にお勧めすることはできません。
一部のフレームワークは、予想される障害の概念をサポートしています。もしそうなら、このカテゴリに残っているテストの数のカウントダウンが表示されるので、これは素晴らしいことです。また、いくつかのテストが予期せず合格し始めたら通知されます。
一部のフレームワークはテストグループをサポートしており、Hudsonにテストの一部のみを実行するように指示したり、テストのグループをスキップしたりすることができます。つまり、テストグループを手動で実行して、現在合格しているものがあるかどうかを確認できる場合があります。
一部のフレームワークでは、単一のテストを無視するように注釈を付けたり、マークを付けることができます。この場合、グループとしてそれらを実行することは困難ですが、それらがあなたの気を散らすのを防ぎます。
通常はビルドに含まれないソースツリーにテストを移動できます。
極端な場合、バージョン管理システムのHEADからコードを削除できますが、これにより、3番目のフェーズがいつ完了したかを認識しにくくなります。
目標は、ジェンキンスができるだけ早くグリーンになるようにすることです。そうすれば、できるだけ早く正しい方向に動き始めることができます。
コードを追加または変更するときに解決して新しいテストを追加し、すべての合格したテストが合格するようにコミットします。
テストは、最初は十分に記述されたテストではなかったなど、さまざまな理由で失敗する場合があります。しかし、Jenkinsをグリーンにしたら、そのように保つことが本当に重要です。
良いテストを書くことに慣れて、テストが失敗し始めたら大したことにしてください。
無効化されたテストを1つずつ確認します。最も頻繁に変更するモジュールに影響を与えるものから始めます。テストの目的と失敗の理由を特定します。
コードベースから意図的に削除された機能をテストしますか?その後、おそらく削除できます。
まだ誰も気付いていないバグをキャッチしていますか?テストを元に戻し、バグを修正します。
それは不当な仮定を行っていたために失敗しましたか(たとえば、ボタンテキストは常に英語であると仮定していましたが、アプリケーションを複数の言語にローカライズしました)。次に、テストを1つのことに焦点を合わせ、できる限り関係のない変更からテストを分離する方法を見つけます。
テストはアプリケーション全体に広がり、システムテストを表しますか?次に、メインのJenkinsテストスイートからそれを削除し、実行頻度の低い回帰スイートに追加します。
アプリのアーキテクチャは認識されないほど変更されたので、テストでは何も役に立たなくなりましたか?消して。
テストは、コードカバレッジ統計を人為的に増やすために追加されましたが、実際には、コードが正しくコンパイルされ、無限ループに陥らないことを確認するだけです。または、テストは、選択したモックフレームワークが指定した結果を返すことを確認するだけです。消して。
この結果、一部のテストは有効になり、一部は変更され、一部は独立した複数のバイトサイズのチャンクに分割され、一部は削除されます。あなたがまだ新しい要件で進歩を遂げている限り、このような技術的負債に対処するための少しの時間を確保することは責任があります。
4000テストは難題です。40回のテストの方が扱いやすいです。管理可能な数のテストをランダムに選択して、実行および分析します。結果を次のように分類します。
多くのテストが最初のカテゴリに該当する場合は、現在のテストスイートを破棄し、現在のコードに役立つテストスイートを作成するときが来るかもしれません。
コードの問題を知らせる方法で多くのテストが失敗した場合、失敗したテストを修正して問題を解決する必要があります。1つまたは2つのバグを修正すると、多数のテストが実行される場合があります。
この文が正しい場合、
テストは...コードが大きく変更されるたびに狂って失敗します。
つまり、「より大きなコード変更」の直前にコードにロールバックすると、テストの多くが再びパスすることを意味します。それを行った後、変更の小さなチャンクを取得し、どのテストが新たに失敗しているかを確認します。これにより、どのコード変更がどのテストの失敗を引き起こしているのかをより適切に特定できます。各テストについて、問題を特定したら、新しいコードに欠陥があるか、テストに欠陥があるかを判断できるはずです。新しいコードに問題がある場合は、特定のバグがすでに修正されている場合に備えて、最新バージョンと比較してください。
最新のコードベースが得られるまで繰り返します。
これは圧倒的な作業のように思えるかもしれませんが、この経路をたどって問題のいくつかを特定し始めると、プロセスが大幅にスピードアップするパターンが出現し始める可能性が非常に高くなります。例えば:
それらが何をテストしているのかわからない場合は、わかるまで削除してください。テストは流動的なものです。不要になった機能を削除した場合、その機能をテストするテストを変更する必要があります。そのため、テストが何をテストしているのかを知らない限り、それらを使用してコードベースを変更する見込みはありません。
開発者のマシンにテストシステムをセットアップして実行すると、開発者はテストがどの部分とやり取りしているのかを確認し、不足しているこのドキュメントを提供し、正しく変更されていないか、またはより正確にテストします。
つまり、変更時に古いテストが失敗する場合、コードの変更は適切ではありません。これらのテストは、システムがどのように機能するかを教育する手段として使用してください。
@Ignore
注釈を好む理由です。テストを保持することはできますが、実行することはできません。次に、それらを再度有効にして、一度に1つずつ修正するだけです。これにより、数千の失敗に圧倒されるのではなく、一度に少数のテストに焦点を絞ることができます。
私がする最も重要なことは、テストが何をするべきか、そしてビジネスが動き続けるために必要なものの基本に戻ることです。テストの仕事は、後で修正するのに費用がかかる前に問題を特定することです。その文のキーワードは「高価」だと思います。これらの問題にはビジネスソリューションが必要です。高価な問題が現場に現れていますか?その場合、テストは完全に失敗しています。
あなたの管理者とあなたは現実チェックに来る必要があります。テストのレガシーセットにより、開発コストが急騰していることがわかります。テストを無効にしたため、これらのコストは、不良製品を提供するコストと比較してどうですか?ユーザーが必要とする動作(テストする必要のあるもの)を実際に把握するという面倒なタスクと比較してどうでしょうか。
これらは、仕事のビジネス側に影響を与えるため、ビジネスソリューションを必要とする問題です。あなたは製品を顧客に提供していますが、それはビジネスが非常に興味を持っている境界です。彼らは開発者としてはできないソリューションを特定できるかもしれません。たとえば、2つの製品を提供するのが合理的である場合があります。1つは信頼性を必要とし、新機能を控える「レガシー」製品で、もう1つはより多くの欠点があるが先駆的な「ビジョン」製品です。これにより、2つの独立したテストセットを開発する機会が得られます。1つは4000テスト、もう1つは実行する必要があると思われるテスト(さらに、このプロセスが繰り返されないように文書化する)です。
それから、芸術が始まります:ある枝の進歩が他の枝にも役立つように、この双頭の獣をどのように管理できますか?厳格なテスト要件にもかかわらず、「visonary」ブランチへの更新を「legacy」ブランチに戻すにはどうすればよいですか。「レガシー」ブランチでの継続的な顧客の要求は、最終的に製品を再マージした場合にレガシー顧客が必要とする要件についての理解をどのように改善することができますか?