UnitTest 测试框架

测试用例testcase

这是 UnitTest 中最重要的概念,测试就是由一个个测试用例组成的,而对于测试框架来说测试用
例就是最底层的东西,就像盖一座房子一样,砖头就是最基础的东西,无论怎么设计和搭建,最终都 是要靠一块块砖头堆砌而成。测试用例既可以是对同一个测试点的不同输入,也可以是对不同测试点 的不同输入,也可以是对多个测试点的组合测试,就看如何设计组合测试用例,但一般适用于前两者
UnitTest 模块中,需要通过继承 TestCase 类来构建单元测试用例
class 测试类名(unittest.TestCase):
测试用例
既可以一个测试用例生成一个类,也可以多个测试用例生成一个类,考虑到执行效率的问题,
建议使用后者来构建测试用例
class 测试类名(unittest.TestCase):
测试用例 1
测试用例 2
测试用例 3 
…
一个测试用例可以通过定义一个函数完成,将执行测试的代码封装到函数内,最后通过
TaseCase 类中的断言来判断测试是否通过,常用的断言方法有以下几种。
assertEqual (预期值,实际值)当两者相等的时候测试通过。
assertNotEqual (预期值,实际值)当两者不相等的时候测试通过。
assertTrue (表达式)当表达式为真的时候测试通过。
assertFalse (表达式)当表达式为假的时候测试通过。
举个简单测试登录接口的例子,通过不同的输入来获取结果,然后用断言判断预期结果和实
际结果是否相等。
实例代码:
1 import unittest#导入 UnitTest 模块
2 import requests
3 class logintest(unittest.TestCase):#定义一个 logintest 的测试类,这个类继承了 UnitTest 的 TestCase 的基类,这样就完成了 UnitTest的一个测试实例,这个实例可以包含多个测试用例,通过函数来完成每一个测试用例
4 def testlogin1(self):#定义 testlogin1()函数作为一个测试用例,该用例测试是否正常登录,即通过输入正确的账号和密码登录,增加断言判断是不是返回的信息“登录成功”,如果是,则测试用例通过,如
果不是,则测试用例不通过
5 url = "http://www.xxx.com/login.html"
6 form = {"username":13111111111,"password":123456}
7 r = requests.post(url,data = form)
8 self.assertEqual(r.text,"登录成功") 
9 def testlogin2(self):#定义 testlogin2()函数作为一个测试用例,该用例测试异常登录,即通过空的账号和正确的密码登录,增加断言判断返回的是不是报错信息“用户名不能为空”,如果是,则测试用例
通过,如果不是,则测试用例不通过
10 url = "http://www.xxx.com/login.html"
11 form = {"username":"","password":123456}
12 r = requests.post(url,data = form)
13 self.assertEqual(r.text,"用户名不能为空") 
14 def testlogin3(self):#定义 testlogin3()函数作为一个测试用例,该用例测试异常登录,即通过正确的账号和空的密码登录,增加断言判断返回的是不是报错信息“密码不能为空”,如果是,则测试用例通
过,如果不是,则测试用例不通过
15 url = "http://www.xxx.com/login.html"
16 form = {"username":13111111111,"password":""}
17 r = requests.post(url,data = form)
18 self.assertEqual(r.text,"密码不能为空") 
19 def testlogin4(self):#定义 testlogin4()函数作为一个测试用例,该用例测试异常登录,即通过正确的账号和错误的密码登录,增加断言判断返回的是不是报错信息“账号或者密码错误”,如果是,则测试
用例通过,如果不是,则测试用例不通过
20 url = "http://www.xxx.com/login.html"
21 form = {"username":13111111111,"password":111111}
22 r = requests.post(url,data = form)
23 self.assertEqual(r.text,"账号或者密码错误")

测试固件testfixture

测试固件从名字来说就是固定的测试代码,对于测试代码来说必然会有一些相同的部分,比
如测试一个接口,那接口地址就是相同的部分,而这可以通过 setup() 进行初始化,然后各个测试
用例直接调用初始化的接口地址就可以简化代码了。同样还可以通过 teardown() 来结束测试工作。
测试固件就是整合了代码的公共部分
通过上一节的例子会发现,每个测试用例 中的 URL 都是相同的,通过测试固 件的 setup() 可以将 URL 初始化,然后可以给各个测试用例调用。这样可以减少重复的代码, 而且对于以后修改代码也有好处,只需要修改初始化的 URL ,而不需要再对每一个测试用例中的 URL 进行修改,那就把代码改一下。
实例代码:
1 import unittest
2 import requests
3 class logintest(unittest.TestCase):
4 def setUp(self):#在 logintest 类中定义 setUp 函数,这个函数就是放置测试用例的公共部分,类似一个全局变量,供其他函数调用。这里就是初始化一个接口的 URL,让其他函数不需要再重复定义,直
接通过变量 self.url 调用
5 self.url = "http://www.xxx.com/login.html"
6 def testlogin1(self):
7 form = {"username":13111111111,"password":123456}
8 r = requests.post(self.url,data = form)
9 self.assertEqual(r.text,"登录成功")
10 def testlogin2(self):
11 form = {"username":"","password":123456}
12 r = requests.post(self.url,data = form)
13 self.assertEqual(r.text,"用户名不能为空")
14 def testlogin3(self):
15 form = {"username":13111111111,"password":""}
16 r = requests.post(self.url,data = form)
17 self.assertEqual(r.text,"密码不能为空")
18 def testlogin4(self):
19 form = {"username":13111111111,"password":111111}
20 r = requests.post(self.url,data = form)
21 self.assertEqual(r.text,"账号或者密码错误")
因为这是一个简单的测试实例,所以看上去代码只减少了 2 行,但对于公共部分比较多的情
况就会发现减少了很多冗余的代码,也易于后期的维护,因此能利用测试固件的时候尽量使用

