驗證
如今咱們已經完成了視圖的測試,讓咱們添加對錶單的驗證。但首先咱們要寫一個測試,驚喜吧!
-
在「tests」目錄下新增一個叫「test_validator.py」的文件並增長如下代碼:
01 |
from django.core.exceptions import ValidationError |
02 |
from django.test import TestCase |
03 |
from user_contacts.validators import validate_number, validate_string class ValidatorTest(TestCase): |
04 |
def test_string_is_invalid_if_contains_numbers_or_special_characters( self ): |
05 |
with self .assertRaises(ValidationError): |
06 |
validate_string( '@test' ) |
07 |
validate_string( 'tester#' ) |
08 |
def test_number_is_invalid_if_contains_any_character_except_digits( self ): |
09 |
with self .assertRaises(ValidationError): |
10 |
validate_number( '123ABC' ) |
11 |
validate_number( '75431#' ) |
-
在運行測試以前,你猜猜會有什麼狀況發生?提示:請密切注意代碼上面導入進來的包。你會有如下錯誤信息,由於咱們沒有「validators.py」文件:
1 |
ImportError: cannot import name validate_string |
換言之,咱們測試所需的邏輯驗證文件還不存在。
-
在「user_contacts」目錄下新增一個叫「validators.py」的文件:
1 |
import refrom django.core.exceptions import ValidationErrordef validate_string(string): |
2 |
if re.search( '^[A-Za-z]+$' , string) is None : |
3 |
raise ValidationError( 'Invalid' ) def validate_number(value): |
4 |
if re.search( '^[0-9]+$' , value) is None : |
5 |
raise ValidationError( 'Invalid' ) |
-
再次運行測試。5個測試會經過的:
1 |
Ran 5 tests in 0.019sOK |
新增聯繫人
-
因爲咱們增長了驗證,咱們想測試一下在管理員區域這個驗證功能是能夠工做的,因此更新「test_views.py」:
01 |
from django.template.loader import render_to_stringfrom django.test import TestCase, Clientfrom user_contacts.models import Person, Phonefrom user_contacts.views import * class ViewTest(TestCase): |
03 |
self .client_stub = Client() |
04 |
self .person = Person(first_name = 'TestFirst' ,last_name = 'TestLast' ) |
06 |
self .phone = Phone(person = self .person,number = '7778889999' ) |
08 |
def test_view_home_route( self ): |
09 |
response = self .client_stub.get( '/' ) |
10 |
self .assertEquals(response.status_code, 200 ) |
11 |
def test_view_contacts_route( self ): |
12 |
response = self .client_stub.get( '/all/' ) |
13 |
self .assertEquals(response.status_code, 200 ) |
14 |
def test_add_contact_route( self ): |
15 |
response = self .client_stub.get( '/add/' ) |
16 |
self .assertEqual(response.status_code, 200 ) |
17 |
def test_create_contact_successful_route( self ): |
18 |
response = self .client_stub.post( '/create' ,data = { 'first_name' : 'testFirst' , 'last_name' : 'tester' , 'email' : 'test@tester.com' , 'address' : '1234 nowhere' , 'city' : 'far away' , 'state' : 'CO' , 'country' : 'USA' , 'number' : '987654321' }) |
19 |
self .assertEqual(response.status_code, 302 ) |
20 |
def test_create_contact_unsuccessful_route( self ): |
21 |
response = self .client_stub.post( '/create' ,data = { 'first_name' : 'tester_first_n@me' , 'last_name' : 'test' , 'email' : 'tester@test.com' , 'address' : '5678 everywhere' , 'city' : 'far from here' , 'state' : 'CA' , 'country' : 'USA' , 'number' : '987654321' }) |
22 |
self .assertEqual(response.status_code, 200 ) |
兩個測試會失敗。 咱們要怎麼作才能讓測試經過呢?首先咱們要爲添加數據到數據庫增長一個視圖功能來查看。
-
添加路徑:
1 |
url(r '^create$' , create), |
-
更新「views.py」:
2 |
form = ContactForm(request.POST) if form.is_valid(): |
4 |
return HttpResponseRedirect( 'all/' ) return render(request, 'add.html' , { 'person_form' : form}, context_instance = RequestContext(request)) |
-
再次測試:
1 |
$ python manage.py test user_contacts |
此次只有一個測試會失敗 - AssertionError: 302 != 200 - 由於咱們嘗試添加一些不經過驗證的數據但添加成功了。換言之,咱們須要更新「models.py」文件中的表單都要把驗證考慮進去。
-
更新「models.py」:
01 |
from django.db import modelsfrom user_contacts.validators import validate_string, validate_numberclass Person(models.Model): |
02 |
first_name = models.CharField(max_length = 30 , validators = [validate_string]) |
03 |
last_name = models.CharField(max_length = 30 , validators = [validate_string]) |
04 |
email = models.EmailField(null = True , blank = True ) |
05 |
address = models.TextField(null = True , blank = True ) |
06 |
city = models.CharField(max_length = 15 , null = True ,blank = True ) |
07 |
state = models.CharField(max_length = 15 , null = True , blank = True , validators = [validate_string]) |
08 |
country = models.CharField(max_length = 15 , null = True , blank = True ) |
10 |
def __unicode__( self ): |
11 |
return self .last_name + ", " + self .first_nameclass Phone(models.Model): |
12 |
person = models.ForeignKey( 'Person' ) |
13 |
number = models.CharField(max_length = 10 , validators = [validate_number]) |
15 |
def __unicode__( self ): |
-
刪除當前的數據庫,「db.sqlite3」,從新同步數據庫:
1 |
$ python manage.py syncdb |
再次設置一個管理員帳戶。
-
新增驗證,更新new_contact_form.py:
01 |
import refrom django import formsfrom django.core.exceptions import ValidationErrorfrom user_contacts.models import Person, Phonefrom user_contacts.validators import validate_string, validate_numberclass ContactForm(forms.Form): |
02 |
first_name = forms.CharField(max_length = 30 , validators = [validate_string]) |
03 |
last_name = forms.CharField(max_length = 30 , validators = [validate_string]) |
04 |
email = forms.EmailField(required = False ) |
05 |
address = forms.CharField(widget = forms.Textarea, required = False ) |
06 |
city = forms.CharField(required = False ) |
07 |
state = forms.CharField(required = False , validators = [validate_string]) |
08 |
country = forms.CharField(required = False ) |
09 |
number = forms.CharField(max_length = 10 , validators = [validate_number]) |
12 |
data = self .cleaned_data |
13 |
person = Person.objects.create(first_name = data.get( 'first_name' ), last_name = data.get( 'last_name' ), |
14 |
email = data.get( 'email' ), address = data.get( 'address' ), city = data.get( 'city' ), state = data.get( 'state' ), |
15 |
country = data.get( 'country' )) |
16 |
phone = Phone.objects.create(person = person, number = data.get( 'number' )) |
-
再次運行測試,7個測試會經過的。
-
如今,先脫離開TDD一下子。我想在客戶端添加一個額外的測試驗證。因此添加test_contact_form.py:
1 |
from django.test import TestCasefrom user_contacts.models import Personfrom user_contacts.new_contact_form import ContactFormclass TestContactForm(TestCase): |
2 |
def test_if_valid_contact_is_saved( self ): |
3 |
form = ContactForm({ 'first_name' : 'test' , 'last_name' : 'test' , 'number' : '9999900000' }) |
5 |
self .assertEqual(contact.person.first_name, 'test' ) |
6 |
def test_if_invalid_contact_is_not_saved( self ): |
7 |
form = ContactForm({ 'first_name' : 'tes&t' , 'last_name' : 'test' , 'number' : '9999900000' }) |
9 |
self .assertEqual(contact, None ) |
-
運行測試,全部9個測試都經過了。耶!如今能夠提交代碼了。
|
頂 翻譯的不錯哦! |