Ansible向けのコードカバレッジツールKirbyを作りました
PythonやJavaでコードを書く場合、コードカバレッジの測定は、よくやりますよね。最近、Ansibleでもコードカバレッジを測りたくなったのですが、それらしいツールがなかったので、作ってみました。名前はKirbyです。今回はKirbyがどんなツールなのか紹介してみます。
どんなことができるのか
Kirbyは、AnsibleのPlaybookやRoleに対して、タスクレベルのカバレッジを測定するツールです。
例えば、次のようなPlaybookと、Serverspecのテストがあったとします。Playbookでは2つのタスクを実行しています。Serverspecのテストでは、Playbookの一つ目のタスク(create dir1
)に対するテストをしています。
~/src/kirby_demo% cat create_2dirs.yml --- - hosts: localhost gather_facts: no tasks: - name: create dir1 file: path=./dir1 state=directory - name: create dir2 file: path=./dir2 state=directory
~/src/kirby_demo% cat spec/localhost/sample_spec.rb require 'spec_helper' describe file('./dir1') do it { should be_directory } end
Kirbyをインストールした状態でAnsibleを動かすと、次のような結果が返ってきます。
~/src/kirby_demo% ansible-playbook create_2dirs.yml -i "localhost," -c local PLAY [localhost] ************************************************************** TASK: [create dir1] *********************************************************** changed: [localhost] tested by: - rspec ./spec/localhost/sample_spec.rb:4 # File "./dir1" should be directory TASK: [create dir2] *********************************************************** changed: [localhost] tested by: PLAY RECAP ******************************************************************** *** Kirby Results *** Coverage : 50% (1 of 2 tasks are tested) Not tested: - create dir2 *** Kirby End ******* localhost : ok=2 changed=2 unreachable=0 failed=0
*** Kirby Results ***
の下の行を見ると、カバレッジが50%であることと、テストされていないタスクはcreate dir2
であることがわかります。
このように、Kirbyを使うと、AnsibleのPlaybookやRoleがどれぐらいテストされているか、また、テストされていないタスクはどれか、を知ることができます。
インストール手順
(2015/09/22追記:実際にKirbyを動かしてみたいけど、Playbookとテストが手元にないという場合は、Playbookとテストのサンプルを利用したチュートリアルが良いかもです)
Kirbyのダウンロード
Playbookのあるディレクトリで、以下のコマンドを実行します。
mkdir callback_plugins cd callback_plugins wget https://raw.githubusercontent.com/ks888/kirby/master/callback_plugins/kirby.py
設定
Playbookのあるディレクトリで、kirby.cfg
というファイルを作成し、以下の内容を書き込みます。
[defaults] enable = yes serverspec_dir = ./ serverspec_cmd = bundle exec rake spec
serverspec_cmd
は、Serverspecを走らせるためのコマンド、serverspec_dir
は、そのコマンドを実行するディレクトリを指定します。環境に応じて変更して下さい。
使い方
実行
いつもどおりansible-playbook
コマンドを動かします。できればAnsibleのターゲットとなるホストはクリーンな状態(まだ一度もAnsibleをかけていない状態)の方が、うまくカバレッジを出せます。
実行結果の確認
例えば以下のような結果が得られたとします。
~/src/kirby_demo% ansible-playbook create_2dirs.yml -i "localhost," -c local PLAY [localhost] ************************************************************** TASK: [create dir1] *********************************************************** changed: [localhost] tested by: - rspec ./spec/localhost/sample_spec.rb:4 # File "./dir1" should be directory TASK: [create dir2] *********************************************************** changed: [localhost] tested by: PLAY RECAP ******************************************************************** *** Kirby Results *** Coverage : 50% (1 of 2 tasks are tested) Not tested: - create dir2 *** Kirby End ******* localhost : ok=2 changed=2 unreachable=0 failed=0
タスクが実行されるたびに、
tested by
という行が表示されます。- もし
tested by
の次の行が空だった場合、タスクはテストされていません(create dir2
がこれに該当します)。 - 空ではない場合、タスクはテストされています(
create dir1
がこれに該当します)。 tested by
という行が表示されていない場合、Kirbyはそのタスクをカバレッジから外しています。タスクがホストの状態を変更しなかった場合(タスクの結果がchanged
ではなかった場合)に、これが当てはまります。
- もし
Playbookの実行後に、カバレッジとテストされていないタスクの一覧が表示されます。
カバレッジの改善
基本的には、テストされていないタスクのテストを書くことでカバレッジを改善します。
ただ、例えば以下のようなタスクについては、テストがいらないかもしれません。
- commandモジュールからlsコマンドを呼ぶ場合(ホストの状態を変更していないため)
- パッケージをインストールするための準備作業として、パッケージをダウンロードする場合(インストール成否のテストで十分そうなため)
そのような場合には、以下の方法でタスクをカバレッジの対象から外すことができます。
changed_when
をつかうKirbyはホストの状態を変更しないタスク(実行結果が
changed
でないタスク)はカバレッジに含めません。もしchanged
なタスクが実際にはターゲットのホストを変更していない場合、Ansibleのchanged_whenが使えます。例えば以下のように書くと、タスクの実行結果がchanged
ではなくなります。
- command: ls changed_when: False
coverage_skip
をつかうKirbyは
coverage_skip
というキーワードがタスクの名前に含まれている場合、そのタスクをカバレッジに含めません。例えば以下のように書くと、タスクはカバレッジの対象外になります。
- name: create dir2 [coverage_skip] file: path=./dir2 state=directory
まとめ
Ansible向けのコードカバレッジツールKirbyを紹介しました。これから色々改善しようと思っているので、感想やご意見があれば、GitHubやTwitterを通して教えていただけると嬉しいです。よろしくお願いします。
(2015/09/22追記:Kirbyをちょっと試してみたいという方向けに、チュートリアルを作成しました。よろしければそちらもご参照下さい)