测试套件testsuite

测试套件把多个测试用例集 合到一起,而测试套件和测试用例一样,也可以有多个,并且可以组合在一起形成更多的测试用例集合
完成了测试用例的准备部分,接着需要根据用例进行组合,这时候就用到测试套件了。测试
套件有多种添加测试用例的方式,下面介绍 2 种常用的添加方式。
第一种:
1 import unittest
2 import requests
3 class logintest(unittest.TestCase):
省略之前的代码
4 def suite():#定义一个 suite()函数,用来返回已经创建好的测试套件实例
5     loginTestCase = unittest.TestSuite()#调用 TestSuite()函数生成一个测试套件实例
6     loginTestCase.addTest(logintest("testlogin1"))#使用实例的 addTest 的方法,将 logintest 中的测试函数加入到测试套件中
7     loginTestCase.addTest(logintest("testlogin2"))
8     loginTestCase.addTest(logintest("testlogin3"))
9     loginTestCase.addTest(logintest("testlogin4"))
10    return loginTestCase#返回添加完测试用例的测试套件实例
这样在完成了将测试用例加入到测试套件之中的过程,但这样一个个添加测试用例的方式有
点烦琐,一旦用例太多就会有太多冗余的代码,于是介绍另外一个添加测试用例的方法,通过
makeSuite 方法来创建测试用例类中所有测试用例的测试套件
实例代码:
1 import unittest
2 import requests
3 class logintest(unittest.TestCase):
省略测试用例的代码
4 def suite():
5     loginTestCase = unittest.makeSuite(logintest,"test")#通过 makeSuite()函数将 logintest 中所有 test 开头的测试用例加入测试套件中。
6     return loginTestCase
只需要一行代码就能添加全部的测试用例到测试套件中,但缺点在于不灵活,只能添加全部,
当然如果在测试类中定义所有需要运行的测试用例,那用这个方法就相当简单了。
多个测试套件其实还可以通过 TestSuite 组合在一起,变成一个新的测试套件,来看一下如何
实现。
1 import unittest
2 import requests
3 class logintest(unittest.TestCase):
省略测试用例的代码
4 class loginouttest(unittest.TestCase):
省略测试用例的代码
5 def suite():
6 loginTestCase = unittest.makeSuite(logintest,"test")#先把 2 个测试类的测试用例分别加入 2 个测试套件之中,然后通过 TestSuite 方法把 2个测试套件合成一个测试套件实例
7 loginoutTestCase = unittest.makeSuite(logintest,"test")
8 alltest = unittest.TestSuite(loginTestCase, loginoutTestCase)
9 return alltest

测试运行器testrunner

测试运行器是给测试用例提供运行环境的,通过它的 run() 方法来执行测试用例,并在执行完
成后将测试结果输出
UnitTest 模块提供了 TestRunner 类,为测试的运行提供了环境,最常见的就是 TextTestRunner
类,整个类使用了文字化的运行方式来报告最后的测试结果,来看例子
2 import requests
3 class logintest(unittest.TestCase):
省略测试用例的代码
4 class loginouttest(unittest.TestCase):
省略测试用例的代码
5 def suite():
省略测试套件的代码
6 if __name__ == "__main__":
7 runner = unittest.TextTestRunner()#使用 TextTestRunner 类构建一个运行器对象,此对象提供了 run 方法,它所接收的参数是之前生成的测试套件实例,这样测试框架就可以自动运行测试套件中的测试用例了
8 runner.run(suite())

执行结果

其实还有一个更简单的运行方法,就是用 UnitTest main 方法,这个方法是一个全局方法,
即直接加载所有测试类中的测试用例,并全部执行,只需要一句代码就行。
1 import unittest
2 import requests
3 class logintest(unittest.TestCase):
省略测试用例的代码
4 class loginouttest(unittest.TestCase):
省略测试用例的代码
5 def suite():
省略测试套件的代码
6 if __name__ == "__main__":
7 unittest.main()#用 main 方法完成所有测试用例的加载和运行,就是将所有的操作封装在 main 方法之中。结果和之前是一样的,这个方法虽然方便,却少了一些灵活性,需要通过实际情况来选择使用

测试报告

UnitTest 测试框架作为 Python 内置的框架,也并非十分完善,虽然运行测试框架能看到结果,
但没有测试报告的输出,不易于测试结果的保存。那要如何获取测试报告呢?需要下载导入一个
第三方模块 HTMLTestRunner ,这个类区别于之前的 TextTestRunner 类,是以 HTML 形式存放测
试结果的,并会以报告的形式保存。
2 import requests
3 import HTMLTestRunner
4 class logintest(unittest.TestCase):
省略测试用例的代码
5 class loginouttest(unittest.TestCase):
省略测试用例的代码
6 def suite():
省略测试套件的代码
7 if __name__ == "__main__":
8 fr = open("res1.html","wb")#新建一个名为 res1.html 的 HTML,并且设置权限是读写,description="详情")
9 runner = HTMLTestRunner.HTMLTestRunner(stream=fr,title=“"测试报告"#使用 HTMLTestRunner 模块中的 HTMLTestRunner 方法,构建一个运行器对象,并通过参数将结果写入之前新建的 res1.html 文件之中,标题为测试报告,描述为详情,最后也是通过 run方法完成测试用例的运行
10 runner.run(suite())

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值