テスト戦略の進化-猿にならない

画像



この一連の記事では、過去数年にわたって作成したNielsen Marketing Cloud Webアプリケーションの完全自動テスト戦略(QAなし)の作成における経験について説明したいと思います。



Nielsen Marketing Cloud開発センターでは、新しい機能とリグレッションの両方を手動でテストすることなく作業しています。 そしてこれは私達に多くの利点を与えます:





長期的には、優れたテスト自動化により品質が向上し、古い機能の回帰の数が減少します。



しかし、ここで100万ドルの疑問が生じます-テストを効果的に自動化する方法は?



パート1-それをしない方法



ほとんどの開発者は「自動化されたテスト」を聞くと、「ユーザーの行動の自動化」(Seleniumを使用したエンドツーエンドのテスト)を考えますが、このルールも例外ではありません。



もちろん、単体テストと統合テストの重要性については知っていましたが、「システムに入り、ボタンを押して、システムのすべての部分を一緒にチェックしましょう」は、自動化のかなり論理的な最初のステップのように思えました。



最後に、決定が下されました-Seleniumを使用して一連のエンドツーエンドテストを作成しましょう。

それは良いアイデアのように思えた。 しかし、最終的に私たちが思いついた結果はそれほど喜ばしいものではありませんでした。 発生した問題は次のとおりです。



1.不安定なテスト



ある時点で、かなりの数のエンドツーエンドテストを記述したときに、それらは落ち始めました。 そして、滝は永久的ではありませんでした。



画像



テストが誤って失敗した理由がわからない場合、開発者は何をしますか? そうです-彼らは睡眠を追加します。



これは、ある場所で300ミリ秒、別の場所で1秒間、次に3秒間のスリープの追加から始まります。



ある時点で、テストでは次のようになります。

sleep(60000)//アクションが完了するのを待つ
なぜ睡眠を追加するのが悪い考えなのかは明白だと思いますか?*



*まったく同じ場合、スリープがないとテストが遅くなり、一定です。つまり、何かがうまくいかず、一部の操作が計画よりも長くかかる場合、テストは失敗します。つまり、テストは不安定であり、決定論的。



2.テストが遅い



自動化されたエンドツーエンドのテストでは、実際のサーバーとデータベースを使用して実際のシステムをテストするため、このようなテストの実行はかなり遅いプロセスです。



動作が遅い場合、開発者は通常それを回避するため、ローカル環境で誰もテストを実行せず、CIがグリーンになることを期待してコードがバージョン管理システムにプッシュされます。 しかし、これはそうではありません。 CIは赤です。 そして、開発者はすでに家に帰っています。 そして...



3.テストの失敗は有益ではありません



エンドツーエンドテストの最大の問題の1つは、テストに問題がある場合、問題の内容を理解できないことです。



そして問題は、それが心地よい場所であるかもしれません:環境(システムのすべての部分が方程式の一部であることを思い出してください)、構成、サーバー、フロントエンド、データ、または単に安定したテストではありません(十分なスリープではありません)。



そして、あなたが見る唯一のもの:







その結果、実際に何がうまくいかなかったかの定義には多くの時間がかかり、すぐに気になり始めます。



4.テスト用データ



すべてのレイヤーをまとめてシステム全体をテストするため、複雑なスクリプトをシミュレートしたり作成したりすることが非常に難しい場合があります。 たとえば、サーバーにアクセスできない場合やデータベース内のデータが破損した場合にユーザーインターフェイスがどのように反応するかを確認したい場合、これは決して簡単な作業ではないため、ほとんどの開発者は抵抗が最も少ないパスに進み、肯定的なシナリオのみをテストします。 また、問題が発生した場合にシステムがどのように動作するかは誰にもわかりません(そして確実に発生します)。



しかし、これは単なる例であり、ボタンを非アクティブにする必要がある特定のシナリオをチェックアウトする必要がある場合が多く、この特定のシナリオ用のユニバース全体を構築するには多大な労力が必要です。 そしてこれは、次のテストのためにゴミを残さないように、テスト後にデータをクリアすることは言うまでもありません。



5.動的ユーザーインターフェイス



ファッショナブルなシングルページ(SPA)アプリケーションでは、ユーザーインターフェイスは非常に動的であり、要素が表示されたり消えたり、アニメーションが要素を非表示にしたり、ポップアップウィンドウが表示されたり、他の部分のデータに応じて画面の一部が非同期に変化したりします。



ほとんどの場合、アクションが成功したことを意味する条件を定義することは非常に難しいため、これによりスクリプトの自動化が非常に難しくなります。







6.独自のフレームワークを構築しましょう



ある時点で、ユーザーインターフェイスのさまざまな部分が同じ要素(検索、フィルタリング、テーブルなど)を使用するため、テストがほぼ繰り返し行われていることに気付き始めました。



テストコードを実際にコピーアンドペーストしたくなかったため、他のスクリプトで使用できる汎用スクリプトを使用して独自のテストフレームワークの構築を開始しました。



その後、いくつかの要素はさまざまな方法で使用したり、さまざまなデータを使用したりできることがわかりました。 そのため、一般化されたパーツは、構成、継承、工場、その他の設計パターンに成長し始めました。



最終的に、テストコードは非常に複雑になり、この魔法がどのように機能するかを理解したのはチームの数人だけでした。



まとめ



もちろん、一部の問題は部分的に解決できます(テストの並行実行、テストの失敗時にスクリーンショットの取得など)が、結果として、このエンドツーエンドテストのセットは非常に問題が多く、複雑で、サポートに費用がかかります。



さらに、ある時点で、非常に多くの誤ったクラッシュと安定性の問題が発生したため、開発者は単に赤いテストを真剣に受け止めました。 そして、これはテストをまったく行わないよりもさらに悪いことです!



その結果、次のことができます。





最終結果は、「 アイスクリームコーンのアンチパターン 」として知られています。







一般的に、エンドツーエンドのテストの数を大幅に減らし、代わりにもっとクールなものを使用することにしました。 しかし、それについては、ストーリーの次の部分で詳しく説明します。



All Articles