ServerspecでMacの開発環境をテストする


開発用のMacBookを新調したのをきっかけに、HomebrewとAnsibleを用いて開発環境構築の自動化に取り組みました。今回はその環境をServerspecを使ってテストする方法をメモしておきます。
HomebrewとAnsibleでMacの開発環境構築を自動化する

testing-mac-with-serverspec-01

環境

環境は以下の通りです。

ソフトウェアバージョン
Mac OS X10.10.4
Homebrew0.9.5
Ansible1.9.1
Serverspec2.19.0

Serverspecとテストについて

Serverspecについては既知の方も多いと思いますが、簡単に説明すると、対象の環境が期待した通りの状態にあるかをテストするためのツールです。AnsibleやChef, Puppetといった構成管理ツールに依存することなく、また、OSの種別毎にテストコードを書き換える必要がないのが特徴です。
Serverspec

Ansibleでもテスト(のようなもの)を書こうと思えばかけますし、テストを書かなくても実行結果から状態を判断することはできます。そういった状況ではありますが、いつでもテストだけを単体で実行できるようServerspecでテストを書きました。
既にリポジトリにテストを追加しているので、READMEに書かれた手順で簡単に実施できます。以前に公開したプロビジョニングの利用者がそれなりにいるようなので、テストに関してもぜひ試していただければと思います。
mawatari/mac-provisioning – GitHub

テストを追加した時の作業ログ

自身でテストを作成した時の作業ログを残しておきます。何かの参考になれば幸いです。

Ruby環境の整備

ServerspecはRuby Gemsなので、Rubyを実行できる環境が必要です。Mac OS Xには初めからRubyはインストールされていますが、ここではSystem Rubyではなく、rbenvを利用したいと思います。環境を整えた後に、他のRubyプロジェクトと、干渉しないようにするためです。

rbenvで最新安定版のRubyをインストールするため、まずは、 web-development.ymlrolesruby-buildを追加します。(ロール名は何でも構いません。)

次に、 ruby-buildのタスクを作成します。Ansibleにはrbenvのモジュールは無いため、 shellモジュールでrbenvの最新安定版をインストールします。以下のとおりです。

web-development.ymlhomebrew_packagesrbenvが指定されていることを前提にタスクを作成しているため、 homebrew_packagesから rbenvを削除している人は、再度、追加するか、このタスクに rbenvのインストールを追加しておきましょう。
ちなみに、 rbenv install -s $(rbenv install -l | grep -v - | tail -1)というコマンドは、rbenvでRubyの最新安定版をインストールするワンライナーです。以下で解説しているので、参照してください。
rbenvでRubyの最新安定版をインストールするワンライナー

テストの作成

ひな形の作成

いよいよテストの作成です。テストを作成するにあたって、まずは bundleコマンド等を用いて、ひな形を作成します。

これにより、19行目から24行目にある通り、4つのファイルが生成されました。 spec/localhost/sample_spec.rbに関しては、 homebrew_spec.rbという名称に変更してから利用します。

ヘルパーの作成

以下のとおり、ヘルパーを作成しました。
Homebrew Caskでインストールしたパッケージは、Serverspecの Package resource be_installed matcherが利用できないため、パッケージ名のディレクトリが存在しているかどうかを確認するテストとしました。

テストの作成

以下のとおり、テストを作成しました。
be_installedマッチャーと、 be_directoryマッチャーを使って、パッケージの存在確認を行っています。

以上でテストの作成は完了です。

テストの実行

テストを書き終えたので、実行してみたいと思います。

すべてのテストをパスしました。面倒なことは無いと思うので、ぜひ取り組んでいただけたらと思います。以上です。

こぼれ話

テストの作成と実行に関しては以上ですが、その過程でこぼれ話もあったので、合わせてメモしておきます。
当初、Homebrewパッケージに関しても、 be_directoryマッチャーを利用してテストしようとしていました。その際、Homebrew Cellarのパスを得るヘルパーを書く必要があったのですが、そこで結構ハマりました。以下の様な内容です。

Bundler.with_clean_envというメソッドが肝で、これが無いと期待通りにはパスを得ることができません。Homebrewだけは、System Rubyを使ってインストールしていて、かつ、このヘルパーは bundle execで呼ばれるためです。
文字だけでは実感がわきにくい方もいると思います。CLIで以下の3つのコマンドを実行し、出力結果を見比べてもらえればと思います。

つまり、2行目と同じことを bundle exec下でも得たい場合は、 Bundler.with_clean_envを利用するということですね。

以上、こぼれ話でした。