Skip to content
RonDen edited this page May 16, 2019 · 1 revision

软件测试

不会写测试的软件工程师不是一个好的软件工程师。

对Django进行单元测试

单元测试(Unittest)对于开发出好的软件来说(提前找到Bug,性能优化,提高开发效率)的重要性毋庸置疑,Python常用 的单元测试工具有unittest和mock、pytest等第三方包。但是对于Django而言,有很好的选择。

在每个APP下都有一个tests.py文件,这个文件用来做单元测试,其中导入了TestCase类,我们就是用它来做测试。Django封装了unittes类(继承)为TestCase,一般来说我们编写自己的测试类要继承TestCase。在其中定义自己的测试方法,每个方法都以test_开头,简单的命名方式为:test_+测试方法名,i_e.: test_student_view_score

但编写好测试类和测试方法时,执行:

python manage.py test

便会自动执行测试,并且可以看到测试的执行耗费时间。启动可能会有点慢,因为默认会创建一个数据库(名为:test_+项目数据库名),并且会执行迁移migrate。但是实际测试时很快的,很适合与CI工具集成测试。

关于TestCase用法的几点说明:

  1. TestCase默认有setUp()tearDown()方法,用来做执行测试前的一些初始化工作,比如创建数据库,登录用户等。其执行顺序为
setUp()
test_method1()
tearDown()
setUp()
test_method2()
tearDown()
...

即会单独的为每个测试方法前后执行一次。我一般用来登录用户保存session。

  1. self.client是默认的一个客户端对象,非常重要,可以用来模拟用户提供http请求,如POST/GET等,以及提供数据。需要掌握使用,用Client类来测试自己项目APP下面的每一个URL和view是否正确工作,可以有助于发现Bug。避免提交了再补锅救火。

常用方法:

url = ""
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'login.html')

url = '/mylogin'
response = self.client.post(url, data=self.log_data)
self.assertIn(response.status_code, [200, 301, 302])

注意:千万注意,这里的url测试的是你在浏览器中访问时127.0.0.1后面的东西,但是要有开始的那个/,而不能有最后那个/,否则会404 Not Found。 i_e: /scoreManagement/stu_view_score: 正确✔

/scoreManagement/stu_view_score/: 错误

scoreManagement/stu_view_score/: 错误

/scoreManagement//stu_view_score/: 错误

/mylogin: 正确✔

/mylogin/: 错误

mylogin: 错误

assertEqual判断状态码是否是200,如果是404、500、403等,必然是错误,不能上线。

这里的状态码可能是302或者301表示重定向,是正常的,可以用assertIn判断。assertTemplateUsed用来判断是否使用了正确的模板页面,避免错误。同时可以使用assertIn判断关心的内容是否在页面中。一般常用的断言方法也就这几个,更多可以自己查看。

response是一个Response对象,有很多方法,比如查看状态码,返回内容等。

  1. python manage.py test会执行项目所有的测试,为了避免打印太多或者其他项目干扰,可以只执行自己项目中的测试,或者只执行一个测试类、一个测试方法:
python manage.py test # 执行所有测试,一般用于集成测试
python manage.py test scoreManagement # 只执行成绩管理测试
python manage.py test scoreManagement.tests.AdmTest # 只执行成绩管理下面的对管理员行为的测试
python manage.py test scoreManegement.tests.AdmTest.test_login # 只执行登录测试
  1. 关注测试的代码覆盖率,不能水测试,一定要对URL和views.py下面的每个用到的函数都做测试!
  2. 一个比较完整的测试样例如下:
class TestStudent(TestCase):
    # 测试初始化函数,每次执行下面的函数之前都会执行这个函数
    # 这里用来创建用户和登录用户,保存session信息
    def setUp(self) -> None:
        # 用mixer这个库用来创建随机的数据
        # 可以递归地创建多层次的外键
        student1 = mixer.blend(Student)
        student1.username = '2016000474'
        # 对密码进行加密
        student1.password = make_encode('2016000474')
        student1.save()
        self.login_data = {
            'username': student1.username,
            'password': student1.username
        }
        data = {
            'username': '2016000474',
            'password': '2016000474'
        }

        url = ""
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'login.html')

        # 发出一个post请求,并且发送登录的数据
        response = self.client.post('/mylogin', self.login_data)
        self.assertIn(response.status_code, [200, 301, 302])

    def test_student_view_score(self):
        # 发出一个get请求,测试这个url是否正确
        response = self.client.get('/scoreManagement/student_view_score')
        self.assertIn(response.status_code, [200, 301, 302])

    def test_student_view_own_study(self):
        response = self.client.get('/scoreManagement/student_own_study')
        self.assertIn(response.status_code, [200, 301, 302])

    def test_student_view_major_course(self):
        response = self.client.get('/scoreManagement/std_view_major_course')
        self.assertIn(response.status_code, [200, 301, 302])

    def test_student_view_major_plan(self):
        response = self.client.get('/scoreManagement/std_view_major_plan')
        self.assertIn(response.status_code, [200, 301, 302])

具体的测试可以查看scoreMangement下的测试文件:test.py

使用Travis CI和Codecov

始于颜值,陷于才华。为了徽章我也要做集成测试!

Travis CI和Codecov能够对项目进行集成测试和测试覆盖率分析,开源免费,而且对github支持很好。每次提交的代码都会在Travis CI上自动测试,写好配置文件后不需要关心。而且可以自己配置测试矩阵、对不同版本和操作系统进行测试。

  1. 注册账号

Travis CI官网上注册账号,用github账号关联,选择需要测试的项目。

Codecov上注册账号,用github账号关联,选择项目。

  1. 编写.travis.yml配置文件

Travis CI是通过配置文件进行测试的,语法比较简单,了解一下yml语法就可以,而且可以参考其他的项目配置。本项目的集成测试配置如下:.travis.yml

注意每次提交Push/PR都会被自动拉取测试,如果失败了项目首页Build Status: Build Status就会显示failing,因此不能乱提交

  1. 关联Codecov后,简单修改.travis.yaml就可以在Codecov上看到代码覆盖率分析了。

需要注意的是:原来运行Django项目测试用

python manage.py test

如果要添加分析功能,使用命令行

coverage run manage.py test
  1. 要尽量提高代码覆盖率,对每一个URL做测试。
Clone this wiki locally