DockerCon EU 2015でLaura Frank氏が,“Stop Being Lazy, and Test Your Software”と題したプレゼンテーションを行った。Frank氏が提案するのは,開発規模や企業の状況に関係なく,ソフトウェアにテストは不可欠であるということだ。開発ワークフローにDockerを取り入れることで,テストフレームワークの記述と実行をより効率化することができる。最終的にはそれがユーザに対して,高品質なソフトウェア製品の継続的な提供を可能にするのだ。
Codeshipのベテランソフトウェア技術者である氏は,講演の冒頭で,ごく初期のマシンがコンピューティングに使用されていた時代から,ソフトウェアテストが行われていたことを紹介した。米軍の弾道研究所(Ballistic Research Laboratory)で大砲の砲撃軌道を計算していた,世界初の汎用電子計算機であるENIACをプログラムしていた女性は,手計算された既知の正しい値を使用して,計算結果を定期的にチェックしていた。テストは,ペアプログラミングやバージョン管理,コードレビュー,高可用性アーキテクチャといった他のテクニックと同様,“製品としてのソフトウェア開発”に不可欠な部分なのだ,とFrank氏は提唱する。
テスト実施に対するモチベーションとしては,レグレッションを発生させないアプリケーションのアップデートの実現,アップデートの機能検証,リファクタリングが既存機能を損ねていないことの確認,といったものがあげられる。テストの作成や実行でしばしば感じるフラストレーションの中には,ローカルで実施するテストスイートに時間が掛かり過ぎること,通常の開発ワークフローからの逸脱,適切なテスト環境構築が困難であることなどが含まれている。これに対してFrank氏は,テスト生成と実行のプロセスにLinuxコンテナとDockerツールボックスツールスイートを採用することで,フラストレーションをある程度軽減することができるのではないか,と提案した。
Docker Composeを使えば,一貫性と再現性を持ったコンテナ環境を簡単に実現することができる。ソフトウェア開発者の多くはDocker Composeを使ってローカル環境を構築しているが,そのレベル止まりだ,とFrank氏は言う。予測と再現の可能な環境構築にDockerを使えば,開発作業でも同じメリットを得ることができる。それは品質保証のプロセスにも大きなメリットとなり得るはずなのだ。
Dockerは予測可能,再現可能なテスト環境を実現します。以上。
ただしテストで使用するには,Docker Composeワークフローをある程度修正する必要がある,とFrank氏は警告する。Docker Composeが‘dockerfile’でサポートしているさまざまな環境変数や実行ターゲットを参照するために,別のDockfileを使用しなくてはならない場合もある。また,コンテナやアプリケーション,データストアを複雑に配置して活用するのであれば,初期化と実行の競合状態の発生を回避するための注意も必要だ。
Docker Composeの’docker-compose up’コマンドは,ComposeのYAMLコンフィギュレーションファイルにエンコードされた自動テストスイートの実行に利用できる。さらには下に示すように,run’コマンドを使って同じようなサービスを実行することも可能だ。
$ docker-compose up $ docker-compose run -e “RAILS_ENV=test” app rake db:setup $ docker-compose run -e “RAILS_ENV=test” app test-command path/to/spec.rb
継続的インテグレーションとテストは連携して進むものだ,とFrank氏は言う。適切なテストカバレッジを欠いたCI/CDに過度に依存するのは間違っている。製品の問題点を探すことよりも,失敗したテスト実行の方に目が向いてしまうのが容易に想像できるからだ。
テストの実行は,可能な限り実運用に近い環境で行うように注意する必要がある。これについてFrank氏は,アプリケーションをコンテナ内で実行することで(さらに開発もコンテナ内で行うことで),ビルドパイプライン内のテストもコンテナ内で進めることができると主張する。これを実現する方法として,‘Docker-in-Docker’構成を使いたいと思う開発者もいるかも知れない。そのような人たちにFrank氏はJérôme Petazzoni氏の著作,例えば‘Using Docker-in-Docker for your CI or testing environment? Think twice.’などの記事を参考にすることを提案した。
開発プロセスでコンテナを使用しようという場合,特定のワークロードを実行するための‘小型VM’としてコンテナを(間違って)考えていることが多い,と氏は指摘する。しかしながら,コンテナをもっと正しく,シンプルなOSプロセスとして扱うならば,さらに多くのメリットをテストプロセスで実現することができる。例えばコンテナ化されたアプリケーション上で,複数のテストを同時並行的に実行することが可能だ。品質向上というDockerCon EUカンファレンスのテーマを踏まえた上で氏が主張したのは,テストコードカバレッジの一定水準以下への低下,コードチェック(lint)エラーの増加,あるいはRatchet上の違反などといった品質低下となって現れるビルド不良に対して,より並列度の高いビルドパイプラインを加えることで,開発するソフトウェアの品質向上が可能になる,という点である。
最後に氏はEdsger Dijkstra博士の言葉を引用し,テストは不可欠なものだがソフトウェアの無謬性を保証するものではない,過度な期待をしてはいけない,と述べて,講演の結論とした。
テストはバグの存在を証明する上では非常に効果的ですが,バグが存在しないことを示すにはまったく不十分なのです。
Frank氏の講演 “Stop Being Lazy, and Test Your Software” で使用されたスライド資料はSlideShareにある。また,プレゼンテーションを記録した動画がDocker YouTubeチャネルで間もなく公開される予定だ。