3.Python UnitTest的使用

目录

一、http请求模块的封装

1.1 __name__函数

1.2http请求的封装

函数注释自动生成

二、单元测试框架unittest

2.1作用

2.2测试用例(TestCase)

2.2.1单元测试函数

2.2.2测试函数的执行顺序

2.3用例收集器(TestLoader)

2.4测试套件(TestSuite)

2.5测试运行器(TextTestRunner)

2.6测试脚手架(FIXture)

2.7断言

三、unittest测试流程

3.1编写用例

3.2收集用例

3.3运行用例并生成测试报告

3.4目录情况

四、生成html报告

4.1HTMLTestRunner

4.2 BeautifulReport


一、http请求模块的封装

1.1 __name__函数

__name__是一个特殊的全局变量

它输出当前脚本的名字,如果该脚本被导入到其他脚本执行,那么它就是当前执行脚本的文件名

如果直接运行当前脚本,那么它等于“__main__”

#文件名为test123.py
print(__init__)
#直接执行运行test.py文件,打印内容为__main__
#文件名为haha.py
import test123
#导入到haha.py后,运行haha.py文件,打印内容为test123

使用:在当前脚本调试页面代码

if __name__ == '__main__':
    """执行当前脚本时执行这里的代码,其他文件调用该文件时不执行此处代码"""
    print('仅在当前脚本执行时有效')

调试unittest中用例脚本

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

1.2http请求的封装

因为发送请求需要在多个地方使用,为了代码复用,需对该功能进行封装

import requests

#此处->requests.Response的作用是表示返回的类型,其他模块调用时,pycharm可以进行提示
def send_http_requests(url,method,**kwargs) ->requests.Response:
    """
    发送http请求
    :param url:请求路径
    :param method:请求方式
    :param kwargs:params、data、json、headers.....
    :return:response
    """
    #把方法名小写化,防止误传
    method=method.lower()
    #获取对应的方法
    return getattr(requests,method)(url,**kwargs)

#方法的调用
res=send_http_requests(url='http://www.baidu.com',method='get')
print(res.json)

函数注释自动生成

  1. 修改File > Settings > Tools > Python Integrated Tools > Docstring format > reStructuredText

  2. 在函数方法名下输入三个双(单)引号,回车之后自动生成

二、单元测试框架unittest

unittest是Python自带的一个单元测试框架

2.1作用

  • 管理用例

  • 批量执行用例

  • 组织运行结果/报告

  • 让代码更稳健

  • 可拓展

2.2测试用例(TestCase)

unittest提供了一个基类TestCase用来创建测试用例;

创建测试用例,导入unittest模块后,需要创建一个类,来继承TestCase;

2.2.1单元测试函数

类中每个方法代表一个测试用例,方法名必须以test开头,unittest只会识别以test开头的方法为测试用例

import unittest
​
class TestAbs(unittest.TestCase):
    name='测试abs函数'
​
    def test_negative_num(self):
        '''
        测试负数
        :return:
        '''
        # 1.测试数据
        data=-1
        except_data=1
        # 2.测试步骤
        res=abs(data)
        # 3.断言
        print(1)
        self.assertEqual(res,except_data,msg='断言运行结果')
​
    def test_zero(self):
        '''
        测试0
        :return:
        '''
        # 1.测试数据
        data=0
        except_data=0
        # 2.测试步骤
        res=abs(data)
        # 3.断言
        print(2)
        self.assertEqual(res,except_data,msg='断言运行结果')
​
    def test_postive_num(self):
        '''
        测试正数
        :return:
        '''
        # 1.测试数据
        data=1
        except_data=1
        # 2.测试步骤
        res=abs(data)
        # 3.断言
        print(3)
        self.assertEqual(res,except_data,msg='断言运行结果')

选择运行方式:

2.2.2测试函数的执行顺序

测试用例执行时不是按照定义的顺序执行,而是按照ascii码排序,可以在test_后加上数字,定义执行顺序

test_1.... 、 test_2.....

#文件名test_abs.py
​
import unittest
​
class TestAbs(unittest.TestCase):
    name='测试abs函数'
    
    #修改测试用例名称
    def test_1negative_num(self):
        '''
        测试负数
        :return:
        '''
        # 1.测试数据
        data=-1
        except_data=1
        # 2.测试步骤
        res=abs(data)
        # 3.断言
        print(1)
        self.assertEqual(res,except_data,msg='断言运行结果')
    
    #修改测试用例名称
    def test_2zero(self):
        '''
        测试0
        :return:
        '''
        # 1.测试数据
        data=0
        except_data=0
        # 2.测试步骤
        res=abs(data)
        # 3.断言
        print(2)
        self.assertEqual(res,except_data,msg='断言运行结果')
