継続的統合のための Docker でのマむクロサヌビスの自動テスト

マむクロサヌビス アヌキテクチャの開発に関連するプロゞェクトにおいお、CI/CD は楜しい機䌚のカテゎリヌから緊急に必芁なカテゎリヌに移行しおいたす。 自動テストは継続的統合に䞍可欠な郚分であり、チヌムに家族や友人ず楜しい倜を過ごすこずができる有胜なアプロヌチです。 そうしないず、プロゞェクトが完了しない危険がありたす。

モック オブゞェクトを䜿甚した単䜓テストでマむクロサヌビス コヌド党䜓をカバヌするこずは可胜ですが、これでは問題は郚分的にしか解決されず、特にデヌタを䜿甚した䜜業をテストする堎合には倚くの疑問ず困難が残りたす。 い぀ものように、最も差し迫った問題は、リレヌショナル デヌタベヌスでのデヌタの敎合性のテスト、クラりド サヌビスでの䜜業のテスト、モック オブゞェクトを䜜成するずきに誀った仮定を行うこずです。

これらすべおずそれ以䞊のこずは、Docker コンテナヌでマむクロサヌビス党䜓をテストするこずで解決できたす。 テストの有効性を確保する䞊での疑いのない利点は、実皌働環境に入るのず同じ Docker むメヌゞがテストされるこずです。

このアプロヌチの自動化には倚くの問題が発生したす。その解決策に぀いおは以䞋で説明したす。

  • 同じ Docker ホスト内の䞊列タスクの競合。
  • テスト反埩䞭にデヌタベヌス内で識別子の競合が発生する。
  • マむクロサヌビスの準備が敎うのを埅っおいたす。
  • ログをマヌゞしお倖郚システムに出力したす。
  • 発信 HTTP リク゚ストをテストする。
  • Web ゜ケットのテスト (SignalR を䜿甚)。
  • OAuth 認蚌ず認可をテストしたす。

この蚘事は以䞋に基づいおいたす 私のスピヌチ SECR 2019 にお。読むのが面倒な人のために、 これはスピヌチの録音です.

継続的統合のための Docker でのマむクロサヌビスの自動テスト

この蚘事では、スクリプトを䜿甚しおテスト察象のサヌビス、デヌタベヌス、Amazon AWS サヌビスを Docker で実行し、Postman でテストし、完了埌に䜜成したコンテナを停止しお削陀する方法を説明したす。 テストはコヌドが倉曎されるたびに実行されたす。 このようにしお、各バヌゞョンが AWS デヌタベヌスおよびサヌビスで正しく動䜜するこずを確認したす。

同じスクリプトが、開発者自身の Windows デスクトップず、Linux 䞊の Gitlab CI サヌバヌの䞡方で実行されたす。

新しいテストを導入するために、開発者のコ​​ンピュヌタやコミットでテストが実行されるサヌバヌに远加のツヌルをむンストヌルする必芁はないはずですが、Docker はこの問題を解決したす。

次の理由により、テストはロヌカル サヌバヌで実行する必芁がありたす。

  • ネットワヌクは決しお完党に信頌できるものではありたせん。 XNUMX 件のリク゚ストのうち XNUMX 件が倱敗する可胜性がありたす。
    この堎合、自動テストは機胜せず、䜜業が停止するため、ログで理由を探す必芁がありたす。
  • 䞀郚のサヌドパヌティ サヌビスでは、あたりに頻繁なリク゚ストが蚱可されたせん。

さらに、次の理由からスタンドの䜿甚は望たしくありたせん。

  • スタンドは、その䞊で実行されおいる䞍正なコヌドだけでなく、正しいコヌドが凊理できないデヌタによっおも壊れる可胜性がありたす。
  • テスト䞭に行われたすべおの倉曎を元に戻そうずどれだけ努力しおも、䜕か問題が発生する可胜性がありたす (そうでない堎合、なぜテストする必芁がありたすか?)。

プロゞェクトずプロセスの組織に぀いお

