python - 简述unittest框架

Posted Wilson

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python - 简述unittest框架相关的知识,希望对你有一定的参考价值。

简述unittest框架   

unittest单元测试框架不仅可以适用于单元测试,还可以适用web UI 和 接口 API 自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过,最终生成测试结果。

一、unittest结构概览

 

unittest中最核心的四个概念是:test fixture、test case, test suite, test runner/report

1、test fixture

① setup():每个测试函数运行前运行

② teardown():每个测试函数运行完后执行

③ setUpClass():必须使用@classmethod 装饰器,所有test运行前运行一次

④ tearDownClass():必须使用@classmethod装饰器,所有test运行完后运行一次

2、Testcase

a、编写自己的测试用例必须继承TestCase类

import unittest

class TestCase(unittest.TestCase)

b、编写测试case:

def test_001_case1(self):
        print("case1")

def test_002_case1(self):
        print("case2")

注:

  1、测试用例的名字必须以test开头,不以test命名的测试用例不会被加载运行(除在test命名的测试用例中调用外)

  2、测试用例的执行顺序可以自定义,如果以数字命名测试用例(如:test_001_case1、test_002_case1),则按照数字顺序执行,如果不以数字命名则按照test后的英文单词的字母顺序作为执行顺序

c、选择性的执行测试case

"""
@unittest.skip(reason): skip(reason)装饰器:无条件跳过装饰的测试,并说明跳过测试的原因。 @unittest.skipIf(reason): skipIf(condition,reason)装饰器:条件为真时,跳过装饰的测试,并说明跳过测试的原因。 @unittest.skipUnless(reason): skipUnless(condition,reason)装饰器:条件为假时,跳过装饰的测试,并说明跳过测试的原因。 @unittest.expectedFailure(): expectedFailure()测试标记为失败。
"""

d、测试case常用的断言

"""
assertEqual(a,b,[msg=\'测试失败时打印的信息\']):断言a和b是否相等,相等则测试用例通过。

assertNotEqual(a,b,[msg=\'测试失败时打印的信息\']):断言a和b是否相等,不相等则测试用例通过。

assertTrue(x,[msg=\'测试失败时打印的信息\']):断言x是否True,是True则测试用例通过。

assertFalse(x,[msg=\'测试失败时打印的信息\']):断言x是否False,是False则测试用例通过。

assertIs(a,b,[msg=\'测试失败时打印的信息\']):断言a是否是b,是则测试用例通过。

assertNotIs(a,b,[msg=\'测试失败时打印的信息\']):断言a是否是b,不是则测试用例通过。

assertIsNone(x,[msg=\'测试失败时打印的信息\']):断言x是否None,是None则测试用例通过。

assertIsNotNone(x,[msg=\'测试失败时打印的信息\']):断言x是否None,不是None则测试用例通过。

assertIn(a,b,[msg=\'测试失败时打印的信息\']):断言a是否在b中,在b中则测试用例通过。

assertNotIn(a,b,[msg=\'测试失败时打印的信息\']):断言a是否在b中,不在b中则测试用例通过。

assertIsInstance(a,b,[msg=\'测试失败时打印的信息\']):断言a是是b的一个实例,是则测试用例通过。

assertNotIsInstance(a,b,[msg=\'测试失败时打印的信息\']):断言a是是b的一个实例,不是则测试用例通过。
"""

e、测试case参数化操作

测试case 默认是不支持传参操作的,因此想要达到传参效果,需要用到一个第三方模块进行参数化操作。

1、下载

pip3 install nose_parameterized

2、示例:

import unittest
from nose_parameterized import parameterized

