バグをなくし開発システムの信頼性(品質)を保証するために,テストコードを書いて自動的にテストをできるようにしたい.またテストカバレッジ(テスト網羅度)を計測して,テスト漏れがないかを確認したい.まずは,カバレッジを計測するための coverage パッケージをインストールしよう.
(py39) C:\Users\lecture\Documents\django\django_comment>pip list | find /I "coverage" ⏎ (py39) C:\Users\lecture\Documents\django\django_comment>pip install coverage ⏎ Collecting coverage Downloading coverage-6.4.2-cp39-cp39-win_amd64.whl (187 kB) |████████████████████████████████| 187 kB 2.2 MB/s Installing collected packages: coverage Successfully installed coverage-6.4.2 (py39) C:\Users\lecture\Documents\django\django_comment>pip list | find /I "coverage" ⏎ coverage 6.4.2 (py39) C:\Users\lecture\Documents\django\django_comment>
Mac でもほぼ同じ方法で coverage パッケージをインストールできる.
rinsaka@Macmini2020 django_comment % pip list | grep -i coverage ⏎ rinsaka@Macmini2020 django_comment % pip install coverage ⏎ Collecting coverage Using cached coverage-6.4.2-cp39-cp39-macosx_10_9_x86_64.whl (184 kB) Installing collected packages: coverage Successfully installed coverage-6.4.2 rinsaka@Macmini2020 django_comment % pip list | grep -i coverage ⏎ coverage 6.4.2 rinsaka@Macmini2020 django_comment %
テストのコードは次のような comments/test.py である.
comments/test.pyfrom django.test import TestCase
# Create your tests here.
このテストコードに簡単なテストを記述してみよう.まずは,トップページ (/) にアクセスして,200番(成功)のステータスコードを受け取ることができるかどうかを確認するテストを記述してみよう.
comments/test.py
from django.test import TestCase
from django.urls import reverse
# Create your tests here.
class CommentIndexTests(TestCase):
def test_comment_index(self):
"""
Comment index のテスト
"""
response = self.client.get(reverse('comments:index'))
self.assertEqual(response.status_code, 200)
テストコードの記述ができたら,テストを実行してみる.1つのテストが実行されて,成功していることがわかる.
(py39) C:\Users\lecture\Documents\django\django_comment>python manage.py test comments ⏎ Found 1 test(s). Creating test database for alias 'default'... System check identified no issues (0 silenced). . ---------------------------------------------------------------------- Ran 1 test in 0.026s OK Destroying test database for alias 'default'... (py39) C:\Users\lecture\Documents\django\django_comment>
次に,コメントの詳細表示ページのテストコードを記述する.Laravel の自動テストと異なり,Django ではテスト実行時に別のデータベースが作成される.つまり,テストコードの中でデータを投入する必要がある.次のコードではコメントを1件追加して,その詳細ページに投稿したタイトルが表示されているかどうかをテストしている.
comments/test.pyfrom django.test import TestCase
from django.urls import reverse
from django.utils import timezone
from .models import Comment
# Create your tests here.
class CommentIndexTests(TestCase):
def test_comment_index(self):
"""
Comment index のテスト
"""
response = self.client.get(reverse('comments:index'))
self.assertEqual(response.status_code, 200)
def test_comment_show(self):
"""
Comment の詳細ページ
"""
comment = Comment.objects.create(
title="test title",
body="test body",
created_at=timezone.now(),
updated_at=timezone.now())
url = reverse('comments:show', args=(comment.id,))
response = self.client.get(url)
self.assertContains(response, "test title")
再度テストを実行すると2件のテストをパスしたことがわかる.
(py39) C:\Users\lecture\Documents\django\django_comment>python manage.py test comments ⏎ Found 2 test(s). Creating test database for alias 'default'... System check identified no issues (0 silenced). .. ---------------------------------------------------------------------- Ran 2 tests in 0.034s OK Destroying test database for alias 'default'... (py39) C:\Users\lecture\Documents\django\django_comment>
このようにコードを変更するたびに自動テストを実施すれば,思わぬバグを作り込んでしまっても発見できる可能性が高くなる.しかし,ソースコードのどの部分のテストはされて,どの部分のテストができていないかを知ることも重要である.このために,テストカバレッジ(網羅度)を計測しよう.
テストカバレッジを計測するには,テストの実行コマンドにいくつかのオプションを加え,coverage run --source='.' manage.py test comments
を実行すると良い.これにより,.coverage ファイルが生成される.その後,カバレッジレポートを表示するために coverage report
コマンドを実行する.その結果,comments/views.py は50行中,18行がまだテストされておらず,カバレッジが64%であることが確認できた.
(py39) C:\Users\lecture\Documents\django\django_comment>coverage run --source="." manage.py test comments ⏎ Found 2 test(s). Creating test database for alias 'default'... System check identified no issues (0 silenced). .. ---------------------------------------------------------------------- Ran 2 tests in 0.043s OK Destroying test database for alias 'default'... (py39) C:\Users\lecture\Documents\django\django_comment>coverage report ⏎ Name Stmts Miss Cover --------------------------------------------------------- comments\__init__.py 0 0 100% comments\admin.py 1 0 100% comments\apps.py 4 0 100% comments\forms.py 18 9 50% comments\migrations\0001_initial.py 5 0 100% comments\migrations\__init__.py 0 0 100% comments\models.py 6 0 100% comments\tests.py 13 0 100% comments\urls.py 4 0 100% comments\views.py 50 18 64% django_comment\__init__.py 0 0 100% django_comment\asgi.py 4 4 0% django_comment\settings.py 18 0 100% django_comment\urls.py 3 0 100% django_comment\wsgi.py 4 4 0% manage.py 12 2 83% --------------------------------------------------------- TOTAL 142 37 74% (py39) C:\Users\lecture\Documents\django\django_comment>
カバレッジの詳細を確認したい場合は,coverage html
コマンドで HTML ファイルを生成すれば良い.このコマンドによって htmlcov というフォルダが作成され,カバレッジレポートの HTML が生成される.この中の index.html をブラウザで閲覧する.なお,この htmlcov や .coverage は Git に含まないように .gitignore に記載があることに注意する.
(py39) C:\Users\lecture\Documents\django\django_comment>coverage html ⏎ Wrote HTML report to htmlcov\index.html (py39) C:\Users\lecture\Documents\django\django_comment>dir ⏎ ドライブ C のボリューム ラベルがありません。 ボリューム シリアル番号は E033-4666 です C:\Users\lecture\Documents\django\django_comment のディレクトリ 2022/07/27 13:23 <DIR> . 2022/07/27 13:23 <DIR> .. 2022/07/27 13:22 53,248 .coverage 2022/07/27 10:57 77 .gitignore 2022/07/27 13:03 <DIR> comments 2022/07/27 13:14 135,168 db.sqlite3 2022/07/27 10:58 <DIR> django_comment 2022/07/27 13:23 <DIR> htmlcov 2022/07/27 10:50 692 manage.py 4 個のファイル 189,185 バイト 5 個のディレクトリ 14,252,630,016 バイトの空き領域 (py39) C:\Users\lecture\Documents\django\django_comment>
htmlcov フォルダ内にある index.html を Web ブラウザで開くとカバレッジレポートを確認できる.
comments/views.py のページを開くと,テストされていないコードがハイライトされて確認できる.このページを確認しながら,すべての行がテストされるようにテストケースを追加し,カバレッジ100%を目指すと良い.