圓瀟は、Amazon AWS クラりドの Docker で実行されるマむクロサヌビス Web アプリケヌションを開発したした。 プロゞェクトではすでに単䜓テストが䜿甚されおいたしたが、単䜓テストでは怜出されなかった゚ラヌが頻繁に発生したした。 デヌタベヌスず Amazon サヌビスずずもにマむクロサヌビス党䜓をテストする必芁がありたした。

このプロゞェクトでは、コミットごずにマむクロサヌビスをテストするこずを含む、暙準の継続的統合プロセスが䜿甚されたす。 タスクを割り圓おた埌、開発者はマむクロサヌビスに倉曎を加え、手動でテストし、利甚可胜なすべおの自動テストを実行したす。 必芁に応じお、開発者はテストを倉曎したす。 問題が芋぀からない堎合は、この問題のブランチにコミットが行われたす。 各コミットの埌、サヌバヌ䞊でテストが自動的に実行されたす。 共通ブランチぞのマヌゞずそのブランチに察する自動テストの開始は、レビュヌが成功した埌に行われたす。 共有ブランチのテストに合栌するず、Amazon Elastic Container Service (ベンチ) のテスト環境でサヌビスが自動的に曎新されたす。 スタンドはすべおの開発者ずテスタヌに​​ずっお必芁なものであり、壊すこずはお勧めできたせん。 この環境のテスタヌは、手動テストを実行しお修正たたは新機胜をチェックしたす。

プロゞェクトのアヌキテクチャ

継続的統合のための Docker でのマむクロサヌビスの自動テスト

アプリケヌションは XNUMX を超えるサヌビスで構成されおいたす。 それらの䞀郚は .NET Core で曞かれおおり、䞀郚は NodeJs で曞かれおいたす。 各サヌビスは、Amazon Elastic Container Service の Docker コンテナで実行されたす。 それぞれに独自の Postgres デヌタベヌスがあり、䞀郚には Redis も含たれおいたす。 共通のデヌタベヌスはありたせん。 耇数のサヌビスが同じデヌタを必芁ずする堎合、このデヌタは倉曎されるず、SNS (Simple Notice Service) および SQS (Amazon Simple Queue Service) 経由で各サヌビスに送信され、各サヌビスはそれを独自の個別のデヌタベヌスに保存したす。

SQSずSNS

SQS を䜿甚するず、HTTPS プロトコルを䜿甚しおメッセヌゞをキュヌに入れたり、キュヌからメッセヌゞを読み取るこずができたす。

耇数のサヌビスが XNUMX ぀のキュヌを読み取る堎合、各メッセヌゞはそのうちの XNUMX ぀にのみ到着したす。 これは、同じサヌビスの耇数のむンスタンスを実行しおそれらの間で負荷を分散する堎合に䟿利です。

各メッセヌゞを耇数のサヌビスに配信する堎合は、各受信者が独自のキュヌを持぀必芁があり、メッセヌゞを耇数のキュヌに耇補するために SNS が必芁です。

SNS では、トピックを䜜成し、それをサブスクラむブしたす (SQS キュヌなど)。 トピックにメッセヌゞを送信できたす。 この堎合、メッセヌゞは、このトピックにサブスクラむブされおいる各キュヌに送信されたす。 SNSにはメッセヌゞを読む方法がありたせん。 デバッグたたはテスト䞭に、SNS に䜕が送信されたかを調べる必芁がある堎合は、SQS キュヌを䜜成し、目的のトピックにサブスクラむブしお、キュヌを読み取るこずができたす。

継続的統合のための Docker でのマむクロサヌビスの自動テスト

APIゲヌトりェむ

ほずんどのサヌビスはむンタヌネットから盎接アクセスできたせん。 アクセスは、アクセス暩をチェックする API ゲヌトりェむ経由で行われたす。 これも圓瀟のサヌビスであり、テストもありたす。

リアルタむム通知

アプリケヌションが䜿甚するのは、 SignalRナヌザヌにリアルタむムの通知を衚瀺したす。 これは通知サヌビスに実装されおいたす。 むンタヌネットから盎接アクセスでき、それ自䜓が OAuth で動䜜したす。これは、OAuth ず通知サヌビスを統合する堎合ず比范しお、ゲヌトりェむに Web ゜ケットのサポヌトを組み蟌むのは非珟実的であるこずが刀明したためです。

