サービス側プログラミング(十五)-Django-自動化テスト入門
13306 ワード
文書ディレクトリ
前言´・ᴗ・`
基本概念
基本的ないくつかのテスト方法は次のとおりです.
テストフレームワークの問題
また、Djangoのデフォルトではunitestを使用しています.もちろん、クラシックなseleniumなど、他の既存のテストフレームワークと統合して遊ぶことができます.この記事に興味があるのは、pythonアプリケーション(6)--爬虫類(1)seleniumの概要です.
Googleにはjsベースの別のテストフレームワークがあります.これは現在の議論の範囲を超えています.もちろん、NodeJSを勉強するときにpuppeteerを遊ぶことができることを期待しています.
テスト範囲テストルール--何をテストしたいですか?
もちろんDjangoがパッケージ化されたアプリケーションをテストする必要はありません.肝心なのは私たちが書いたコードです.もちろん、私はmodelでlastを規定しています.name max_length=100はよく分からないと思いますか?なぜテストするの?
テストプロセス一覧
まずここではDjango内蔵のunitestライブラリを用いてテストを行うunitestが提供する多くのテストのパッケージをSimpleTestCase,TransactionTestCase,TestCase,LiveServerTestCaseなどにカプセル化して継承して運用しています
catalog/
/tests/
__init__.py
test_models.py
test_forms.py
test_views.py
テストルールファイルを置くためにtestsファイルを別途作成したtestが「テストキット」です
__init__
を見ると、キット内のファイルの名前に規範があるので、勝手に書いてはいけません.setUpTestData()
setUp()
python manage.py test
python3 manage.py test catalog.tests.test_models
などの特定のテストを実行し、テスト名testに注意する.catalog.test_modelこのフォーマットの書き方>python3 manage.py test
Creating test database for alias 'default'...
setUpTestData: Run once to set up non-modified data for all class methods.
setUp: Run once for every test method to setup clean data.
Method: test_false_is_false.
.setUp: Run once for every test method to setup clean data.
Method: test_false_is_true.
FsetUp: Run once for every test method to setup clean data.
Method: test_one_plus_one_equals_two.
.
======================================================================
FAIL: test_false_is_true (catalog.tests.tests_models.YourTestClass)
----------------------------------------------------------------------
Traceback (most recent call last):
File "D:\Github\django_tmp\library_w_t_2\locallibrary\catalog\tests\tests_models.py", line 22, in test_false_is_true
self.assertTrue(False)
AssertionError: False is not true
----------------------------------------------------------------------
Ran 3 tests in 0.075s
FAILED (failures=1)
Destroying test database for alias 'default'...
2つのポイントについて説明します.
テストの過程を完全に理解することは期待していませんが、大体の印象を持ってください.
次は実戦です.
Authorモデルのテスト
class Author(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
date_of_birth = models.DateField(null=True, blank=True)
date_of_death = models.DateField('Died', null=True, blank=True)
def get_absolute_url(self):
return reverse('author-detail', args=[str(self.id)])
def __str__(self):
return '%s, %s' % (self.last_name, self.first_name)
元のモデルにどのような制限があるかを見てtest_を作成しますModelはAuthorModelTestをtestCaseを採用しています.
from django.test import TestCase
from catalog.models import Author
class AuthorModelTest(TestCase):
@classmethod
def setUpTestData(cls):
#Set up non-modified objects used by all test methods
Author.objects.create(first_name='Big', last_name='Bob')
def test_first_name_label(self):
author=Author.objects.get(id=1)
field_label = author._meta.get_field('first_name').verbose_name
self.assertEquals(field_label,'first name')
def test_date_of_death_label(self):
author=Author.objects.get(id=1)
field_label = author._meta.get_field('date_of_death').verbose_name
self.assertEquals(field_label,'died')
def test_first_name_max_length(self):
author=Author.objects.get(id=1)
max_length = author._meta.get_field('first_name').max_length
self.assertEquals(max_length,100)
def test_object_name_is_last_name_comma_first_name(self):
author=Author.objects.get(id=1)
expected_object_name = '%s, %s' % (author.last_name, author.first_name)
self.assertEquals(expected_object_name,str(author))
def test_get_absolute_url(self):
author=Author.objects.get(id=1)
#This will also fail if the urlconf is not defined.
self.assertEquals(author.get_absolute_url(),'/catalog/author/1')
ここでは、いくつかの点に注意してください.
test_first_name_label(self):
つまり2番目の関数の末尾には、assertEquals(field_label,‘first name’)assertTrue(field_label=‘first name’)があります.フィードバック情報が多いので(first nameの実際の値を教えてください)フォームformsのテスト
実はテストモデルとあまり差がありません.私たちの図書館の応用は主にレンタル日です.これは元のformsをテストする必要があります.pyコード:
class RenewBookForm(forms.Form):
"""
Form for a librarian to renew books.
"""
renewal_date = forms.DateField(help_text="Enter a date between now and 4 weeks (default 3).")
def clean_renewal_date(self):
data = self.cleaned_data['renewal_date']
#Check date is not in past.
if data < datetime.date.today():
raise ValidationError(_('Invalid date - renewal in past'))
#Check date is in range librarian allowed to change (+4 weeks)
if data > datetime.date.today() + datetime.timedelta(weeks=4):
raise ValidationError(_('Invalid date - renewal more than 4 weeks ahead'))
# Remember to always return the cleaned data.
return data
これに対して、次のテストコードを設計しました.
/catalog/tests/test_forms.py
from django.test import TestCase
# Create your tests here.
import datetime
from django.utils import timezone
from catalog.forms import RenewBookForm
class RenewBookFormTest(TestCase):
def test_renew_form_date_field_label(self):
form = RenewBookForm()
self.assertTrue(form.fields['renewal_date'].label == None or form.fields['renewal_date'].label == 'renewal date')
def test_renew_form_date_field_help_text(self):
form = RenewBookForm()
self.assertEqual(form.fields['renewal_date'].help_text,'Enter a date between now and 4 weeks (default 3).')
def test_renew_form_date_in_past(self):
date = datetime.date.today() - datetime.timedelta(days=1)
form_data = {'renewal_date': date}
form = RenewBookForm(data=form_data)
self.assertFalse(form.is_valid())
def test_renew_form_date_too_far_in_future(self):
date = datetime.date.today() + datetime.timedelta(weeks=4) + datetime.timedelta(days=1)
form_data = {'renewal_date': date}
form = RenewBookForm(data=form_data)
self.assertFalse(form.is_valid())
def test_renew_form_date_today(self):
date = datetime.date.today()
form_data = {'renewal_date': date}
form = RenewBookForm(data=form_data)
self.assertTrue(form.is_valid())
def test_renew_form_date_max(self):
date = timezone.now() + datetime.timedelta(weeks=4)
form_data = {'renewal_date': date}
form = RenewBookForm(data=form_data)
self.assertTrue(form.is_valid())
ここで、転送データはキー値ペアの形式を採用し、この「renewal_date」は確かにクラス属性に由来し、クラスインスタンスの
is_valid()
を呼び出してテストを断言します. date = datetime.date.today() - datetime.timedelta(days=1)
form_data = {'renewal_date': date}
form = RenewBookForm(data=form_data)
self.assertFalse(form.is_valid())
ビューのテスト
ここでauthorの検証を例に挙げると、実際に私たちの多くの仕事はdjangoに検証する必要はありません.ここでは栗/catalog/tests/test_を挙げるだけです.views.py
from django.test import TestCase
# Create your tests here.
from catalog.models import Author
from django.urls import reverse
class AuthorListViewTest(TestCase):
@classmethod
def setUpTestData(cls):
#Create 13 authors for pagination tests
number_of_authors = 13
for author_num in range(number_of_authors):
Author.objects.create(first_name='Christian %s' % author_num, last_name = 'Surname %s' % author_num,)
def test_view_url_exists_at_desired_location(self):
resp = self.client.get('/catalog/authors/')
self.assertEqual(resp.status_code, 200)
def test_view_url_accessible_by_name(self):
resp = self.client.get(reverse('authors'))
self.assertEqual(resp.status_code, 200)
def test_view_uses_correct_template(self):
resp = self.client.get(reverse('authors'))
self.assertEqual(resp.status_code, 200)
self.assertTemplateUsed(resp, 'catalog/author_list.html')
def test_pagination_is_ten(self):
resp = self.client.get(reverse('authors'))
self.assertEqual(resp.status_code, 200)
self.assertTrue('is_paginated' in resp.context)
self.assertTrue(resp.context['is_paginated'] == True)
self.assertTrue( len(resp.context['author_list']) == 10)
def test_lists_all_authors(self):
#Get second page and confirm it has (exactly) remaining 3 items
resp = self.client.get(reverse('authors')+'?page=2')
self.assertEqual(resp.status_code, 200)
self.assertTrue('is_paginated' in resp.context)
self.assertTrue(resp.context['is_paginated'] == True)
self.assertTrue( len(resp.context['author_list']) == 3)
ここではまず彼がページを分けて13のデータを作ったかどうかを検証します.
number_of_authors = 13
for author_num in range(number_of_authors):
Author.objects.create(first_name='Christian %s' % author_num, last_name = 'Surname %s' % author_num,)
あとで断言する
self.assertTrue('is_paginated' in resp.context)
self.assertTrue(resp.context['is_paginated'] == True)
self.assertTrue( len(resp.context['author_list']) == 10)
さらに重要なのはurlマッピングとreverse逆マッピングをテストすることですclient.get実装:)
def test_view_url_exists_at_desired_location(self):
resp = self.client.get('/catalog/authors/')
self.assertEqual(resp.status_code, 200)
def test_view_url_accessible_by_name(self):
resp = self.client.get(reverse('authors'))
self.assertEqual(resp.status_code, 200)
まとめ´◡`
自動化テストはまた1つの大学が個人に聞くのは先に焦らないで勉強します