テスティングフレームワークとデプロイ自動化を支える技術
技術部の高津です。
このブログは、現在、弊社が採用する技術や、今後取り入れようとしている技術や手法について積極的に発信していこうと考えスタートしたいと思っています。
第一回目は弊社が継続的に取り組んでいるテスティングフレームワークを利用した開発とデプロイの自動化について簡単にご紹介出来ればと思います。
伝統的な開発手法の振り返りと問題点
上記は、昔から行われている伝統的な開発手法です。
この手法は、エンジニア単体で、”開発〜テスト〜リリースまで実施出来る為、効率的な手法の一つではありますがこの方法はもう何年も前から通用しなくなってきていると弊社では考えています。
- 昨今、Webシステムと言えど、スマートフォン対応等を含め一つ一つのシステムに対する機能要求が増加し、プログラム品質に対する要求基準も向上してきた。
- システムが大規模化する事に相対し開発要件も増加し一人で手に追えるシステムが少なくなってきており、少人数の優秀なエンジニアのみに依存する属人的な開発方法は既に通用しなくなってきた。
- フロントエンドエンジニアリングやセキュリティエンジニア、クラウドアーキテクト等、新たに注目を集める専門性の高い、プロフェッショナルな職務領域が確立した事を背景としチームによる開発を前提とする時代へ移行した
が挙げられます。
チームで開発を行う際、(たとえ優秀なエンジニアであっても、)情報や仕様を公開せずに動けば正義というプログラムを書いても全く価値がないと言っても過言ではありません。
それよりもチームに対する情報や状況の共有が重要となっており、チーム全体がその価値を理解しチーム全体でその品質を守り構築してゆく事が求められています。
これらの詳しい内容や、歴史などは以下の書籍によくまとまっていますので、ご興味がある方はぜひ読んでみてください!(弊社にも本棚においてあります)
弊社での開発手法の改善
これらチームでの共同作業を実施し、その価値を維持する為にTDD(テスト駆動型開発/test-driven development)が普及し多くの開発チームにより採用されてきました。
テストプログラムを中心とするこれら開発手法は、2000年以前より提唱されておりJUnitのファーストリリースが1997年等、全く新しいものではありません。
これら技術は主にJavaを用いて開発される大規模業務案件にて積極的に活用が進んでおり『プログラムをテストするためのプログラム』が必要になってきた背景や歴史は参考になると考えます。
当時、PHPやPerl等のWebアプリケーションを支える言語は、その手軽さから一般ユーザーにも手軽く利用され、インターネット関連システムの仕様も簡素であったことから当時はまさに人間力でカバーできる範囲の内容でした。
しかし、昨今のWebアプリケーションは、ビジネスに対し大きな影響を与える為、当時と異なり厳しい品質基準が求められておりテストの重要性が高まり最早必須であると考えています。
すこし前置きが長くなってしまいましたが、弊社でも上記のような問題は昔から起きていました。
例に漏れず、エンジニアの努力でカバーし、
時には徹夜で作業…なんてことも(´・ω・`;;)
しかし、これら属人的な作業を続けていると、お客様に迷惑をかけるばかりか、開発者の疲弊の蓄積は避けられないと考えています。
だからこそ弊社技術部ではチームで作業を行う事を前提とし、『プログラム作成したら、そのプログラムをテストするプログラムを書く』事を継続的に取り組み実践しています。
しかし、テストプログラムは銀の弾丸ではありません。
- そもそもテストプログラムに問題があればその行為自体が無価値になる。
- 実機操作をからめたテストプログラムは巨大なE2Eテストを書く必要があり、規模が小さめの案件ではすべてをカバーできない。
(参考)TDDの導入とエンドツーエンドテスト自動化の実践まとめ - 厳格なテスト仕様の策定は多くの間接的な設計工数を伴う為、ビジネス要件の変動しやすい案件では非効率になる場合も多い。
これら問題に対応するために弊社ではテストプログラムの実施を前提にしつつも、合理性を考慮しプロトタイプ開発や属人的な開発やテストについても肯定的に取り入れてゆこうと考えています。
また弊社では厳密なTDD/BDDは行っておりません。テストファーストという進め方ではなく、開発と同時にテストコードを書くという手法を取り込んでいます。
この手法に関してはテスト駆動開発(TDD)はもう終わっているのか?の記事に本質的な議論が掲載されています。
弊社では合理性を意識しつつテストコードを組み込みエラーを無くすことを最重要ポイントとしています。
弊社での開発を支えるツール・サービス
↑クリックすると拡大します
上記ワークフローを行うことにより以下を解決します。
- ソースコードの更新差分をgitで管理し、各ツールがgitの差分のみを精査・適用することにより、人のチェックに依存していた部分を自動化する
- 同様にソースコードの更新差分を可視化・共有することにより、未然のトラブルを別の人によって防ぐ
- プロビジョニング・デプロイツールを利用することにより、毎回同じ手順を保証する。
- 人間が定期的に行う作業をサーバーに任せることで、人へ依存する作業を減らす
- アプリケーション実行環境環境の共通化を行うことで環境依存するアプリケーション実装を未然に防ぐ
- 共用の確認環境を用意することで、結合テストを容易にする
- 単体テストはエンジニア自身が用意し、サーバー上で自動実行する。これにより、テスターは結合テストのみに注力できる
開発・制作フェーズでは弊社では以下のツール/アプリケーションを導入しています
- Vagrant/Virtual Box
弊社ではローカルPC環境はWindows/Macを自由に選択できる環境を提供しています。
しかし、環境の異なるPC上に開発環境を準備し開発を行いリリースしてみると、、
『表示が崩れた!!』、『プログラムが動かない!!』なんてことが普通に起きます。
これら問題を解消する為、本番環境と同一の開発環境を、ローカルPC上のVirtualBox内に構築しVirtualBoxの設定を手軽に扱えるVagrantを平行利用しています。
その他、プロビジョニングと呼ばれる技術を採用しておりますがこの辺はまた次の機会に。 - GitHub
gitでバージョン管理をしチームのコードを安全にマージする為にGitHubを利用しています
開発時はgitの機能を利用し『誰が何を書いたか?』を管理します。
作成したプログラムはVirtualBox内の仮想環境でまずテストを行い、問題がなければGitHubへプッシュ(ソースコードの変更をアップロード)します。
リリースソースコードへの反映は、チームメンバーや品質管理担当者はその生産されたコードを pull request という機能で確認し、問題があれば指摘(レビュー)を行い未然に防ぎます。 -
PHPUnit
PHPUnitとはJava環境にて利用されていたテスティングフレームワークにインスパイアされ開発されたPHP版のテスティングフレームワークです。
弊社ではPHPUnitを利用し追加開発時のデグレードを未然に防ぐ運用を行っています。 また弊社のアプリケーション開発ベースはCakePHPというフレームワークを利用することが多いため、テストコードも当然の事ながらCakePHPに準じたものを作成します。
その他、構文チェックなどで Code Sniffer なども利用していますが、こちらはテスト関連記事を書くときに改めてご紹介できればと思います。 -
Capistrano
作成したアプリケーションを、本番環境などにソースコードを配置するためのツールとなります。
CapistranoはRubyで開発されたツールですが、デプロイするアプリケーションの言語は問いません。
このツールはソースコードを配置するだけでなく、以下機能を利用できます。- 環境に適したファイルの配置・書き換え
- 多重化された環境の場合、複数台マシンへの同時適用
- 万が一不測の事態が発生した場合のリリース切り戻し機能
上記機能は規模が大きめの開発では、自分たちの安心のために手放せない機能となっています(*´ω`*)
昨今活用が一般化しているAWS(Amazon Web Service)では、Elastic Beanstalkという優れたデプロイソリューションが準備されており、現状はこちらの活用が主軸なっています。
Elastic Beanstalkは、AWSにて提供される様々なサービスと連携し稼働する事を前提としており、AWSをインフラとするシステム運用において非常に優れた合理性を提供しています。
また同社から提供されているOpsWorksやCodeDeployと違うところとして、環境構築に関してはプリセットされたものを利用することにより、インフラ環境構築に時間をかけることなくすぐにアプリケーション開発に注力できるメリットを持っています。
Elastic Beanstalkやその他AWSの各サービスに関しては次回以降詳しくご紹介出来ればと思いますが、弊社ではこれら実行環境の特徴に合わせ適切なツールを随時選定しています。 -
Jenkins
PHPUnitなどのテストツールやCapistranoなどのデプロイツールは基本的にはCLI(コマンドラインインターフェース)での利用を前提としており、エンジニアではないと使いにくいツールになっています。
しかし、プロジェクトに関わるデザイナーなどの非エンジニアメンバーも本番環境への適用に関わるため、上記ワークフローが可視化され誰でも触れるGUI環境を必要とします。
Jenkinsはこれら要求を解決するためのアプリケーションとして、ブラウザによるGUIにて管理を可能としており、実行されたログをいつでも、どこからでも、誰でも確認可能な環境を提供してくれます。
最近ではCircleCIやWercker等、クラウド型のCI(継続的インテグレーション)ツールが充実してきており、CIツールの[クラウド]VS[オンプレミス]については次回以降にまた詳しく書いていきます。
今回は弊社開発手法に関する紹介程度の記事になってしまいましたが、次回からは各技術要素についてもう少し深く書いていきたいと思います。
弊社ではdevopsを意識した開発が大好きなアプリケーションエンジニアを募集しております。
ご興味のある方はぜひ上記フォームよりエントリください!