Django でテストを実装します。
私は今までテストを実装したいと思っても、テストを実装していませんでしたが、プロジェクトが大きくなるとデグレード(デグレ)が酷く、何とかこの状況を改善したいと思い、テストを実装し始めました。実際にテストを実装すると、意外に簡単に実装できることがわかります。
テストを実装することで、リグレッションテストができ、デグレ防止だけでなく、コードレビューでレビューする側が、テストコード部分の動作を確認する必要がなくなり、レビュー時間の短縮にも貢献します。
CI ツールと組み合わせることで、自動でテストすることもできますし、テストを実装することで、様々な恩恵を受けることができます。
Contents
完成イメージ
$ python3.6 manage.py test app Creating test database for alias 'default'... System check identified no issues (0 silenced). .... ---------------------------------------------------------------------- Ran 4 tests in 0.018s OK Destroying test database for alias 'default'... $
バージョン
- Python 3.6.4
- Django 2.0.3
インストール
Python, Django
Python と Django のインストールは、Python Web フレームワーク Django の環境を構築するの記事を参考にしてください。
実装
views.py
from django.shortcuts import render def index(request): return render(request, 'app/index.html') def plus(a, b): return a + b def is_true(): return True def is_none(): return None
テスト対象となる views.py です。4つの関数を実装しました。
tests.py
from django.urls import reverse from django.test import TestCase, Client class ViewsTest(TestCase): def test_index(self): response = Client().get(reverse('index')) self.assertEqual(response.status_code, 200) class FuncTest(TestCase): def test_plus(self): from app.views import plus self.assertEqual(plus(1, 1), 2) def test_true(self): from app.views import is_true self.assertTrue(is_true()) def test_none(self): from app.views import is_none self.assertIsNone(is_none())
views.py のテストを実装します。
テストは、Django の TestCase を使います。Django の TestCase は、Python unittest の TestCase を継承していますので、テストの合否を判断する関数は、unittest の TestCase 関数を使用します。
テストの合否を判断する関数は、たくさんありますので、詳細はリファレンスを確認してください。ここでは、その中の一部を取り上げます。
assertEqual
引数を2つ渡し、等価であれば、テストが合格します。この関数が一番使用頻度が高いと思います。
assertTrue
引数を1つ渡し、True であれば、テストが合格します。
assertIsNone
引数を1つ渡し、None であれば、テストが合格します。
補足
tests.py としていますが、tests ディレクトリを作って、test_views.py や test_forms.py とした方が見通しが良くなります。
テスト
test コマンド
$ python3.6 manage.py test app Creating test database for alias 'default'... System check identified no issues (0 silenced). .... ---------------------------------------------------------------------- Ran 4 tests in 0.018s OK Destroying test database for alias 'default'... $
テストの実行は、manage.py の test コマンドを使います。
実行すると、上記のような出力なります。
今回実装したテストの関数は4つで、テストは関数毎に実行しますので、 Ran 4 tests となっています。1つの関数に複数のテストを入れてしまうと、テストが失敗したときに、どこで失敗したのかがわからなくなります。特別な理由がない限り、1つの関数にテストは1つまでとした方が良いと思います。
まとめ
Django のテストを実装しました。
Django のテスト(というか、Python の unittest)には、実行前に呼び出される setUp() 、実行後に呼び出させる tearDown() など便利な機能がたくさんありますし、フィクスチャーやモックなどを使わないといけないケースも出てくると思います。
テストの実装について、覚えることはまだたくさんあると思いますが、デグレのないシステムを実現するために、これからもテストを実装し続けていきたいと思います。