Djangoメモ(9) : ビューのテストを作成して実行する
A Complete Beginner's Guide to Djangoのチュートリアルを参考にビューのテストを作成して実行してみる。
テストを実行する
Djangoのテストはpython manage.py test
コマンドで実行できる。現時点でテストは作成していないので当然何も実行されない。
$ python manage.py test Creating test database for alias 'default'... System check identified no issues (0 silenced). ---------------------------------------------------------------------- Ran 0 tests in 0.000s OK Destroying test database for alias 'default'...
ビューのテストを作成する
チュートリアル通りにboards/test.py
を編集。
このテストは前回作成したhome
のレスポンスのステータスコードが200 OK
であるか確認するテスト。
変更前
from django.test import TestCase # Create your tests here.
変更後
from django.core.urlresolvers import reverse from django.test import TestCase class HomeTests(TestCase): def test_home_view_status_code(self): url = reverse('home') response = self.client.get(url) self.assertEquals(response.status_code, 200)
編集後、実行したがエラーとなってしまった。
$ python manage.py test Creating test database for alias 'default'... System check identified no issues (0 silenced). E ====================================================================== ERROR: boards.tests (unittest.loader._FailedTest) ---------------------------------------------------------------------- ImportError: Failed to import test module: boards.tests Traceback (most recent call last): File "/home/vagrant/.pyenv/versions/3.6.4/lib/python3.6/unittest/loader.py", line 428, in _find_test_path module = self._get_module_from_name(name) File "/home/vagrant/.pyenv/versions/3.6.4/lib/python3.6/unittest/loader.py", line 369, in _get_module_from_name __import__(name) File "/home/vagrant/django/myproject/myproject/boards/tests.py", line 1, in <module> from django.core.urlresolvers import reverse ModuleNotFoundError: No module named 'django.core.urlresolvers' ---------------------------------------------------------------------- Ran 1 test in 0.000s FAILED (errors=1) Destroying test database for alias 'default'...
調べたところ、ビューからURLに変換してくれるreverse()
関数はDjango 2.0ではdjango.urls
に変わったようなので修正する。
# from django.core.urlresolvers import reverse from django.urls import reverse
これでテストが通るようになる。
$ python manage.py test Creating test database for alias 'default'... System check identified no issues (0 silenced). . ---------------------------------------------------------------------- Ran 1 test in 0.045s OK Destroying test database for alias 'default'...
次にもう一つテストを追加する。
resolve()
はURLからビューに変換する関数でresolve('/')
の場合はhome
に変換される。
from django.urls import reverse, resolve from django.test import TestCase from .views import home class HomeTests(TestCase): def test_home_view_status_code(self): url = reverse('home') response = self.client.get(url) self.assertEquals(response.status_code, 200) def test_home_url_resolves_home_view(self): view = resolve('/') self.assertEquals(view.func, home)
再びテストを実行してOK
になることを確認する。
3行目の部分はテストが成功している場合は..
のような表示になり、エラーがあるとE.
のような表示(2つあるテストの最初がエラー)になる。
$ python manage.py test Creating test database for alias 'default'... System check identified no issues (0 silenced). .. ---------------------------------------------------------------------- Ran 2 tests in 0.019s OK Destroying test database for alias 'default'...
verbosityオプション
テストの詳細を出力したい場合は--verbosity
オプション(0〜3)を指定する。
それぞれのレベルの出力は以下の通り。
0=minimal output
$ python manage.py test --verbosity 0 System check identified no issues (0 silenced). ---------------------------------------------------------------------- Ran 2 tests in 0.020s OK
1=normal output
$ python manage.py test --verbosity 1 Creating test database for alias 'default'... System check identified no issues (0 silenced). .. ---------------------------------------------------------------------- Ran 2 tests in 0.019s OK Destroying test database for alias 'default'...
2=verbose output
クリックで展開
$ python manage.py test --verbosity 2
Creating test database for alias 'default' ('file:memorydb_default?mode=memory&cache=shared')...
Operations to perform:
Synchronize unmigrated apps: django_extensions, messages, staticfiles
Apply all migrations: admin, auth, boards, contenttypes, sessions
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying boards.0001_initial... OK
Applying sessions.0001_initial... OK
System check identified no issues (0 silenced).
test_home_url_resolves_home_view (boards.tests.HomeTests) ... ok
test_home_view_status_code (boards.tests.HomeTests) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.021s
OK
Destroying test database for alias 'default' ('file:memorydb_default?mode=memory&cache=shared')...
3=very verbose output
クリックで展開
$ python manage.py test --verbosity 3
Creating test database for alias 'default' ('file:memorydb_default?mode=memory&cache=shared')...
Operations to perform:
Synchronize unmigrated apps: django_extensions, messages, staticfiles
Apply all migrations: admin, auth, boards, contenttypes, sessions
Running pre-migrate handlers for application boards
Running pre-migrate handlers for application admin
Running pre-migrate handlers for application auth
Running pre-migrate handlers for application contenttypes
Running pre-migrate handlers for application sessions
Running pre-migrate handlers for application django_extensions
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Running migrations:
Applying contenttypes.0001_initial... OK (0.008s)
Applying auth.0001_initial... OK (0.029s)
Applying admin.0001_initial... OK (0.024s)
Applying admin.0002_logentry_remove_auto_add... OK (0.019s)
Applying contenttypes.0002_remove_content_type_name... OK (0.040s)
Applying auth.0002_alter_permission_name_max_length... OK (0.010s)
Applying auth.0003_alter_user_email_max_length... OK (0.029s)
Applying auth.0004_alter_user_username_opts... OK (0.037s)
Applying auth.0005_alter_user_last_login_null... OK (0.021s)
Applying auth.0006_require_contenttypes_0002... OK (0.001s)
Applying auth.0007_alter_validators_add_error_messages... OK (0.017s)
Applying auth.0008_alter_user_username_max_length... OK (0.017s)
Applying auth.0009_alter_user_last_name_max_length... OK (0.016s)
Applying boards.0001_initial... OK (0.110s)
Applying sessions.0001_initial... OK (0.005s)
Running post-migrate handlers for application boards
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Running post-migrate handlers for application admin
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Running post-migrate handlers for application auth
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Running post-migrate handlers for application contenttypes
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Running post-migrate handlers for application sessions
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Adding permission 'Permission object (None)'
Running post-migrate handlers for application django_extensions
System check identified no issues (0 silenced).
test_home_url_resolves_home_view (boards.tests.HomeTests) ... ok
test_home_view_status_code (boards.tests.HomeTests) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.022s
OK
Destroying test database for alias 'default' ('file:memorydb_default?mode=memory&cache=shared')...
まとめ
- テストは
python manage.py test
コマンドで実行 - テストの作成は
test.py
を編集 reverse()
はビューからURLに変換する関数で、Django 2.0ではfrom django.urls import reverse()
resolve()
はURLからビューに変換する関数--verbosity
オプションで出力レベルを変更可能