🦁

Djangoで設定ファイルを利用してカバレッジレポートを作成する方法

2021/08/14に公開

概要

Django のコードを書いた際にテストを買いたり、書かなかったりすることがあります。

基本的にテストコードは書いた方が良いのですが、書いたとしても正しくすべての条件を通っているのかを確認するのは大変時間がかかります。

そういった際に、自動で条件を通っているかどうかを確認できる方法について調べた内容を載せます。

検証環境について

  • python 3.9.4

ライブラリについて

coverage==5.5

Django でカバレッジ測定するためのおすすめの方法について

.coveragercというファイルを作成して、カバレッジ測定に使用する coverage コマンドの設定を作成することをおすすめします。

理由は、コマンドの実行時に指定するオプションを省略できるからです。

もちろん省略しなくても動きますし、ci 環境で動かす際にも必須ではありません。

ただし、オプションが多くなることで、実行されているコマンドが読みづらくなってしまい、メンテナンスに時間がかかるかもしれません。

設定ファイルは可能な限り外に出すことをおすすめします。

.coveragerc の記述方法について

先に例を載せます。

[run]
omit = 
  ./*/migrations/*

include = 
  ./apps/*

omitinclude と書かれている箇所を他の値に書き換えたい場合は、ドキュメントを参考にすると良いです。
https://coverage.readthedocs.io/en/coverage-5.5/cmd.html#execution-coverage-run

例えば、 omit は指定したファイルを除外し、 include はカバレッジの対象を指定できます。

The --include and --omit flags specify lists of file name patterns. They control which files to report on, and are described in more detail in Specifying source files.

rcfile というオプションもあるので、環境別で rc ファイルを用意しても良いかもしれません。
ステージ環境様の設定ファイル(.stage.coveragerc)を用意した場合、実行時のコマンドは以下のようになります。

coverage run --rcfile=.stage.coveragerc manage.py test 

あとは以下のコマンドを実行するだけでカバレッジを測定できます。

coverage run manage.py test

すると、カレントディレクトリに .coverageという隠しファイルが作成されます。

次に、以下のコマンドを実行してレポートを作成します。

coverage html

コマンドを実行すると、htmlcovディレクトリが作成され、その中に静的ファイルが作成されます。

その中からindex.htmlをブラウザで開くとカバレッジを確認できます。

実行したコマンドについては、run 同様に.coveragercに記載できます。

[html]
directory = coverage_html_report

このように設定すると、テスト結果がcoverage_html_report以下に作成され、どののテストから実行されたのかが分かるようになります。

設定ファイルの例と実行コマンドの例

解説だけだとイマイチ分かりづらいと思いますので、設定ファイルと、実行時のコマンドを載せます。

設定ファイルの例

[run]
omit =
  ./*/migrations/*
  venv/*

include =
  */core/*

dynamic_context = test_function

[html]
directory = coverage_html_report
show_contexts = True

実行コマンドの例

レポートを作成し、その結果をブラウザで開くコマンドです。

rm -r coverage_html_report 2>/dev/null
coverage run manage.py test
coverage html
open coverage_html_report/index.html

おまけ

include と source のどちらを使ったほうが良いか

ドキュメントや「python coverage」等で検索すると、以下のように source を使ったサンプルが見つかることがあります。

coverage run --source='.' manage.py test myapp 

これでも間違いでは無いと思いますが、プロジェクトが大きくなるにつれて、測定対象のファイルを細かく調整したくなってくるはずです。

そのときに--sourceでの指定だと、直接対象を指定することになるため規模が大きくなった際の指定に手間がかかります。

こういった設定ファイルはアプリケーションへの直接的な影響は起こりづらいですが、テストの設定を更新するために開発が止まってしまうことがあります。

可能な限り拡張しやすい設定を選んだ方が良いという理由から、--includeの使用をおすすめします。

.coveragercsourceincludeの指定をそれぞれ書いた場合は、以下の違いがあります。

  • source はパッケージかディレクトリを指定する
  • include はファイルのパターンを設定する

source と include をそれぞれ同じパッケージを指定した場合の違いについて

coreパッケージがどこかに存在するプロジェクトで、.coveragercに以下のように記載すると実行時にメッセージが出力されます。

[run]
source =
    */core/*

結果

Coverage.py warning: Module */core/* was never imported. (module-not-imported)
Coverage.py warning: No data was collected. (no-data-collected)

レポート対象のデータが見つからなかったということです。
正しく実行されるようにするには、sourceの指定方法を./core/*とする必要があります。

なので、「パッケージのどこかにある core パッケージ以下を対象にする」といったことはできません。

同様の手順でincludeについても設定をして検証します。

[run]
include =
  */core/*

結果

Ran 2 tests in 0.001s

FAILED (failures=1)

source とは異なり、途中に存在する core パッケージも対象となります。

Discussion