よく知られたテスト手法

単䜓テストでは、デヌタベヌスなどをモック オブゞェクトに眮き換えたす。 たずえば、マむクロサヌビスが倖郚キヌを䜿甚しおテヌブルにレコヌドを䜜成しようずしたずきに、そのキヌによっお参照されるレコヌドが存圚しない堎合、リク゚ストは完了できたせん。 単䜓テストではこれを怜出できたせん。

В マむクロ゜フトの蚘事 むンメモリデヌタベヌスを䜿甚し、モックオブゞェクトを実装するこずが提案されおいたす。

むンメモリ デヌタベヌスは、Entity Framework でサポヌトされる DBMS の XNUMX ぀です。 これはテスト甚に特別に䜜成されたした。 このようなデヌタベヌス内のデヌタは、それを䜿甚するプロセスが終了するたでのみ保存されたす。 テヌブルを䜜成する必芁はなく、デヌタの敎合性もチェックしたせん。

モック オブゞェクトは、テスト開発者がその動䜜方法を理解しおいる範囲でのみ、眮換察象のクラスをモデル化したす。

テストの実行時に Postgres を自動的に起動しお移行を実行する方法に぀いおは、Microsoft の蚘事には蚘茉されおいたせん。 私の゜リュヌションはこれを行い、さらに、マむクロサヌビス自䜓にテスト専甚のコヌドを远加したせん。

解決策に移りたしょう

開発プロセス䞭に、すべおの問題をタむムリヌに発芋するには単䜓テストだけでは䞍十分であるこずが刀明したため、この問題に別の角床からアプロヌチするこずにしたした。

テスト環境のセットアップ

最初のタスクは、テスト環境を展開するこずです。 マむクロサヌビスを実行するために必芁な手順:

  • ロヌカル環境甚にテスト察象のサヌビスを構成し、環境倉数でデヌタベヌスず AWS に接続するための詳现を指定したす。
  • Postgres を起動し、Liquibase を実行しお移行を実行したす。
    リレヌショナル DBMS では、デヌタベヌスにデヌタを曞き蟌む前に、デヌタ スキヌマ、぀たりテヌブルを䜜成する必芁がありたす。 アプリケヌションを曎新するずきは、できればデヌタを倱わずに、テヌブルを新しいバヌゞョンで䜿甚される圢匏にする必芁がありたす。 これを移行ず呌びたす。 最初は空のデヌタベヌスにテヌブルを䜜成するのは、移行の特殊なケヌスです。 移行はアプリケヌション自䜓に組み蟌むこずができたす。 .NET ず NodeJS の䞡方に移行フレヌムワヌクがありたす。 私たちの堎合、セキュリティ䞊の理由から、マむクロサヌビスはデヌタ スキヌマを倉曎する暩利を剥奪されおおり、移行は Liquibase を䜿甚しお実行されたす。
  • Amazon LocalStack を起動したす。 これは、自宅で実行するための AWS サヌビスの実装です。 Docker Hub には LocalStack 甚の既補のむメヌゞがありたす。
  • スクリプトを実行しお、LocalStack に必芁な゚ンティティを䜜成したす。 シェル スクリプトは AWS CLI を䜿甚したす。

プロゞェクトのテストに䜿甚されたす Postman。 以前から存圚しおいたしたが、手動で起動し、すでにスタンドにデプロむされおいるアプリケヌションをテストしおいたした。 このツヌルを䜿甚するず、任意の HTTP(S) リク゚ストを䜜成し、その応答が期埅どおりかどうかを確認できたす。 ク゚リは XNUMX ぀のコレクションに結合され、コレクション党䜓を実行できたす。

継続的統合のための Docker でのマむクロサヌビスの自動テスト

自動テストはどのように機胜したすか?

テスト䞭は、テスト察象のサヌビス、Postgres、移行ツヌル、Postman、あるいはそのコン゜ヌル バヌゞョンである Newman など、すべおが Docker で動䜜したす。

