unittest自动化测试报告(unittest单元测试框架)

unittest 单元测试框架

Unittest 单元测试框架简介

Unittest 是Python内置的单元测试框架,具备编写用例、组织用例、执行用例、功能,可以结合selenium 进行UI自动化测试,也可以结合appium、requests 等模块做其它自动化测试。

使用unittest 前需要熟悉该框架的五个概念:

test case : 一个完整的测试单元,执行该测试单元可以完成对某一个问题的验证,完整提现在测试前环境准备(setUp),执行测试代码(run),一级测试后环境还原(tearDown)‘

test suit :多个测试用例的集合,测试套件或测试计划;

testLoader : 加载TestCase 到TestSuite 中的,其中loadTestsFrom__() 方法用于寻找TestCase,并创建它们的实例,然后添加到TestSuite中。

test runner : 执行多个测试用例,并将测试结果保存到TestTestResults 实例中,包括允许多少测试用例,成功了多少,失败了多少等信息;

test fixture : 一个测试用例的初始化准备环境及环境还原,主要是setUp() 和setDown() 方法

Unittest 基础框架

unittest 基础使用步骤:

  1. 用import 语句引入unittest 模块
  2. 让所执行的测试的类都基础于TestCase类,可以将TestCase看出是对特定类进程测试的方法的集合
  3. setUp() 方法中进行测试前的初始化工作, teardown() 方法中执行测试后的清理工作,它们都是TestCase 中的方法
  4. 编写测试的方法最好以test 开头(可以直接运行)

def test_add(self)、def test_sub(self)等,可以编写多个测试用例对被测对象进行测试

  1. 在编写测试方法过程中,使用TestCase class提供的方法测试功能点,比如:assertEqual等
  2. 调用 unittest.main() 方法运行所有以test开头的方法。

unittest 代码示例

import unittestclass test_cases(unittest.TestCase): # 继承TestCase类def setUp(self): # 测试用例执行之前初始化print('setUp')def tearDown(self): # 测试用例执行之后还原、清理print('tearDown')def testcase01(self):print('execute case01')self.assertEqual(3,3) # 断言if __name__ == '__main__':unittest.main()

unittest 常用断言介绍:

断言即进行预期结果和实际结果对比。

assertEqual(a,b) a == b # a,b 是否相等

assertNotEqual(a,b) a != b # a,b 是否不相等

assertTrue(x) bool(x) is True # x 是否为True

assertFalse(x) bool(x) is False # x 是否为False

assertIn(a,b) a in b # a是否包含 b

assertGreater(a,b) a>b # a大于b

assertGreaterEqual(a,b) a>=b # a 大于等于b

assertLess(a,b) a<b # a 小于 b

assertLessEqual(a,b) a<=b # a 小于等于b

可以在断言最后一个参数中加入自定义的测试失败信息,如:

assertEqual(10,20,”10!=20 测试失败”) 当断言失败时,显示该信息。

unittest用例执行顺序:

当在一个测试类或多个测试模块下,用例数量较多时,unittest在执行用例(test_xxx)时,并不是从上到下的顺序执行,有特定的顺序。

unittest框架默认根据ACSII码的顺序加载测试用例,数字与字母的顺序为0~9,A~Z,a~z。

对于类来说,class TestAxx 会优先于class TestBxx被执行,对于方法来说,test_aaa()方法会优先于test_bbb()被执行。对于测试目录与测试文件来说,unittest同样时按照这个规则来加载测试用例的。

Unittest 用例执行顺序代码示例:

import unittestclass test_cases_01(unittest.TestCase):def setUp(self) -> None:print('setup')def tearDown(self) -> None:print('tearDown')def test_ccc(self):print('execute test_ccc')self.assertEqual(3,3)def test_aaa(self):print('execute test_aaa')self.assertEqual(3,3)if __name__ == '__main__':unittest.main()

Unittest 控制测试用例执行顺序:

如需要unittest自行控制测试方法的执行顺序,可以通过如下两种方法;

