Django框架自动化测试

【图书介绍】《Django 5企业级Web应用开发实战(视频教学版)》_django 5企业级web应用开发实战(视频教学版)-CSDN博客

《Django 5企业级Web应用开发实战(视频教学版)》(王金柱)【摘要 书评 试读】- 京东图书 (jd.com)

本节介绍关于Django框架自动化测试的内容,自动化测试是实际项目开发中必不可少的工具。

8.2.1  自动化测试概述

对于使用Django框架的Web开发人员而言,自动化测试是一个非常有用的解决Bug的工具。设计人员可以使用一组测试(一个测试套件)来解决或避免许多问题,具体包括:

(1)在编写新代码时,可以使用测试来验证代码是否按预期进行工作。

(2)重构或修改旧代码时,可以使用测试来确保所做的更改不会意外影响应用程序的行为。

测试Web应用程序是一项复杂的工作,因为Web应用程序通常是由几层逻辑组成的,从HTTP级别的请求处理到表单验证与处理,再到模板渲染等。借助Django的测试执行框架和各种实用程序,可以实现模拟HTTP请求、插入测试数据、检查应用程序的输出,以及验证常规代码是否在执行其应该做的事情。

8.2.2  编写和运行自动化测试

本小节主要分为两个部分,首先是说明如何使用Django框架编写测试,然后解释如何运行这些测试。学习完本小节的内容后,读者会发现Django框架的自动化测试确实很容易。

Django框架的单元测试使用了Python标准库模块unittest,该模块使用基于类的方法来定义测试。这里使用django.test.TestCase子类进行单元测试,django.test.TestCase是unittest.TestCase的子类,在事务中运行每个测试以提供独立的方式。

在编写实际测试用例之前,先简单介绍一下TestCase类的结构。常见的TestCase类由test_func()函数、setUp()函数和tearDown()函数组成。

  • test_func()是指实际编写了测试逻辑的函数。
  • setUp()函数是在test_func()函数之前执行的函数,常用于测试之前的初始化操作。
  • tearDown()函数是在test_func()函数之后执行的函数,常用于测试结束之后的收尾操作。

首先,我们创建一个用于自动化测试的项目MyTestSite,并添加一个应用testapp。然后,创建一个用于测试的模型,具体代码如下:

【代码8-1】(详见源代码MyTestSite项目的testapp/models.py文件)

01  from django.db import models
02  
03  # 在此处创建模型
04  class Students(models.Model):
05      name = models.CharField(max_length=32)
06      age = models.IntegerField()

【代码分析】

在第01行代码中,通过import关键字引入models模块。

在第04~06行代码中,创建了一个学生模型Students,继承自models.Model模型类。详细说明如下:

在第05行代码中,创建了一个CharField类型的name字段属性。

在第06行代码中,创建了一个IntegerField类型的age字段属性。

接下来,我们就可以在tests.py(创建应用时默认已存在)文件中编写自动化测试的代码了,具体如下:

【代码8-2】(详见源代码MyTestSite项目的testapp/tests.py文件)

01  from django.test import TestCase
02  
03  from .models import Students
04  
05  # Create your tests here.
06  class ModelTest(TestCase):
07      def setUp(self):
08          Students.objects.create(name='cici', age=7)
09          pass
10  
11      def test_students_model(self):
12          s = Students.objects.get(name='cici')
13          self.assertEqual(s.name, 'cici')
14          pass
15  
16      def tearDown(self):
17          pass

【代码分析】

在第01行代码中,通过import关键字引入TestCase模块。

在第03行代码中,通过import关键字引入测试代码中需要的Students模型。

在第06~17行代码中,创建了一个测试类ModelTest,继承自TestCase测试类,详细说明如下:

  • 在第07~09行代码中,在setUp()函数中进行了Students模型的初始化操作。在第08行代码中,创建了一条Students模型的学生数据(name='cici', age=7),我们将使用这条数据进行测试  演示。
  • 在第11~14行代码中,定义了一个测试方法test_students_model(),包含一个自身的self参数。注意,方法名称必须以“test”开头。其中,第13行代码通过self调用assertEqual()方法进行测试,判断学生的姓名是否与测试要求一致。
  • 在第16、17行代码中,定义了tearDown()函数,这里没有定义实际的操作代码。