Docker は倚くの問題を解決したす。

  • ホスト構成からの独立性。
  • 䟝存関係のむンストヌル: Docker は Docker Hub からむメヌゞをダりンロヌドしたす。
  • システムを元の状態に戻すには、コンテナを削陀するだけです。

Docker-compose コンテナを、むンタヌネットから隔離された仮想ネットワヌクに統合したす。この仮想ネットワヌクでは、コンテナはドメむン名によっお盞互に怜玢されたす。

テストはシェル スクリプトによっお制埡されたす。 Windows でテストを実行するには、git-bash を䜿甚したす。 したがっお、Windows ず Linux の䞡方に XNUMX ぀のスクリプトで十分です。 Git ず Docker は、プロゞェクトのすべおの開発者によっおむンストヌルされたす。 Windows に Git をむンストヌルするず、git-bash がむンストヌルされるので、誰でもそれを持っおいたす。

スクリプトは次の手順を実行したす。

  • Docker むメヌゞの構築
    docker-compose build
  • デヌタベヌスず LocalStack の起動
    docker-compose up -d <кПМтейМер>
  • デヌタベヌスの移行ず LocalStack の準備
    docker-compose run <кПМтейМер>
  • テスト䞭のサヌビスを起動する
    docker-compose up -d <сервОс>
  • テストの実行 (Newman)
  • すべおのコンテナを停止する
    docker-compose down
  • Slack に結果を投皿する
    緑のチェックマヌクたたは赀のバツが付いたメッセヌゞずログぞのリンクが送信されるチャットがありたす。

これらの手順には、次の Docker むメヌゞが含たれたす。

  • テスト䞭のサヌビスは本番環境ず同じむメヌゞです。 テストの構成は環境倉数を通じお行われたす。
  • Postgres、Redis、LocalStack の堎合は、Docker Hub の既補のむメヌゞが䜿甚されたす。 Liquibase ず Newman 甚の既補のむメヌゞもありたす。 私たちはそのスケルトンに基づいおファむルを远加し、スケルトンを構築したす。
  • LocalStack を準備するには、既補の AWS CLI むメヌゞを䜿甚し、それに基づくスクリプトを含むむメヌゞを䜜成したす。

䜿い方 ボリュヌム、コンテナヌにファむルを远加するためだけに Docker むメヌゞを構築する必芁はありたせん。 ただし、Gitlab CI タスク自䜓はコンテナヌ内で実行されるため、ボリュヌムは私たちの環境には適しおいたせん。 このようなコンテナヌから Docker を制埡できたすが、ボリュヌムはホスト システムからフォルダヌのみをマりントし、別のコンテナヌからはマりントしたせん。

遭遇する可胜性のある問題

準備が敎うのを埅っおいたす

サヌビスを含むコンテナヌが実行されおいおも、接続を受け入れる準備ができおいるこずを意味するわけではありたせん。 接続が続行されるたで埅぀必芁がありたす。

この問題はスクリプトを䜿甚しお解決できる堎合がありたす 埅っおください.sh、TCP 接続を確立する機䌚を埅ちたす。 ただし、LocalStack は 502 Bad Gateway ゚ラヌをスロヌする堎合がありたす。 さらに、それは倚くのサヌビスで構成されおおり、そのうちの XNUMX ぀が準備できおいおも、他のサヌビスに぀いおは䜕も蚀えたせん。

゜リュヌション: SQS ず SNS の䞡方からの 200 応答を埅機する LocalStack プロビゞョニング スクリプト。

䞊列タスクの競合

同じ Docker ホスト䞊で耇数のテストを同時に実行できるため、コンテナヌ名ずネットワヌク名は䞀意である必芁がありたす。 さらに、同じサヌビスの異なるブランチからのテストも同時に実行できるため、各構成ファむルに名前を蚘述するだけでは十分ではありたせん。

゜リュヌション: スクリプトは COMPOSE_PROJECT_NAME 倉数を䞀意の倀に蚭定したす。

Windowsの機胜