class Test(unittest.TestCase):
    @parameterized.expand(
        [
            [\'xiaogang\',\'123456\',True], #可以是list,也可以是元祖
            [\'\',\'123456\',True],
            [\'xiaogang\',\'\',False],
            [\'adgadg\',\'123456\',False]
        ]
    )
    def test_login(self,args1,args2,args3): #这里的参数对应上述列表里的元素,运行的时候会遍历上述列表里的二维列表直到所有元素都调用运行完成
        print(args1,args2)

3、Text Suite

测试往往需要多测试用例的,可以把多的测试用例集合在一起执行,这就是TestSuite的概念。

a、unittest.main()

搜索所有以test开头的测试用例方法,按照ASCII的顺序执行多个用例

if __name__ == \'__main__\':
    unittest.main()

b、unittest.TestSuite()和unittest.TextTestRunner()

先实例化测试套件,将用例加载进去,再用TextTestRunner去执行用例

if __name__ == "__main__": 
    suite=unittest.TestSuite()
    suite.addTest(Test(\'test_case2\'))
    suite.addTest(Test(\'test_case1\'))
    runner=unittest.TextTestRunner()
    runner.run(suite)

c、unittest.defaultTestLoader.loadTestsFromModule 

根据给定的模块实例来获取测试用例套件,如果是通过manage.py来启动测试case的话,不建议使用loadTestsFromModule,因为loadTestsFromModule在manage.py中不能启动单独指定.py文件中的case 

if __name__ == \'__main__\':
    module_name = os.path.basename(__file__).split(".")[0]
    module = __import__(module_name)
    html_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "report")
    with open("report.html", "wb") as f:
        runner = HTMLTestReportCN.HTMLTestRunner(stream=f)
        all_suite = unittest.defaultTestLoader.loadTestsFromModule(module)
        runner.run(all_suite)

d、unittest.defaultTestLoader.discover()

在指定路径下,找到满足正则表达式的测试case.py文件执行。

if __name__ == \'__main__\':
        pattern = "Test_*.py"
        case_path = os.getcwd()
        html_path = os.path.join(os.path.join(os.getcwd(), "report"))
        all_suite = unittest.defaultTestLoader.discover(start_dir=case_path, pattern=pattern)
        result = BeautifulReport(all_suite)
        result.report(filename="report--%s.html" % self.now_time, description=\'测试报告\', log_path=html_path)

e、其他测试unittest.defaultTestLoader,case启动方法:

"""
 loadTestsFromModule(self, module) : 根据给定的模块实例来获取测试用例套件
 loadTestsFromName(self, name, module=None) : 根据给定的字符串来获取测试用例套件,字符串可以是模块名,测试类名,测试类中的测试方法名,或者一个可调用的是实例对象
 这个实例对象返回一个测试用例或一个测试套件
 loadTestsFromNames(self, names, module=None)  :  和上面功能相同,只不过接受的是字符串列表
 loadTestsFromTestCase(self, testCaseClass) :  根据给定的测试类,获取其中的所有测试方法,并返回一个测试套件
"""

 

4、test runner/report

测试结果会保存到TextTestResult实例中,包括运行了多少用例,成功与失败多少等信息,这里介绍两种测试报告生成的第三方库 HTMLTestReportCNBeautifulReport,相比原生的测试报告,无疑美观许多。

a、HTMLTestReportCN

import HTMLTestRunnerEN
...

if __name__ == \'__main__\':
    filePath =\'F:\\\\Report.html\'
    fp = file(filePath,\'wb\')
    runner = HTMLTestRunnerEN.HTMLTestRunner(
        stream=fp,
        title=\'{ Test Report }\',
        #description=\'\',
        #tester="Findyou"
        )
    runner.run(Suite())

b、BeautifulReport

import unittest
from BeautifulReport import BeautifulReport

if __name__ == \'__main__\':
    test_suite = unittest.defaultTestLoader.discover(\'../tests\', pattern=\'test*.py\')
    result = BeautifulReport(test_suite)
    result.report(filename=\'测试报告\', description=\'测试deafult报告\', log_path=\'report\')

 

以上是关于python - 简述unittest框架的主要内容,如果未能解决你的问题,请参考以下文章

Python接口测试之unittest框架

python 单元测试,unittest 测试框架

python unittest框架装饰器

Python单元测试框架:unittest

python之单元测试框架—unittest(补充)

Python 中 unittest 单元测试框架中需要知识点