方法一:通过addTest()添加用例的顺序控制用例执行

if __name__ == '__main__':suite = unittest.TestSuite()suite.addTest(test_cases_01('test_ccc'))suite.addTest(test_cases_01('test_aaa'))unittest.main(defaultTest='suite')

方法二:顺应unittest的默认执行顺序,通过设置测试类或者测试方法方法名字来实现。

Unittest 忽略用例:

在执行测试脚本的时候,可能会有某几条用例本次不想执行,但又不想删也不想注释,unittest通过忽略部分测试用例不执行的方式,分无条件忽略和有条件忽略,通过装饰器实现所描述的场景。提供的装饰器如下:

@unittest.skip(reason): 强制跳转。reason是跳转原因

@unittest.skipIf(condition,reason):condition为True的时候跳转

@unittest.skipUnless(condition,reason):condition为False的时候跳转

@unittest.expectedFailure:标记该测试预期为失败,如果该测试方法运行失败,则该测试不算做失败。

Unittest忽略用例示例代码:

import unittestclass test_cases_01(unittest.TestCase):def setUp(self) -> None:print('setup')def tearDown(self) -> None:print('tearDown')@unittest.skip('无条件跳过')def test_ccc(self):print('execute test_ccc')self.assertEqual(3, 3)@unittest.skipIf(True, '条件为真时跳过')def test_aaa(self):print('execute test_aaa')self.assertEqual(3, 3)@unittest.skipUnless(False, '条件为假跳过')def test_bbb(self):print('execute test_bbb')self.assertEqual(3, 3)@unittest.expectedFailure # 预期结果为断言失败def test_ddd(self):print('execute test_ddd')self.assertEqual(3, 3)def test_fff(self):print('execute test_fff')self.assertEqual(3, 3)if __name__ == '__main__':suite = unittest.TestSuite()suite.addTest(test_cases_01('test_ccc'))suite.addTest(test_cases_01('test_aaa'))suite.addTest(test_cases_01('test_bbb'))suite.addTest(test_cases_01('test_ddd'))suite.addTest(test_cases_01('test_fff'))unittest.main(defaultTest='suite')

构建测试套件

在实际项目中,随着项目进度的开展,测试类会越来越多,可是直到现在我们还只会一个一个单独运行测试类,这在实际项目实践中肯定是不可行的,在unittest中可以通过测试套件来解决该问题。

测试套件(Test Suits)是由多个测试用例(Test Case)组成的,当然也可以由多个子套件组成。

在unittest中,把测试用例加载到测试套件的方法由如下方法:

方法一:

用unittest.TestSuite()实例化测试套件对象后,内部的addTest() 方法对测试类颞部的测试案例逐一添加:

if __name__ == '__main__':suite = unittest.TestSuite()suite.addTest(test_cases_01('test_ccc')) # 增加单个测试用例suite.addTest(test_cases_01('test_aaa'))unittest.main(defaultTest='suite')

方式二:

Unitttest提供一个TestLoader类用于自动创建一个测试集并把单个测试放入到测试集中。TestLoader自动运行以test开头的测试方法。可以通过如下方法加载用例:

if __name__ == '__main__':# 增加类下的所有用例suite01 = unittest.TestLoader().loadTestsFromTestCase('TestCase02')# 增加模块下所有用例suite02 = unittest.TestLoader().loadTestsFromModule('test_case_02')suite02.run()

在导入类及模块下的测试用例之前,如果用例实在其它模块,需要先进行import导入操作。

方式三:

用unittest.TestSuite()实例化测试套件对象后,内部的addTests()方法可以把多个子测试集合进行整合到一个大的测试集合中

if __name__ == '__main__':allsuite = unittest.TestSuite() # 增加单个测试用例testsuite01 = unittest.TestSuite()testsuite01.addTest('test_dddd')testsuite01.addTest('test_eee')testsuite02 = unittest.TestLoader().loadTestsFromModule('TestCases03') # 增加模块下的所有用例?allsuite.addTests(testsuite01) # 把testsuite01集合的用例加载到allsuite测试集合allsuite.addTests(testsuite02) # 把testsuite02 集合的用例加载到allsuite测试集合unittest.main(defaultTest='allsuite')

