皆さん当たり前のように書かれているテストですが、テストやったことないプログラミング初心者である私からすると、テストが何を行っているかまったくわからないこともあります。そのため、Djangoのテストでわからない部分を調べて忘備録として残しておくことにしました。
ネットやYoutube、書籍で出会ったテストでわかりそうな範囲で調べられることを見つけ次第、追加していきたいと思います。(注意)あくまで素人が推測をもとに書いていることにご注意ください。
そもそもテストとはなんなのか
これはウェブサービスを作ることを前提にした話ですが、作ったシステムが正常に動作するかどうかそのサイトに触れることなく確認できる仕組みのことなのかな、と思っています。そしてテストコードを書き溜めていくと、たくさんのチェックが瞬時にできるようになるので便利、といったこともテストの持つ利点の一つなのでしょう。
assert〜から始まる関数
assertは「断言する・主張する」といった意味の動詞です。ここからassertEqual
などの関数は、「(2つの値が)イコールであることを確認する」といった意味になると推測できます。
下記の表はPython公式ドキュメントのUnittestに掲載されている、一般的に最もよく使用されるメソッドです。これを見れば大体のメソッドはプログラミングでよく使う比較演算子と同じだということがわかります。
メソッド | 確認事項 | 初出 |
---|---|---|
assertEqual(a, b) | a == b | |
assertNotEqual(a, b) | a != b | |
assertTrue(x) | bool(x) is True | |
assertFalse(x) | bool(x) is False | |
assertIs(a, b) | a is b | 3.1 |
assertIsNot(a, b) | a is not b | 3.1 |
assertIsNone(x) | x is None | 3.1 |
assertIsNotNone(x) | x is not None | 3.1 |
assertIn(a, b) | a in b | 3.1 |
assertNotIn(a, b) | a not in b | 3.1 |
assertIsInstance(a, b) | isinstance(a, b) | 3.2 |
assertNotIsInstance(a, b) | not isinstance(a, b) | 3.2 |
DjangoにおけるTestCaseはPythonのunittestのクラスであるTestCaseを継承して作られたものです。そこにDjango独自のassertTemplateUsed
などの関数を加えているのだと思います。
テストは基本的に比べる対象をある条件をもとに設定し、最後にassert関数で合否判定して問題なければクリア、という流れになるんだと理解してます。このテストを python manage.py test
で実行すれば色々な機能が一瞬でチェック出来るようになります。
テスト実例
assertEqual でurlとビューの一致を確認
from django.test import TestCase
from django.urls import resolve
from .views import post_new
class CreatePostTest(TestCase):
def test_should_resolve_post_new(self):
found = resolve('/post/new/')
self.assertEqual(post_new, found.func)
まずresolveが何してるのかさっぱりわかりませんでした。print
してみるとresolve('/post/new/')
の引数に対して以下のような値が帰ってくることがわかりました。
ResolverMatch(
func=post.views.add_post,
args=(), kwargs={}, url_name=new,
app_names=[], namespaces=[], route=
)
foundに格納されたfuncはどうやら引数のpathに対応するファンクションビューを取得していたようです。url_name
にはurls.pyで設定したnameも取得されています。そしてassertEqualでviewからインポートしたpost_newと取得したfuncが等しいかどうか確認してます。
要するにこれは特定のURLに対してビューとurls.pyのパスが設定されているかどうかを確認するテストだったようです。
assertContains で特定の文字列が含まれているかテスト
def test_top_page_returns_200_and_expected_title(self):
response = self.client.get('/')
self.assertContains(response, "Django", status_code=200)
assertContainsは特定の文字列を含むかどうかチェックします。この場合は「Django」という文字列が含まれているかどうかに加え、status_codeの確認も同時に行っています。
assertTemplateUsed で特定のテンプレートが使われているかテスト
def test_top_page_uses_expected_template(self):
response = self.client.get('/')
self.assertTemplateUsed(response, "posts/top.html")
assertTemplateUsedは指定されたテンプレートがレスポンスのレンダリングに使用されたかどうか確認するものです。この場合は「/」に「posts/top.html」が使用されているかどうかを確認しています。
コメント