今日は、プロジェクトの「低レベル」の構成要素である悪魔についてお話します。
ウィキペディアの定義:「
デーモンはUNIXクラスのシステムのコンピュータープログラムであり、システム自体によって起動され、ユーザーが直接操作することなくバックグラウンドで実行されます。」
これは明らかではありませんが、サイトのほとんどすべての機能はこれらのプログラムの動作に大きく依存しています。 「デート」のゲーム、新しい顔の検索、注意の中心、メッセージ、ステータス、ジオロケーション、その他多くのことは、特定の悪魔に結びついています。 ですから、世界中の人々がコミュニケーションを取り、新しい友達を見つけるのを助けていると言えます。 同時に、数十人の悪魔がサイトで働き、互いにやり取りすることができます。 それらの正しい動作は非常に重要なタスクであるため、デーモンの主な機能を自動テストでカバーすることにしました。
Badooでは、特別な部門がこれを扱っています。 今日は、サイトのこの重要な部分を開発するプロセスとオートテストの実装をどのように進めているかについてお話します。 この領域は非常に具体的であり、多くの資料があります。そのため、興味のあるすべての人が理解できるように、プロセス全体の構造化されたレビューを準備しました。
VCSとしてGitを使用し、継続的な統合のためにTeamCityを使用し、JIRAはバグトラッカーとして機能します。 テストには、PHPUnitを使用します。 悪魔の開発は、サイトの他の部分と同様に、「機能-分岐」の原則に基づいて実行されます。 それが何であるかを理解するために、GitおよびJIRAでのフローの予測を検討します。
Gitフロー
Gitでの作業は図で概略的に説明できます。
masterブランチからタスクを処理するには、すべての開発が実行される別のtask_nブランチをフォークします。 次に、このブランチと、場合によっては他のいくつかのブランチが、いわゆるブランチbuild_n.nn(または単にビルド)にマージされ、それだけがすでにマスターになります。
ジラフロー
JIRAのプロセスはより複雑で、より多くのステップが含まれます。 以下の図は、主なものを示しています。
オープン->進行中オープンステータスは、タスクがあるがまだ開始されていないことを意味します。 プログラマーが作業を開始し、最初の変更をgitサーバーに送信すると(名前にtask_n、JIRAの識別子が含まれるブランチが表示されます)、いくつかのイベントが発生します。 まず、タスクのステータスが
In progressになり、次にTeamCityがこのブランチ用に個別のアセンブリを作成します。このアセンブリは、開発者の新しい「プッシュ」で毎回開始されます。 リリースエンジニアと開発者の努力のおかげで、アセンブリのアーティファクトが開発環境のマシンにコピーされ、その後すべてのリグレッションテストが開始され、実行の結果がTeamCity Webインターフェイスに表示されます。 開発者は、タスクの作業が終了したと考えると、チケットを
レビュー中ステータスに転送します。
レビュー中ここでは、タスクが同僚によって徹底的に研究されています。 彼の視線が文句を言う何かを見つけなかった場合、チケットは
ブランチ内QAのステータスに転送されます。
ブランチqaこの段階で、タスクはテスターに落ちます。 まず第一に、彼は回帰テストの実行結果を調べます-突然、そのうちのいくつかは現在失敗しています。 この場合、2つのオプションがあります。すべてが正常であるか、新しい動作の結果であり、リグレッションテストを更新するか、デーモンが期待どおりに動作しない場合、タスクは開発者に戻ります。 テストを完了する必要がある場合は、QAエンジニアが問題を綿密に処理します。 デーモンの新しい動作をテストでカバーし、必要に応じて古いものを同時に修正します。
マージするには->ビルド中 開発者とテスターがtask_nブランチからのアセンブリが安定して動作し、予想どおりに動作すると考えると、JIRAで[
マージする ]ボタンをクリックします。 この時点で、TeamCityは開発者のブランチをbuild_n.nnブランチに「マージ」し、ビルドを開始します。 タスクは再びテスターに分類されますが、ステータスは
In Buildです。
実際には、マージでは予期しない競合が発生する可能性があります。ブランチのテスト中に、互換性のない変更がビルドに追加される可能性があります。 このような状況が発生すると、ビルドでの手動マージのためにタスクがプログラマに転送されます。 別の問題は、回帰テストの低下、または最悪の場合、デーモンを起動できないことです。 これは、ビルドブランチからタスクをロールバックし、チケットを開発者に返すことで解決されます。 ただし、問題を解決するために小さな変更が必要な場合、タスクは残り、ビルド自体にパッチが表示されます。
テストに合格し、デーモンが安定したら、QAエンジニアはタスクステータスを[
ビルド中]に設定し、開発者に戻ります。 動作が変更されたデーモンビルドは、開発環境のメインビルドになり、戦闘でテストされています。
ビルドOK->プロダクションである時点で、多くの必要な変更がビルドブランチに蓄積されるか、重要なタスクが表示され、開発者はビルドを実稼働に移行する時が来たと判断します。 [
ビルドの
終了 ]ボタンを
クリックすると、勇敢な管理者のおかげで、新しいバージョンのデーモンがサイトの実際の作業を担当するマシンで作業を開始します。 この時点で、ビルドはmasterブランチにマージされ、build_m.mmという名前の新しいビルドが作成され、そこにすべての新しい変更が適用されます。 まあ、プログラマーのチケットは
生産中ステータスに設定されます。
開発プロセス全体の2つの予測を組み合わせると、以下に示すサイクルが得られます。
開発プロセスとJIRA、TeamCity、Gitの緊密な統合の詳細については、
こちら 、
こちら 、
こちらの記事を
ご覧 ください 。
自動テスト実行
テスト対象まず、テスト対象を正確に決定しましょう。
私たちの場合、一般にプログラムは端末から始まるバイナリファイルです。 引数として、彼は自分の仕事に影響するさまざまなパラメーターを与えることができます:構成ファイル( "configs")、ポート、ログファイル、スクリプトのあるフォルダーなど。 ほとんどの場合、これは少なくとも構成であり、この場合の起動行は次のようになります。
>> daemon_name -c daemon_config
デーモンは、起動後、外部と通信するためのいくつかのポート(ソケットファイル)に接続することを想定しています。 形式は異なる場合があり、テキストまたはJSONから始まり、
protobufで
終わります。 通常、それらのいくつかはすぐにサポートされます。 また、一部のデーモンには、データをディスクに保存し、起動時にロードする機能があります。 CとC ++は主に開発に使用されますが、最近GolangとLuaが追加されました。
一般に、自動テストのパフォーマンスはいくつかの段階に分けることができます。
- テスト環境の準備。
- テストの実行と実行。
- テスト環境のクリーニング。
したがって、テストを実行します。
>> phpunit daemon_tests/test.php --option=value
テスト環境の準備 テストを開始した後、setUpBeforeClassおよびsetUpコンストラクターで定義されているコードの一部が最初に実行されます。 この段階では、環境が準備されています。最初に、起動パラメーターが読み込まれます。これについては別途説明します。次に、必要なバージョンのバイナリファイルを選択し、作業に必要な一時フォルダー、構成、さまざまなファイルを作成し、必要に応じてデータベースを準備します。 作成されたすべてのオブジェクトには、名前に一意の識別子が含まれています。この識別子は、コンストラクターで一度選択され、すべての場所で使用されます。 これにより、複数の開発者とテスターで同時にテストを実行する際の競合を回避できます。
仕事中に悪魔が他の悪魔と通信することはよくあります。データを送受信したり、親族からコマンドを送受信したりできます。 この場合、テストスタブ(「moki」)を使用するか、実際のデーモンを実行します。 必要なものがすべて作成されると、設定でデーモンインスタンスが起動され、環境で動作します。
覚えている、私はデーモンがポート上の接続を待っていると言った? 最後のステップは、それらへの接続を作成し、悪魔のコミュニケーションの準備を確認することです。 すべてが順調であれば、テストは直接実行されます。
起動と実行ほとんどのテストは、アルゴリズムによって説明できます。
送信要求は、特定の状態に至る1つ以上の要求である場合があります。
応答を
取得する内部のアクション-
応答の受信、データベース内のレコードの読み取り、ファイルの読み取り。 一方、
アサートとは、さまざまなアクションを意味します。応答の検証、デーモンの状態の評価、近隣のデーモンに送られたデータの確認、データベース内のレコードの比較、正しいデータでのスナップショットの作成の確認などです。
しかし、私たちのテストは上記のアルゴリズムに限定されるものではありません。可能な限り、実験対象の生活のさまざまな側面をカバーするように努めています。 そのため、偶発的なトラブルが発生する可能性があります:何度か再起動したり、リクエストのデータが切り捨てられたり、誤った情報が含まれたり、無効な設定が設定に追加されたり、デーモンの対話者が応答しないか、不思議なことに消えてしまうことがあります。
現時点では、(私の意見では)最も困難で興味深いのは、プログラム間相互作用「悪魔-悪魔」をテストする分野です。 これは主に、通信プロセスが内部ロジック、外部リクエスト、時間、設定の設定など、多くの要因に依存するという事実によるものです。 オブジェクトが複数の異なるデーモンと通信できるようになると、非常に楽しくなります。
テスト環境のクリーニングテストがどのように終了したとしても、自分で掃除する必要があります。 まず、接続を閉じ、悪魔と関連するすべてのモックまたは隣接する悪魔を停止します。 次に、テスト中に作成されたすべてのファイルとフォルダーが不要な場合は削除され、データベースが消去されます。
ここでの問題は、致命的なエラーの後のクリーニングです-場合によっては、一時ファイルが残る場合があります(デーモンが動作し続けることもあります)。
特定の機能は、説明されているテストプロセス全体に重ねられます-異なるマシンへの配布。 現在の通常のシナリオは、あるサーバーでテストを実行し、別のサーバーでデーモンを起動することです。 まあ、またはdockerコンテナ内の別のサーバー上。
テスト実行パラメーターに戻りましょう。 現在、このリストは5〜6個のオプションで構成されており、常に増え続けています。 それらはすべて、テストプロセスを促進し、コードに入らずにテストを少し「カスタマイズ」する機会を提供することを目的としています。 ここに私たちのトップがあります:
- ブランチ これはJIRAのチケットの名前で、デーモンに関する作業が含まれています。 テストでは、この特定のタスクにバイナリファイルアセンブリを使用します。
- 設定 ここでは、iniファイルへのパスが渡されます。ここには、テストに固有のものが登録されます。 これは、ビルドのバージョン、デフォルト構成へのパス、デーモンの起動元のユーザー、必要なファイルの場所などです。
- デバッグ このフラグが渡されると、テストはデバッグモードで動作します。 私たちにとって、これは、一時ファイルとフォルダーの名前が読み取り可能であることを意味します。これにより、一時ファイルとフォルダーを区別しやすくなります。 また、テスト実行中に作成されたすべてのファイルは削除されません-これにより、必要に応じて落下テストをプレイできます。
- スクリプト 。 このフラグが存在する場合、テストの実行中に、テストが完了するかアサーションがトリガーされるまでテストのすべてのアクションを繰り返すphpスクリプトが生成されます。 このスクリプトは完全に独立しており、デーモンのデバッグに役立ちます。
今日は、これが私たちが話したいことのすべてです。コメントの質問に移ります。
在庫には、テストの再生、ドキュメントの生成、テストでのdockerコンテナの使用に関するスクリプトの作成に関する記事のアイデアがあります。最も興味のあるトピックをマークしてください。
QAエンジニア、コンスタンチンカルポフ