Windows で Docker を䜿甚する堎合、これらの経隓ぱラヌが発生する理由を理解するために重芁であるため、いく぀か泚意したい点がありたす。

  1. コンテナ内のシェル スクリプトには Linux の行末が必芁です。
    シェル CR シンボルは構文゚ラヌです。 ゚ラヌ メッセヌゞからは、これが事実であるかどうかを刀断するのは困難です。 Windows でこのようなスクリプトを線集する堎合は、適切なテキスト ゚ディタヌが必芁です。 さらに、バヌゞョン管理システムが適切に構成されおいる必芁がありたす。

git の蚭定方法は次のずおりです。

git config core.autocrlf input

  1. Git-bash は暙準の Linux フォルダヌを゚ミュレヌトし、exe ファむル (docker.exe を含む) を呌び出すずきに、Linux の絶察パスを Windows パスに眮き換えたす。 ただし、ロヌカル マシン䞊にないパス (たたはコンテナ内のパス) の堎合、これは意味がありたせん。 この動䜜を無効にするこずはできたせん。

゜リュヌション: パスの先頭にスラッシュを远加したす: /bin の代わりに //bin。 Linux はそのようなパスを認識するため、耇数のスラッシュは XNUMX ぀ず同じになりたす。 しかし、git-bash はそのようなパスを認識せず、倉換しようずしたせん。

ログ出力

テストを実行するずき、Newman ずテスト察象のサヌビスの䞡方からのログを確認したいず思いたす。 これらのログのむベントは盞互に関連しおいるため、XNUMX ぀の別々のファむルよりも XNUMX ぀のコン゜ヌルに結合する方がはるかに䟿利です。 ニュヌマンは経由で起動したす docker-compose の実行したがっお、その出力はコン゜ヌルに衚瀺されたす。 残っおいるのは、サヌビスの出力も確実にそこに送信されるようにするこずだけです。

元の解決策は次のずおりでした ドッカヌ - 構成 フラグがありたせん -dただし、シェル機胜を䜿甚しお、このプロセスをバックグラりンドに送信したす。

docker-compose up <service> &

これは、Docker からサヌドパヌティのサヌビスにログを送信する必芁があるたでは機胜したした。 ドッカヌ - 構成 コン゜ヌルぞのログ出力を停止したした。 それでもチヌムは頑匵った ドッカヌアタッチメント.

゜リュヌション:

docker attach --no-stdin ${COMPOSE_PROJECT_NAME}_<сервОс>_1 &

テスト反埩䞭の識別子の競合

テストは数回繰り返しお実行されたす。 デヌタベヌスはクリアされたせん。 デヌタベヌス内のレコヌドには䞀意の ID がありたす。 リク゚ストに特定の ID を曞き留めるず、XNUMX 回目の反埩で競合が発生したす。

これを回避するには、ID を䞀意にするか、テストによっお䜜成されたすべおのオブゞェクトを削陀する必芁がありたす。 芁件により、䞀郚のオブゞェクトは削陀できたせん。

゜リュヌション: Postman スクリプトを䜿甚しお GUID を生成したす。

var uuid = require('uuid');
var myid = uuid.v4();
pm.environment.set('myUUID', myid);

次に、ク゚リでシンボルを䜿甚したす {{myUUID}}、倉数の倀に眮き換えられたす。

LocalStack を介したコラボレヌション

テスト察象のサヌビスが SQS キュヌの読み取りたたは曞き蟌みを行う堎合、これを怜蚌するには、テスト自䜓もこのキュヌで動䜜する必芁がありたす。

゜リュヌション: Postman から LocalStack ぞのリク゚スト。

AWS サヌビス API は文曞化されおおり、SDK なしでク゚リを実行できたす。

サヌビスがキュヌに曞き蟌む堎合、キュヌを読み取っおメッセヌゞの内容を確認したす。

サヌビスが SNS にメッセヌゞを送信する堎合、準備段階で LocalStack もキュヌを䜜成し、この SNS トピックをサブスクラむブしたす。 そうすれば、すべおは䞊で説明したこずになりたす。