方式四:

当测试用例存放在多个不同目录下,我们能用之气那把用例加载到测试集合中的方式是不太方便,需要不断去导入和添加用例模块,如此可以通过discover()方法实现,实现如下:

Discover(start_dir,pattern = ‘test*.py’,top_level_dir = None)

Start_dir : 要测试的模块名或测试用例目录;

Pattern=’test*.py’ :表示用例文件名的匹配原子,例子中匹配文件名以“test”开头的“.py”文件,星号“*”表示任意多个字符。

Top_level_dir=None :测试模块的顶层目录,如果没有顶层目录,默认是None。

该方法通过从指定的开始目录递归到子目录中查找所有测试模块,并返回包含它们的TestSuite对象,只要与模式匹配测试文件和可导入的模块名称才会被加载。

如果一个测试文件的名称符合pattern,会自动查找该文件中派生自TestCase的类包含的test开头的方法作为测试方法。

代码示例:

import unittest,oscase_path = os.path.join(os.path.dirname(__file__))print(case_path)def get_all_cases():discover = unittest.defaultTestLoader.discover(case_path,pattern='test*.py',top_level_dir=None) # 加载不同模块下的用例suit = unittest.TestSuite()suit.addTest(discover)return suitif __name__ == '__main__':suite = unittest.TestSuite()suite = get_all_cases()unittest.main(defaultTest='suite')

Unittest 生成测试报告

测试报告为测试结果的统计即展示,是自动化测试不可或缺的一部分,利用unittest生成测试报告方式如下:

方式一:

用unittest.main()执行测试集

if __name__ == '__main__':suite = unittest.TestSuite()unittest.main() # 执行当前模块下所有类的测试用例unittest.main(verbosity=2) # 执行当前模块下所有类的测试用例unittest.main(defaultTest='suite') # 执行suite测试集合下所有的测试用例

这里的verbosity是一个选项,表示测试结果的信息复杂度,有三个值:

0 (静默模式) :你只能获得总的测试用例数和总的结果,比如100个,失败20个,成功80个

1 (默认模式) :非常类似静默模式,只是再每个成功的用力前面有个“.”,每个失败的用例前面有个“F”。

2 (详细模式) :测试结果会显示每个测试用例的所有相关的信息

方式二:

使用TextTestRunner 执行测试用例集,TextTestRunner有三个参数,它们都哦有静默参数:

  1. Verbosity 分别三个级别:0,1,2它们输出的测试报告详细程度不同,2 最详细
  2. Stream 关系着测试报告的位置,如果默认为None的话,测试报告会输出到控制台
  3. descriptions 测试报告的描述

mport unittest,oscase_path = os.path.join(os.path.dirname(__file__))print(case_path)def get_all_cases():discover = unittest.defaultTestLoader.discover(case_path,pattern='test*.py',top_level_dir=None) # 加载不同模块下的用例suit = unittest.TestSuite()suit.addTest(discover)return suitif __name__ == '__main__':# 方式一:# suite = unittest.TestSuite()# suite = get_all_cases()# unittest.main(defaultTest='suite')# 方式二:# suite = unittest.TestSuite()# unittest.main() # 执行当前模块下所有类的测试用例# unittest.main(verbosity=2) # 执行当前模块下所有类的测试用例# unittest.main(defaultTest='suite') # 执行suite测试集合下所有的测试用例# 方式三:from sample.test_02.test_cases_01 import test_cases_01suite = unittest.TestSuite()suite = get_all_cases()test_runner = unittest.TextTestRunner(stream=None,descriptions=None,verbosity=2)test_runner = unittest.TextTestRunner(stream=None,descriptions=None,verbosity=0)with open('test_result.txt','w',encoding='utf-8') as file:runner = unittest.TextTestRunner(stream=file, descriptions='执行用例的测试报告', verbosity=2)runner.run(suite)

