【Squishノウハウ】DockerコンテナでSquishテストを実行する

ソフトウェアテストプロジェクトは、再現性のある結果をもたらす、しっかりと定義されたテスト環境から大きな恩恵を受けます。Squishを使用したGUIテストの自動化もその例外ではありません。Dockerコンテナはこのような環境を定義するための素晴らしい方法ですが、それだけではありません。Dockerの上にGUIテスト自動化セットアップを実装することで、テスト実行の並列化やDocker SwarmやKubernetesを使った複数のコンピュータへのテスト実行の分散も簡単にできるようになります。Dockerを使ったテストに関する記事はネット上に溢れており、「これは単なる誇大広告なのか、それとも本当に目に見えるメリットがあるのか」と疑問に感じている方もいらっしゃるかもしれません。

DockerコンテナとGUIテスト自動化

Dockerがソフトウェアの配布と実行に関する考え方に影響を与えたという話はよく聞きますが、それは単なる一時的な流行ではありません。特に、Dockerコンテナは、GUIテスト自動化に大きく関連する2つの特性を備えています:

  1. Dockerコンテナは、システムの他の部分から隔離されています。しかし、従来の仮想マシンとは異なり、瞬時に起動・停止することができます。そのため、すべてのテストをクリーンで管理された環境で開始することが可能です。
  2. Dockerコンテナは、完全に自己完結させることができます。さらに、Dockerイメージ(コンテナの起動元となるテンプレート)は、異なるコンピュータに簡単に移動することができます。そのため、テストの実行を複数のホストに分散させることで、テストのサイクルタイムを短縮することが非常に簡単に実現できます。

この記事では、DockerコンテナでSquish GUIテストを立ち上げて実行する方法の基本的な例をご紹介します。このユースケースを最大限に活用するためには、Dockerの基本的な(しかし決して広範ではない)理解が非常に有益です。もし不明点があれば、Dockerの公式ウェブページにある、Dockerの概要(英語)をご確認ください。

テスト用のコンテナの中身

Dockerコンテナは、Dockerイメージのインスタンスです。したがって、テストを実行できるコンテナを作成するには、まず適切なDockerイメージとはどのようなものかを考案する必要があります。

デモンストレーションのため、以下のように仮定します。

  • Linux上で動作するアプリケーションをテストしたい。
  • あなたはすでに、アプリケーション(およびそのすべての依存関係)を含むLinuxベースのDockerイメージを持っている。

多くの場合、複雑なアプリケーションは、それぞれが単一のアプリケーションを実行する複数のDockerコンテナを組み合わせることによって構築されます。例えば、Webサーバー用のコンテナとデータベース用のコンテナを別々に用意するような場合です。コンテナ間の通信は、ネットワーク接続を介して行われます。

ピクセル座標を手掛かりにしてGUIを操作するのではなく、Squishはアプリケーションのオブジェクト階層を深く理解しており、検証やオブジェクトの特定に使用できるプロパティも備えています。緊密な統合を実現するために、SquishはAUT(テスト対象のアプリケーション)と同じコンテナで実行される必要があります。

したがって、あるコンテナでAUTを実行し、別のコンテナでSquishを実行するのではなく、アプリケーションと、GUIテストの実行に必要なすべてのコンポーネントを含む単一のDockerイメージを作成する必要があります。このイメージは、AUTを含む既存のDockerイメージをベースにして、それを拡張することになります。

特に、テスト用のDockerイメージには、以下の要素が必要になります。

  • アプリケーションのユーザーインターフェイスを表示するために、グラフィカルディスプレイをエミュレートするプログラム: Xvfb(英語wiki)
  • Squishのインストールフォルダ(ライセンスキーを含む)
  • AUTに対して実行するテストスクリプト

厳密には、テストスクリプトはDockerイメージの一部である必要はありません。ファイルシステムのパスをコンテナにマッピングすることで、実行時にコンテナにロードすることも可能でしょう。実際、テストスクリプトのサイズがかなり大きい場合(スクリーンショットが多い場合など)には、この方法が有効かもしれません。しかし、テストスクリプトをDockerイメージにパッケージ化することには、2つの重要な利点があります:

  1. Dockerイメージは自己完結型となり、Dockerランタイムを実行できるコンピュータであれば、Squishテストの実行に使用することができます。
  2. 特定のアプリケーションのビルドに対応するテストスクリプトが同じコンテナに常に利用可能な状態となります。異なるAUTビルド(例えば、アプリケーションの異なるバージョン)は、異なる機能を有している可能性があるため、異なる、より広範囲なテストスイートを必要とする可能性があります。

このプロセス全体は、通常、継続的インテグレーションパイプラインの一部として、自動的に行われることが想定されます。

Dockerイメージのビルド

Dockerイメージのビルドには、以下の3つのステップを踏むことが必要です:

  1. Dockerコンテキストを形成するためにDockerイメージに含めるべきすべてのファイルを1つの作業ディレクトリに集める。
  2. Dockerfileというファイルを作成し、必要なファイルをどこに置くか、どのようにDockerイメージを構成するのか(例えば、どのような追加ソフトウェアパッケージをインストールするか、どのような環境変数を設定するかなど)を定義する。
  3. docker buildコマンドを実行する。

