Day21 - 使用Django进行自动化测试 (3)

今天的实作内容主要根据教学网站进行。

接续前两天的内容,今天将实作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)

<<:  19 | WordPress 表格区块 Table Block

>>:  Day18 - this&Object Prototypes Ch3 Objects - Iteration 开头

Ruby on Rails Controller

第 1 步 - 新增 Route 别忘了,使⽤者想要看到你网站上的内容,第⼀步是要问过 Route,...

Day 1 - 浅谈 Kubernetes 的架设与管理

本文将於赛後同步刊登於笔者部落格 有兴趣学习更多 Kubernetes/DevOps/Linux 相...

[Day11]PHP函数01

PHP函数 自定义函数 函数可用以下语法来定义 <?php function foo($arg...

[Day 26] Android Studio 七日陨石开发:嘘! 我正在监听这个元件

前言 昨天我们设计好UI介面後, 我们有一堆按钮和文字框的"元件", 要让这些元...

[Day 30] 结算成果!铁人赛真的结束了吗?!

终於~~~ 来到了第30天啦 不管有没有做完,都该来结算一下成果了 来看看目前的专案跟一开始规划的完...