​
    #修改测试用例名称
    def test_3postive_num(self):
        '''
        测试正数
        :return:
        '''
        # 1.测试数据
        data=1
        except_data=1
        # 2.测试步骤
        res=abs(data)
        # 3.断言
        print(3)
        self.assertEqual(res,except_data,msg='断言运行结果')

2.3用例收集器(TestLoader)

if __name__ == '__main__':
    #testcase为文件路径
    re=unittest.TestLoader().discover('testcase')
    print(re)

收集规则可以通过patterns自定义,默认是以test开头的模块,一般不做修改。

会到指定目录下递归去寻找符合patterns规则的模块中继承了TestCase的类。

注意:如果有嵌套的文件夹,一定要在文件夹中加入__init__.py,其实就是把文件夹变成一个Python的包。

2.4测试套件(TestSuite)

用例收集器,会返回能够收集到的所有的用例,封装成测试套件类型。

测试套件,其实就是一系列的测试用例类。

添加单个测试用例:

import unittest
import testcase01
suite = unittest.TestSuite()
suite.addTest(testcase01.MyTest("test_001"))
suite.addTest(testcase01.MyTest("test_002"))
# 只是把测试用例添加到了测试套件中,并不是执行测试用例

添加测试用例类:

import unittest
import testcase01
suite = unittest.TestSuite()
# 只是把测试用例添加到了测试套件中,并不是执行测试用例
suite.addTest(unittest.makeSuite(testcase01.MyTest))

2.5测试运行器(TextTestRunner)

TextTestRunner是用来执行和输出测试用例和测试套件的结果的。

import unittest
​
#输出内容在控制台
if __name__ == '__main__':
    re=unittest.TestLoader().discover('testcase')
    #实例化TextTestRunner对象
    runner=unittest.TextTestRunner()
    #调用对象的run方法,执行测试用例
    runner.run(re)
    
#输出内容问txt报告
if __name__ == '__main__':
    re=unittest.TestLoader().discover('testcase')
    # 保存在报告文件中
    with open('reports/测试报告.txt','w',encoding='utf-8') as f:
        runner=unittest.TextTestRunner(f)
        runner.run(re)

2.6测试脚手架(FIXture)

可以在测试用例执行之前自动调用指定的函数,在测试用例执行之后自动调用指定的函数。

对象、方法:

-setUp会在每个单元函数测试开始前执行。

import unittest
​
class MyTest(unittest.TestCase):
    def setUp(self) -> None:
        print('setup被自动调用了')
​
    def test_01(self):
        print('测试用例01')
​
    def test_02(self):
        print('测试用例02')
​
​
​
if __name__ == '__main__':
    MyTest()

-tearDown会在每个单元测试函数执行结束之后执行。

import unittest
​
class MyTest(unittest.TestCase):
    def tearDown(self) :
        print('teardown被自动调用了')
​
    def test_01(self):
        print('测试用例01')
​
    def test_02(self):
        print('测试用例02')
​
​
​
if __name__ == '__main__':
    MyTest()

类方法,记得使用@classmethod去修饰:

-setUpclass在整个测试用例类开始执行前执行。

import unittest
​
class MyTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        print('setupclass自动调用了')
​
    def test_01(self):
        print('测试用例01')
​
    def test_02(self):
        print('测试用例02')
​
​
​
if __name__ == '__main__':
    MyTest()

-tearDownclass在整个测试用例类执行结束之后执行。

import unittest
​
class MyTest(unittest.TestCase):
    @classmethod
    def tearDownClass(cls):
        print('teardownclass自动调用了')
​
    def test_01(self):
        print('测试用例01')
​
    def test_02(self):
        print('测试用例02')
​
​
​
if __name__ == '__main__':
    MyTest()

模块方法:

-setUpModule在.py文件开始执行前时调用

import unittest
​
def setUpModule():
    print('setUpModule自动调用了')
​
​
class MyTest(unittest.TestCase):
​
    def test_01(self):
        print('测试用例01')
​
​
class HerTest(unittest.TestCase):
    def test_02(self):
        print('测试用例02')
​
​
​
if __name__ == '__main__':
    MyTest()

-tearDownModule在.py文件执行完成时调用

import unittest
​
def tearDownModule():
    print('tearDownModule自动调用了')
​
​
class MyTest(unittest.TestCase):
​
    def test_01(self):
        print('测试用例01')
​
​
class HerTest(unittest.TestCase):
    def test_02(self):
        print('测试用例02')
​
​
​
if __name__ == '__main__':
    MyTest()

2.7断言