必要なファイルをまとめる

まず、テストの実行に使用するSquishのインストールと、実行されるテストスイートが最低限必要となります。そこで、まずコンテキストを保持するための作業ディレクトリを作成しましょう:

$ mkdir /tmp/workdir

Qt 5.15パッケージをテストしたいので、squish-6.6.2-qt515x-linux64.runパッケージがインストールされている必要があります。私たちがインストールプログラムをクリックする必要なくSquishのインストールが行われるようにするため、今回は無人インストール(英語)を実行することにします。また、インストール・プログラムがライセンス・キーを作業ディレクトリに保存するように、SQUISH_LICENSEKEY_DIR環境変数が上書きされるようにします:

$ export SQUISH_LICENSEKEY_DIR=/tmp/workdir
$ ~/Downloads/squish-6.6.2-qt515x-linux64.run unattended=1 targetdir=/tmp/workdir/squish licensekey=111-22222-33333-444 ide=0 testcenter=0 menushortcut=0 desktopshortcut=0

もちろん、あなたの環境では、111-2222-3333-444の代わりに実際のライセンスキーを指定する必要があります(無償の評価版ライセンスをご入用の際はjapan@qt.ioまでお問い合わせください)。

最後に、テスト用Dockerイメージに含めるテストスイートを作業ディレクトリにコピーします:

$ cp -r ~/suite_sample /tmp/workdir

ここまでは順調です!次に、テスト用のDockerイメージがAUTを含む既存のDockerイメージに基づいていること、またテスト上のDockerイメージをどのように構成するかを表現するDockerfileを定義する必要があります。

Dockerfileの作成

作業ディレクトリができたので、これらのファイルをコンテナのどこに置くか、またDockerイメージにどのような追加設定を適用するかを定義する必要があります。

以下では、アプリケーションを含むDockerイメージはaddressbook:1.0.1という名前で、テストするアプリケーションは/home/addressbook/addressbookにあると仮定しています。Dockerfileを作成する際にできる便利なことはたくさんありますが、それらの説明はDockerfileの公式ドキュメント(英語)に譲り、ここでは以下の内容で/tmp/workdir/Dockerfileというファイルを作成します:

dockerfile
# 標準のアプリケーションイメージ(ここでは、addressbook:1.0.1)をベースにテスト用イメージを作成。 FROM addressbook:1.0.1