生成的txt报告:

unittest自动化测试报告(unittest单元测试框架)(1)

方式三:

使用第三方HTMLRunner 执行用例集,它可以输出网页版本测试报告

HTMLTestRunner 是Python标准库的unittest模块的一个扩展,在使用该模块之前要下载HTMLTestRunner.py文件,并将该文件保存在python安装路径下的lib文件夹或者是项目的子包中,在python代码中通过import htmlTestRunner导入,即可使用。

import unittest,oscase_path = os.path.join(os.path.dirname(__file__))print(case_path)def get_all_cases():discover = unittest.defaultTestLoader.discover(case_path,pattern='test*.py',top_level_dir=None) # 加载不同模块下的用例suit = unittest.TestSuite()suit.addTest(discover)return suit

if __name__ == '__main__':import HTMLTestRunnersuite = unittest.TestSuite()suite = get_all_cases()html_obj = open('result.html','w ',encoding='utf-8') # 创建runner = HTMLTestRunner.HTMLTestRunner(stream=html_obj,title='测试报告',description='测试报告')runner.run(suite)

HTMLTestRunner常用参数:

stream : 配置测试报告要保存的文件路径

title : 测试报告标题

description : 测试报告的描述信息

生成的简易的html报告:

unittest自动化测试报告(unittest单元测试框架)(2)

测试用例信息在报告中显示:

一:在测试用例中加上注释西悉尼,即可在html报告中体现,能更好的展示每个用例的信息。

import unittest,osclass TestCases03(unittest.TestCase):'''测试类的详细信息'''def setUp(self) -> None:print('setUp')def tearDown(self) -> None:print('tearDown')def test_aaa(self):'''测试用例test_aaa的详细信息'''print('execute test_aaa')self.assertEqual(3,3)def test_ccc(self):'''测试用例test_ccc的详细信息'''print('execute test_ccc')self.assertEqual(3,3)def test_dddd(self):'''测试用例test_dddd的详细信息'''print('execute test_ccc')self.assertEqual(3,3)def test_eee(self):'''测试用例test_eee的详细信息'''print('execute test_eee')self.assertEqual(3, 3)

unittest自动化测试报告(unittest单元测试框架)(3)

测试用例信息在报告中显示:

二:在测试方法中通过:

self._testMethodName = ‘设置测试用例的名称’

self._testMethodDoc = ‘设置测试用例详情’

def test_aaa(self):'''测试用例test_aaa的详细信息'''self._testMethodName = 'test_aaa'self._testMethodDoc = '测试用例test_aaa详细信息'print('execute test_aaa')self.assertEqual(3,3)

生成的报告如下图:

unittest自动化测试报告(unittest单元测试框架)(4)

方式四:

使用第三方HTMLTest ReportCN 执行测试用例集,它可以输出网页版测试报告。

在使用该模块之前下载HTMLReportCN.py文件,并将该文件保存在python安装路径下的lib文件夹或项目的子包中,在python代码中通过

import HTMLTestReportCN 导入,即可使用。

from sample.test_02.comm import HTMLTestReportCNsuite = unittest.TestSuite()suite = get_all_cases()report_dir = './html_report/' # 测试报告路径,必须以 / 结尾report_path_obj = HTMLTestReportCN.ReportDirectory(report_dir) # 创建测试报告路径对象report_path_obj.create_dir('UI 自动化测试_') # 创建测试报告存放目录html_path = HTMLTestReportCN.GlobalMsg.get_value('report_path') # 获取测试报告文件对象html_file = open(html_path,'wb') # 创建html测试报告html_runner = HTMLTestReportCN.HTMLTestRunner(stream=html_file,title='UI 测试报告',tester='YangShiYu',description='20221013')html_runner.run(suite)

生成的测试报告展示如下:

unittest自动化测试报告(unittest单元测试框架)(5)

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页