下面,我们通过命令行指令python manage.py test app进行自动化测试,效果如图8.1所示。

图8.1  MyTestSite项目自动化测试(1)

图8.1显示的是测试成功的情况,如果测试时发现错误会是什么情况呢?下面我们对【代码8-2】稍加修改,加入一些错误测试,具体代码如下:

【代码8-3】(详见源代码MyTestSite项目的testapp/tests.py文件)

01  from django.test import TestCase
02  
03  from .models import Students
04  
05  # Create your tests here.
06  class ModelTest(TestCase):
07      def setUp(self):
08          Students.objects.create(name='cici', age=7)
09          pass
10  
11      def test_students_model(self):
12          s = Students.objects.get(name='cici')
13          self.assertEqual(s.name, 'cici')
14          self.assertEqual(s.age, 8)
15          pass
16  
17      def tearDown(self):
18          pass

【代码分析】

在第14行代码中,通过self调用assertEqual()方法进行测试,判断学生的年龄是否与测试要求一致。

下面,我们再次通过命令行指令python manage.py test app进行自动化测试,效果如图8.2所示。初始化学生的年龄为7,当我们测试年龄值是否等于8时,给出了错误提示信息(很清楚提示了“7 != 8”)。

图8.2  MyTestSite项目自动化测试(2)

8.2.3  数据库自动化测试

本小节基于前一小节介绍的Django项目(MyTestSite)介绍数据库自动化测试的过程。

首先,完善一下用于测试的模型,具体代码如下:

【代码8-4】(详见源代码MyTestSite项目的testapp/models.pym文件)

01  from django.db import models
02  
03  # 在此处创建模型
04  class Teachers(models.Model):
05      name = models.CharField(max_length=32)
06      pass
07  
08  class Clazz(models.Model):
09      name = models.CharField(max_length=16)
10      teachers = models.ManyToManyField(Teachers)
11      pass
12  
13  class Students(models.Model):
14      name = models.CharField(max_length=32)
15      age = models.IntegerField()
16      clazz = models.ForeignKey(Clazz, on_delete=models.CASCADE)
17      pass

【代码分析】

在第01行代码中,通过import关键字引入models模块。

在第04~06行代码中,创建了一个教师模型Teachers,继承自models.Model模型类,详细说明如下:

  • 在第05行代码中,创建了一个CharField类型的name字段属性。

在第08~11行代码中,创建了一个班级模型Clazz,继承自models.Model模型类,详细说明如下:

  • 在第09行代码中,创建了一个CharField类型的name字段属性。
  • 在第10行代码中,创建了一个与教师模型Teachers多对多关系的字段属性teachers。

在第13~17行代码中,创建了一个学生模型Students,继承自models.Model模型类,详细说明如下:

  • 在第14行代码中,创建了一个CharField类型的name字段属性。
  • 在第15行代码中,创建了一个IntegerField类型的age字段属性。
  • 在第16行代码中,创建了一个班级模型Clazz的外键字段属性clazz。

然后,我们就可以在tests.py(创建应用时默认已存在)文件中编写自动化测试的代码了,具体如下:

【代码8-5】(详见源代码MyTestSite项目的testapp/tests.py文件)

01  from django.test import TestCase
02  
03  from .models import Teachers, Clazz, Students
04  
05  # Create your tests here.
06  class ModelTest(TestCase):
07      def setUp(self):
08          t1 = Teachers.objects.create(name='liu')
09          t2 = Teachers.objects.create(name='guan')
10          t3 = Teachers.objects.create(name='zhang')
11          c = Clazz.objects.create(name='A1')
12          c.save()
13          c.teachers.add(t1)
14          c.teachers.add(t2)
15          c.teachers.add(t3)
16          c.save()
17          Students.objects.create(name='cici', age=7, clazz=c)
18          pass
19  
20      def test_teachers_model(self):
21          t1 = Teachers.objects.get(name='liu')
22          self.assertEqual(t1.name, 'liu')
23          t2 = Teachers.objects.get(name='guan')
24          self.assertEqual(t2.name, 'guan')
25          t3 = Teachers.objects.get(name='zhang')
26          self.assertEqual(t3.name, 'zhang')
27          pass
28  
29      def test_clazz_model(self):
30          t1 = Teachers.objects.get(name='liu')
31          t2 = Teachers.objects.get(name='guan')
32          t3 = Teachers.objects.get(name='zhang')
33          c = Clazz.objects.get(name='A1')
34          self.assertEqual(c.name, 'A1')
35          self.assertIn(t1, c.teachers.all())
36          self.assertIn(t2, c.teachers.all())
37          self.assertIn(t3, c.teachers.all())
38          pass
39  
40      def test_students_model(self):
41          s = Students.objects.get(name='cici')
42          self.assertEqual(s.name, 'cici')
43          c = Clazz.objects.get(name='A1')
44          self.assertEqual(s.clazz, c)
45          pass
46  
47      def tearDown(self):
48          pass