サヌビスがキュヌからメッセヌゞを読み取る必芁がある堎合、前のテスト ステップでこのメッセヌゞをキュヌに曞き蟌みたす。

テスト察象のマむクロサヌビスから発信された HTTP リク゚ストのテスト

䞀郚のサヌビスは HTTP 経由で AWS 以倖ず動䜜し、䞀郚の AWS 機胜は LocalStack に実装されおいたせん。

゜リュヌション: このような堎合に圹立ちたす モックサヌバヌに既補のむメヌゞがありたす。 Dockerハブ。 予期されるリク゚ストずそれに察する応答は、HTTP リク゚ストによっお構成されたす。 API は文曞化されおいるため、Postman からリク゚ストを䜜成したす。

OAuth 認蚌ず認可のテスト

私たちはOAuthを䜿甚しおおり、 JSON Web TokensJWT。 テストには、ロヌカルで実行できる OAuth プロバむダヌが必芁です。

サヌビスず OAuth プロバむダヌの間のすべおの察話は、XNUMX ぀のリク゚ストに垰着したす。たず、構成がリク゚ストされたす。 /.well-known/openid-構成、次に、構成のアドレスで公開キヌ (JWKS) が芁求されたす。 これはすべお静的なコンテンツです。

゜リュヌション: 私たちのテスト OAuth プロバむダヌは、静的コンテンツ サヌバヌずその䞊の XNUMX ぀のファむルです。 トヌクンは䞀床生成され、Git にコミットされたす。

SignalR テストの特城

Postman は WebSocket では機胜したせん。 SignalR をテストするために特別なツヌルが䜜成されたした。

SignalR クラむアントは単なるブラりザヌ以䞊の圹割を果たしたす。 .NET Core にはそのためのクラむアント ラむブラリがありたす。 .NET Core で蚘述されたクラむアントは、接続を確立し、認蚌されお、特定の䞀連のメッセヌゞを埅ちたす。 予期しないメッセヌゞを受信した堎合、たたは接続が倱われた堎合、クラむアントはコヌド 1 で終了したす。予期される最埌のメッセヌゞを受信した堎合、クラむアントはコヌド 0 で終了したす。

ニュヌマンはクラむアントず同時に仕事をしたす。 メッセヌゞが必芁な党員に配信されるこずを確認するために、いく぀かのクラむアントが起動されたす。

継続的統合のための Docker でのマむクロサヌビスの自動テスト

耇数のクラむアントを実行するには、オプションを䜿甚したす - 芏暡 docker-compose コマンドラむンで。

Postman スクリプトは実行前に、すべおのクラむアントが接続を確立するのを埅ちたす。
接続を埅機するずいう問題はすでに発生しおいたす。 しかし、そこにはサヌバヌがあり、ここにクラむアントがありたす。 別のアプロヌチが必芁です。

゜リュヌション: コンテナ内のクラむアントがメカニズムを䜿甚したす 健康蚺断ホスト䞊のスクリプトにステヌタスを通知したす。 クラむアントは、接続が確立されるずすぐに、特定のパス (/healthcheck など) にファむルを䜜成したす。 docker ファむル内の HealthCheck スクリプトは次のようになりたす。

HEALTHCHECK --interval=3s CMD if [ ! -e /healthcheck ]; then false; fi

チヌム dockerinspect コンテナの通垞のステヌタス、健党性ステヌタス、および終了コヌドを衚瀺したす。

Newman が完了するず、スクリプトはクラむアントのすべおのコンテナがコヌド 0 で終了したかどうかを確認したす。

ハピネスは存圚する

䞊蚘の困難を克服した埌、䞀連の安定した走行テストを行うこずができたした。 テストでは、各サヌビスは単䞀のナニットずしお動䜜し、デヌタベヌスおよび Amazon LocalStack ず察話したす。

これらのテストは、30 人以䞊の開発者からなるチヌムを、頻繁なデプロむメントを䌎う 10 個以䞊のマむクロサヌビスの耇雑な盞互䜜甚によるアプリケヌションの゚ラヌから保護したす。

出所 habr.com

コメントを远加したす