断言方法断言描述
assertTrue(expr, msg=None)验证 expr 是 true,如果为 false,则 fail
assertFalse(expr, msg=None)验证 expr 是 false,如果为 true,则 fail
assertEqual(expected, actual, msg=None)验证 expected==actual , 不等则 fail
assertNotEqual(first, second, msg=None)验证 first != second, 相等则 fail
assertIsNone(obj, msg=None)验证 obj 是 None , 不是则 fail
assertIsNotNone(obj, msg=None)验证 obj 不是 None , 是则 fail
assertIn(member, container, msg=None)验证是否 member in container
assertNotIn(member, container, msg=None)验证是否 member not in container

三、unittest测试流程

3.1编写用例

1.导入unittest和被测试的函数

创建测试用例类,继承unittest.TestCase

2.创建单元测试函数

以test开头,编写测试数据,测试步骤,断言

#在test_case文件夹下创建test_abs.py文件
import unittest
​
class TestAbs(unittest.TestCase):
    name='测试abs函数'
    
    #修改测试用例名称
    def test_1negative_num(self):
        '''
        测试负数
        :return:
        '''
        # 1.测试数据
        data=-1
        except_data=1
        # 2.测试步骤
        res=abs(data)
        # 3.断言
        print(1)
        self.assertEqual(res,except_data,msg='断言运行结果')

3.2收集用例

unittest.TestLoader().discover(路径/模块名)

用例模块名默认为test*.py

返回测试套件unittest.TestSuit

3.3运行用例并生成测试报告

testrunner 测试运行器

unittest.TextTestRunner 文本报告

#创建main.py入口函数
import unittest
​
if __name__ == '__main__':
    #收集用例并返回测试套件
    re=unittest.TestLoader().discover('testcase')
    #运行器运行并生成报告
    with open('reports/测试报告.txt','w',encoding='utf-8') as f:
        runner=unittest.TextTestRunner(f)
        runner.run(re)

3.4目录情况

四、生成html报告

导入模块顺序:系统级模块、第三方模块、自定义模块

4.1HTMLTestRunner

可修改HTMLTestRunner.py中默认信息

将HTMLTestRunner.py文件放在common文件夹下

#main.py文件
import unittest
​
from common.HTMLTestRunner import HTMLTestRunner
​
if __name__ == '__main__':
    re=unittest.TestLoader().discover('testcase')
    with open('reports/测试报告.html','wb') as f:
        runner=HTMLTestRunner(f)
        runner.run(re)

  

4.2 BeautifulReport

安装:

pip install beautifulreport

使用:

#main.py文件
import unittest

from BeautifulReport import BeautifulReport

if __name__ == '__main__':
    re=unittest.TestLoader().discover('testcase')
    br=BeautifulReport(re)
    br.report(description='项目描述',filename='reports/测试报告.html')

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我了解了您的要求,下面是关于Python unittest使用教程: 1.引入unittest模块 在Python使用unittest时,首先需要引入unittest模块,示例如下: ```python import unittest ``` 2.测试用例的编写 在unittest中,每一个测试用例都需要是一个类,并且需要继承自unittest.TestCase。在该类中,需要编写一些测试方法,用于测试具体的功能。示例如下: ```python class TestStringMethods(unittest.TestCase): def test_upper(self): self.assertEqual('foo'.upper(), 'FOO') def test_isupper(self): self.assertTrue('FOO'.isupper()) self.assertFalse('foo'.isupper()) def test_split(self): s = 'hello world' self.assertEqual(s.split(), ['hello', 'world']) # 检查 s.split 的返回值是否为 ['hello', 'world'] with self.assertRaises(TypeError): s.split(2) ``` 在上述示例中,我们定义了一个名为TestStringMethods的类,并继承了unittest.TestCase。在该类中,我们定义了三个测试方法,分别用于测试字符串是否转化为大写格式、字符串是否全部为大写格式以及字符串分割成列表的功能。其中,使用了self.assertEqual()和self.assertTrue()方法来检查功能是否正确。 3.测试运行 编写完测试用例后,我们需要使用unittest模块的unittest.main()方法来运行测试,示例如下: ```python if __name__ == '__main__': unittest.main() ``` 在上述代码中,我们使用了__name__变量,该变量用于判断当前模块是否为主模块。如果当前模块为主模块,则执行unittest.main()方法来运行测试。 完整代码示例如下: ```python import unittest class TestStringMethods(unittest.TestCase): def test_upper(self): self.assertEqual('foo'.upper(), 'FOO') def test_isupper(self): self.assertTrue('FOO'.isupper()) self.assertFalse('foo'.isupper()) def test_split(self): s = 'hello world' self.assertEqual(s.split(), ['hello', 'world']) # 检查 s.split 的返回值是否为 ['hello', 'world'] with self.assertRaises(TypeError): s.split(2) if __name__ == '__main__': unittest.main() ``` 希望这个教程能够帮到您,如果您还有其他问题,可以继续向我提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值