今天的實作內容主要根據教學網站進行。
接續前兩天的內容,今天將實作view的測試程式。
因為view的行為與使用者透過client送出的HTTP request息息相關,為了測試view,Django的測試模組提供了test client協助開發人員模擬瀏覽器行為。
response self.client.get('/track/book/')
response = self.client.post('/track/book/', data)
目前views.py有兩個view可進行測試:
BookListView:此為使用Django內建模組generic.ListView建立,僅需針對自己另外開發的邏輯進行測試即可。
TrackBook:這個view使用在表單上,故在測試上,針對表單行為 (初始化、表單驗證成功、表單驗證失敗)各種情境都須進行測試。
views.py中,BookListView使用內建模組建立ListView,並對於回傳資料做了條件篩選:
class BookListView(generic.ListView):
model = Book
template_name = 'book_list.html'
def get_queryset(self):
return Book.objects.filter(istrack=True)
在開發測試程式時,主要重點將放在
def test_view_url_exist_at_desired_location(self):
resp = self.client.get('/track/books/')
self.assertEqual(resp.status_code, 200)
def test_view_use_direct_template(self):
resp = self.client.get('/track/books/')
self.assertEqual(resp.status_code, 200)
self.assertTemplateUsed(resp,'book_list.html')
def setUpTestData(cls):
author = Author.objects.create(authorname='A')
number_of_book_track = 5
number_of_book_untrack = 5
for book_num in range(number_of_book_untrack):
book=Book.objects.create(title=str(book_num), authorid=author, istrack=False)
for book_num in range(number_of_book_track):
Book.objects.create(title=str(book_num + number_of_book_untrack), authorid=author, istrack=True)
def test_list_book_only_track(self):
resp = self.client.get('/track/books/')
self.assertEqual(resp.status_code, 200)
self.assertEqual(len(resp.context['book_list']), 5)
for book in resp.context['book_list']:
self.assertEqual(book.istrack, True)
views.py中,TrackBook主要任務如下:
使用三種回傳資料提供給template呈現:
form:表單資料
title_save:儲存成功時回傳書名,其他情況下回傳None
parsing_error:此變數為今日新增,主要因應URL無法解析時提供給template顯示錯誤訊息使用,發生問題時此變數為True
非POST Request(例如GET),回傳初始化表單,title_save=None,parsing_error=Falase
POST Request:如解析成功,回傳title_save=實際書名,parsing_error=False;解析時發生錯誤,回傳title_save=None,parsing_error=True
def TrackBook(request):
# If this is a POST request then process the Form data
if request.method == "POST":
form = TrackBookForm(request.POST)
if form.is_valid():
# 取得相關資訊
try:
newclawer = BookCrawler(form.cleaned_data['oriurl'])
newclawer.getinfo()
except:
return render(request, 'track_book.html', {'form': form, 'title_save': None, 'parsing_error': True})
#### 新增Author和Book,因程式較長這邊就省略不放####
return render(request, 'track_book.html', {'form': TrackBookForm(), 'title_save': record_book.title, 'parsing_error': False})
# If this is a GET (or any other method) create the default form.
else:
form = TrackBookForm(initial={'oriurl':None})
return render(request, 'track_book.html', {'form': form, 'title_save': None, 'parsing_error': False})
測試程式:
def test_view_url_exist_at_desired_location(self):
resp = self.client.get('/track/newtrack/')
self.assertEqual(resp.status_code, 200)
def test_view_use_direct_template(self):
resp = self.client.get('/track/newtrack/')
self.assertEqual(resp.status_code, 200)
self.assertTemplateUsed(resp,'track_book.html')
def test_form_initial_has_no_title_save(self):
resp = self.client.get('/track/newtrack/')
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.context['title_save'], None)
self.assertEqual(resp.context['parsing_error'], False)
def test_form_has_title_save_on_success(self):
formdata = {'oriurl': 'https://www.jjwxc.net/onebook.php?novelid=4918054'}
resp = self.client.post('/track/newtrack/', data=formdata)
expect_title_save = '剑名不奈何'
self.assertEqual(resp.context['title_save'], expect_title_save)
self.assertEqual(resp.context['parsing_error'], False)
def test_form_has_parsing_error_on_fail(self):
formdata = {'oriurl': 'https://www.jjwxc.net/onebook.php?novelid=4'}
resp = self.client.post('/track/newtrack/', formdata)
self.assertEqual(resp.context['title_save'], None)
self.assertEqual(resp.context['parsing_error'], True)