# XvfbとSquishに必要な追加の依存関係をインストール。
RUN apt-get update && apt-get install -y --no-install-recommends \\
libxtst6 \\
libgssapi-krb5-2 \\
xvfb \\
&& rm -rf /var/lib/apt/lists/*

# テスト対象のアプリケーションがXvfbで作成した仮想ディスプレイにアクセスするために必要な環境変数を設定。
ENV DISPLAY=:0
ENV LD_LIBRARY_PATH=/home/addressbook

# Squishのインストール、ライセンスファイル、サンプルテストスイートをイメージにコピー。
COPY squish /root/squish
COPY .squish-3-license /root/.squish-3-license
COPY suite_sample /tmp/suite_sample

# テスト対象のアプリケーションをsquishserverに登録。
RUN /root/squish/bin/squishserver --config addAUT addressbook /home/addressbook

# コンテナ起動時に仮想ディスプレイサーバーXvfbを起動。
CMD ["Xvfb", ":0", "-screen", "0", "1920x1080x24+32"]

このファイルは、Dockerに対して、我々のイメージをaddressbook:1.0.1(つまりAUTビルドを含む既存のイメージ)から派生させること、いくつかの追加Linuxパッケージ(特にXvfb)をインストールすること、そしてどの環境変数をアクティブにするのかを指示するものです。最後に、Squishのインストールは/root/squishに行い、squishserverにはテスト中のアプリケーションの実行ファイルがどこにあるか(/home/addressbook/addressbook)わかるように設定されています。

最後に、コンテナ起動時に自動的にXvfb(HD解像度の仮想ディスプレイ)が起動するように設定されています。

Dockerイメージのビルド

ここまで来たら、あとはイメージのビルドを開始するだけです。作業ディレクトリに移動して、docker build を実行します:

$ cd /tmp/workdir
$ docker build -t addressbook-with-squish:1.0.1 .

引数 -t は、結果の Docker イメージの名前を定義するために使用されます。AUTイメージの名前から派生したものを使うのがよいでしょう。私たちのAUT用Dockerイメージはaddressbook:1.0.1という名前なので、addressbook-with-squish:1.0.1としましたが、どのような名前にするかは自由です。

コンテナ化されたテストの実行

では、このイメージからコンテナを作成し、起動してみましょう:

$ docker run -d addressbook-with-squish:1.0.1
71f150d5c9ccb7e4219ce0f412400839a925f1cf7ea0d15d66ffacd1ab80ca4e

このコマンドは、デタッチモードでコンテナを起動します。それにより、このコマンドは新しく起動したコンテナを一意に識別するID文字列を出力したあと、すぐに処理を戻します。

あなたのマシンで、新しい独立した環境が動き出しました。この環境では今、仮想ディスプレイが動作していますが、それ以外はアイドル状態です。では、テストを実行してみましょう!

$ docker exec 71f /root/squish/bin/squishrunner --testsuite /tmp/suite_sample --local --reportgen testcenter,http://testcenter/project/addressbook?token=ABCDEF --reportgen junit,/tmp/report.xml

このコマンドは、71fで始まるIDを持つ実行中のコンテナの中で、squishrunnerコマンドを実行するものです。IDを全部指定する必要はなく、最初の数文字で十分であることに注意してください。squishrunnerには、4つの引数が渡されています:

  • --local : squishserverインスタンスを起動
  • --testsuite : コンテナ内に格納されているテストスイート /tmp/suite_sample を実行 
  • --reportgen testcenter,... : すべてのテストレポートを Test Centerインスタンスに直接送信する
  • --reportgen junit,... : テストレポートをJUnit形式で保存する(継続的インテグレーションシステムなどで処理するため)

コマンド実行後、実際に何が起こっているかを目視で確認することはできません。特に、アプリケーションが動作しているところを見ることはできません。これは仮想ディスプレイを使用しているためで、すべてのグラフィカルなインタラクションはヘッドレスモードで行われます。最も目に見える進捗状況の表示は、squishrunnerコマンドによって生成される出力です。

テストレポートの取得

Test Centerを使用する場合、レポートを取得するために特別なことをする必要はありません。すべてのテスト結果は Test Centerインスタンスにすぐにアップロードされるので、 Webブラウザを使用してレポートを分析することができます。今回は、JUnit形式のテスト結果のコピーを追加で/tmp/report.xmlというファイルに保存するよう、squishrunnerに指示を出しています。このファイルはコンテナ内にのみ存在します。このファイルを処理するために、例えば、継続的インテグレーションシステムに供給するためには、コンテナから取り出す必要があります。

これには複数のアプローチがあり、それぞれにメリットとデメリットがあります。今回は、単純なdocker cpコマンドが最も簡単なアプローチです:

$ docker cp 71f:/tmp/report.xml /home/frerich/report.xml

これにより、IDが71fで始まるコンテナから/tmp/report.xmlファイルがホストシステムにコピーされ、ファイルは/home/frerich/report.xmlに保存されます。コピーされたファイルは、継続的インテグレーションシステム(Jenkinsなど)に送り、さらに処理をすることができます。

さらなる考慮事項

Squishを使った最初のGUIテストを、完全に分離された自己完結型の環境で実行することができました!しかし、ここまではあくまで基本的な内容です。まだまだ検討すべきこと、やるべきことはたくさんあります。ここでは、この先どうするかを考える際に考慮すべきトピックをいくつか紹介します:

  • テスト用のイメージを他のコンピュータでも利用できるようにする必要があるかもしれません。簡単な方法は、docker saveとdocker importを呼び出すことですが、より管理しやすいソリューションは、複数のコンピュータ間で共有するDockerイメージのリポジトリとして機能する、あなた自身のプライベートDockerレジストリ(英語)をホストすることでしょう。
  • Docker cp を使ってコンテナからテストレポートをコピーするのは、今回のような小さな例ではうまくいきます。しかし、スクリーンショットやその他のアーティファクトを含む大きなテストレポートでは、かなり時間がかかることがあります。より良いアプローチは、コンテナにホストディレクトリをマッピングできるDockerボリュームを使用することでしょう。そうすれば、コンテナ内の特定の場所に書き込むと、ファイルが自動的にホスト上に表示されるようになります。
  • 今回のテスト用のDockerイメージは必要以上に大きくなっています。これは、Squishのインストールフォルダを整理する努力を怠ったためです。インストールフォルダに同封されているサンプルやドキュメント、提供されているスクリプトインタプリタのほとんどは、テストスイートを実行するためという観点では必要なものではありません。したがって、テストイメージを構築する際に、Squishのインストールから不要なファイルを削除する追加の「刈り込み」作業を導入することが有効です。
  • テストを複数のノードに分散させ、ロードバランシングを使って負荷が均等になるようにするのが有効でしょう。Docker swarm(英語)は、複数のコンピュータをクラスタとして動作させるのに最適な方法です。中央のマネージャーノードが、テスト実行用のコンテナがアイドル状態のコンピュータに常にディスパッチされるようにします。

Dockerを使ったお気に入りのトリック、もしくはほかに知りたいことはありますか?是非 コメントでお聞かせください!

お問い合わせ

SquishをはじめとするQtのQA(品質保証)ツールにご興味がおありの方は、Qt JapanのEメールアドレス:japan@qt.ioまでお気軽にご連絡ください。概要のご説明から詳細な技術的相談、また無料のツールトライアルのご案内もいたしております。


Blog Topics:

Comments