iT邦幫忙

2021 iThome 鐵人賽

DAY 21
1
自我挑戰組

Python 30天自我挑戰系列 第 21

Day21 - 使用Django進行自動化測試 (3)

  • 分享至 

  • xImage
  •  

今天的實作內容主要根據教學網站進行。

接續前兩天的內容,今天將實作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可進行測試:

  1. BookListView:此為使用Django內建模組generic.ListView建立,僅需針對自己另外開發的邏輯進行測試即可。

  2. TrackBook:這個view使用在表單上,故在測試上,針對表單行為 (初始化、表單驗證成功、表單驗證失敗)各種情境都須進行測試。

BookListView

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)

在開發測試程式時,主要重點將放在

  • URL是否正確
  def test_view_url_exist_at_desired_location(self):
    resp = self.client.get('/track/books/')
    self.assertEqual(resp.status_code, 200)
  • 是否使用正確的template
  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')
  • 回傳資料的條件篩選是否正確
    為了測試這個情境,在測試初始化階段,需要先建立istrack=False和istrack=True兩種資料,盡量模擬出真實情境;在檢查時,同時檢查了回傳筆數與回傳資料的istrack屬性。
  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)

TrackBook

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})

測試程式:

  • URL是否正確
  def test_view_url_exist_at_desired_location(self):
    resp = self.client.get('/track/newtrack/')
    self.assertEqual(resp.status_code, 200)
  • 是否使用正確的template
  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')
  • 使用GET時,回傳資料情境是否正確
  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)
  • 使用POST並成功儲存資料
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)
  • 使用POST,但網址格式符合form檢核,但無法解析 (ex. 連結無法使用)
  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)

上一篇
Day20 - 使用Django進行自動化測試 (2)
下一篇
Day22 - 使用者身份驗證
系列文
Python 30天自我挑戰30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言