Djangoで単体テストやってる時の話。規模が大きくなると実行対象分割して実行させたくなる。分割の仕方は色々あると思うので割愛。

で、分割実行した場合って結果のcovrageとかも分割されるので、結果をどうにかマージしたい。

jenkinsなんかに表示させてる場合、xunit形式の結果と.coverageが必要になる。

これをどうマージするのかという話。


coverage

Coverage.pyというのがあり、それを使う。というかDjangoの中でも使ってる模様。

普通の単体テストは「python manage.py test」みたいに実行すると思うのですが、

色々やりにくいので、Coverage.pyを通して実行するように変える。↓の感じ。

coverage run --source='.' manage.py test app/tests

で、これだとcoverageのデータファイルが全部「.coverage」になっちゃうので、ファイル名を変えるために下記にする。

COVERAGE_FILE=.coverage_datafile coverage run --source='.' manage.py test app/tests

環境変数の「COVERAGE_FILE」にファイル名指定しておいてから実行するらしい。

そうすると分割したテスト毎にファイル名固定出来るのであとはそれを最後に下記でマージする。

coverage combine .coverage_*

「.coverage_」でファイルを全部指定みたいな。上を実行すると「.coverage」ってデータファイルにまとまるので、あとは、「coverage html」とか「coverage xml」何かで必要なレポート形式に変換する。


xunit

xunitも同様にマージが必要。とりあえず、テストの実行時に下記のオプション指定して結果のファイル名を実行毎に指定してあげる。

manage.py test app/tests/target --with-xunit --xunit-file nose_result_xxx.xml

そしたら、こっちも実行毎にファイルが出来るので、これをマージする。

で、pythonでこれをマージするツール無いかなーって探してみたのですが、下記しかない。

https://pypi.org/project/xunitmerge/

ただ、このツール開発止まってるぽくて更新6年くらい止まってるんですよね。。。

ついでに、python3系で出来ない書き方してるようでそのままだと動かない。

下のプルリクの修正が必要みたい。

https://github.com/miki725/xunitmerge/pull/9

本体に取り込まれる事は無さそうな気がするので、自分でリポジトリ作ってそっち直して、そっちからPIPでインストールする。

GitHubとかGitLabとかリモートリポジトリからpipインストールする場合は↓の感じ。

※別に直で実行してもOK。

pip install  -b release git+https://github.com/***/***/xunitmerge

実行できるようにしたら、下記でマージする。

xunitmerge nosetests_*.xml nosetests.xml

「nosetests_」で始まるファイルを「nosetests.xml」にマージするみたいな。

あとはこれらをjenkinsなりに食わせればOKという寸法です。


最終的にDjangoのtest実行する時のコマンドはもろもろオプションとかつけた感じにすると下記の感じ。

COVERAGE_FILE=.coverage_datafile coverage run --source='.' manage.py test app/tests --settings=dapp.settings_hoge.py --keepdb --with-xunit --xunit-file nosetests_xxx.xml