【代码分析】

在第07~18行代码中,在setUp()函数中分别对Teachers模型、Clazz模型和Students模型进行了初始化操作。

在第20~27行代码、第29~38行代码和第40~45行代码中,分别定义了一组测试方法test_teachers_model()、test_clazz_model()和test_students_model(),具体说明如下:

  • 在第35~37行代码中,分别通过self调用assertIn()方法进行测试,用于判断3个教师模型对象t1、t2和t3是否包含在班级模型Clazz的教师字段teachers里。
  • 在第44代码中,通过self调用assertEqual()方法进行测试,判断学生模型Students的外键clazz是否与班级模型Clazz的字段c一致。

下面,我们通过命令行指令python manage.py test app进行自动化测试,效果如图8.3所示。

图8.3  MyTestSite项目数据库自动化测试(1)

图8.3显示的是测试成功的情况,下面我们对【代码8-6】稍加修改,加入一些错误测试,具体代码如下:

【代码8-6】(详见源代码MyTestSite项目的testapp/tests.py文件)

01  from django.test import TestCase
02  
03  from .models import Teachers, Clazz, Students
04  
05  # Create your tests here.
06  class ModelTest(TestCase):
07      def setUp(self):
08          t1 = Teachers.objects.create(name='liu')
09          t2 = Teachers.objects.create(name='guan')
10          t3 = Teachers.objects.create(name='zhang')
11          c = Clazz.objects.create(name='A1')
12          c.save()
13          c.teachers.add(t1)
14          c.teachers.add(t2)
15          c.teachers.add(t3)
16          c.save()
17          Students.objects.create(name='cici', age=7, clazz=c)
18          pass
19  
20      def test_teachers_model(self):
21          t1 = Teachers.objects.get(name='liu')
22          self.assertEqual(t1.name, 'liu')
23          t2 = Teachers.objects.get(name='guan')
24          self.assertEqual(t2.name, 'guan')
25          t3 = Teachers.objects.get(name='zhang')
26          self.assertEqual(t3.name, 'zhang')
27          pass
28  
29      def test_clazz_model(self):
30          t1 = Teachers.objects.get(name='liu')
31          t2 = Teachers.objects.get(name='guan')
32          t3 = Teachers.objects.get(name='zhang')
33          c = Clazz.objects.get(name='A1')
34          self.assertEqual(c.name, 'A1')
35          self.assertIn(t1, c.teachers.all())
36          self.assertIn(t2, c.teachers.all())
37          self.assertNotIn(t3, c.teachers.all())
38          pass
39  
40      def test_students_model(self):
41          s = Students.objects.get(name='cici')
42          self.assertEqual(s.name, 'cici')
43          c = Clazz.objects.get(name='A1')
44          self.assertEqual(s.clazz, c)
45          pass
46  
47      def tearDown(self):
48          pass

【代码分析】

在第37行代码中,将通过self调用的assertIn()方法修改为assertNotIn()方法进行测试,判断教师模型对象t3是否不包含在班级模型Clazz的教师字段teachers里。

下面,我们再次通过命令行指令python manage.py test app进行自动化测试,效果如图8.4所示。因为教师模型对象t3包含在班级模型Clazz的教师字段teachers里,所以使用assertNotIn()方法进行测试时给出了相应的错误提示信息。

图8.4  MyTestSite项目数据库自动化测试(2)

  • 10
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值