python的UnitTest使用

本文详细介绍了Python单元测试框架unittest的使用,包括TestCase、TestSuite、TestRunner、TestLoader和Fixture的运用。讲解了如何创建测试用例文件,使用断言方法进行结果验证,以及参数化测试和跳过测试的实现。此外,还重点介绍了HTMLTestRunner,用于生成美观的测试报告。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UnitTest核心要素(unitest的组成)

1. TestCase(最核心的模块)

Testcase(测试用例),注意这个测试用例是unittest框架的组成部分,不是手工和自动化中我们所说的用例( Test Case)
主要作用:每个Testcase(测试用例)都是一个代码文件,在这个代码文件中来书写真正的用例代码

2. TestSuite

Testsuite(测试套件),用来管理组装(打包)多个TestCase(测试用例)的

3. TestRunner

TestRunner(测试执行,测试运行),用来执行TestSuite(测试套件)的

4. TestLoader

TestLoader(测试加载),功能是对Testsuite(测试套件)功能的补充,管理组装(打包)多个Testcase(测试用例)的

5.Fixture

Fixture(测试夹具),书写在Testcase(测试用例)代码中,是一个代码结构,可以在每个方法执行前后都会执行的内容
举例:
登录的测试用例,每个用例中重复的代码就可以写在Fixture代码结构中,只写一遍,但每次用例方法的执行,都会执行 Fixture中的代码
1.打开浏览器2.输入网址

----------------------------------------------------------

1. TestCase(最核心的模块)

在一个项目中Testcase(测试用例)的代码,一般放在一个单独的目录(case)

1.是一个代码文件,在代码文件中来书写真正的用例代码
2.代码文件的名字必须按照标识符的规则来书写(可以将代码的作用在文件的开头使用注释说明)
步骤
1.导包(unittest)
2.自定义测试类
3.在测试类中书写测试方法
4.执行用例
"""代码的目的:学习TestCase(测试用例)模块的书写方法"""
# 1,导包
import unittest


# 2,自定义测试类,需要继承unittest模块中的 Testcase类即可
class TestDemo1(unittest.TestCase):
    # 3,书写测试方法,用例代码
    # 书写要求,测试方法必须以test_开头(本质是以test开头)
    def test_method1(self):
        print('测试方法1')

    def test_method2(self):
        print('测试方法2')

# 4,执行用例(方法)
# 4.1 将光标放在类名的后边运行,会执行类中的所有的测试方法
# #4.2将光标放在方法名的后边运行,只执行当前的方 法

2. TestSuite TestRunner

Testsuite(测试套件),用来管理组装(打包)多个TestCase(测试用例)的
TestRunner(测试执行,测试运行),用来执行TestSuite(测试套件)的

步骤
1.导包(unittestR
2.实例化(创建对象)套件对象
3.使用套件对象添加用例方法
4.实例化运行对象
5.使用运行对象去执行套件对象
"""学习TestSuite和 TestRunner的使用"""
# 1.导包(unittest)
import unittest

# 2。实例化(创建对象)套件对象,
from TestCase import TestDemo1, TestDemo2

suite = unittest.TestSuite()
# 3。使用套件对象添加用例方法
# 方式一,套件对象.addTest(测试类名('方法名'))
# 建议测试类名和方法名直接去复制,不要手写
# suite.addTest(TestDemo1('test_method1'))
# suite.addTest(TestDemo1('test_method2'))
# suite.addTest(TestDemo2('test_method1'))
# suite.addTest(TestDemo2('test_method2'))

# 方式二 将一个测试类中的所有方法进行添加
# 套件对象. addTest(unittest.makeSuite(测试类名))
# #缺点:makeSuite()不会提示
suite.addTest(unittest.makeSuite(TestDemo1))
suite.addTest(unittest.makeSuite(TestDemo2))

# 4.实例化运行对象
runner = unittest.TextTestRunner()
# 5.使用运行对象去执行套件对象
# 运行对象.run(套件对象)
runner.run(suite)

3,TestLoader (测试加载)

TestLoader(测试加载),作用和TestSuite 的作用是一样的,对TestSuite 功能的补充,用来组装测试用例的比如:如果Testcase 的代码文件有很多,(10 20,30 )-使用步骤
1.导包
2.实例化测试加载对象并添加用例--->得到的是suite对象
3.实例化运行对象
4.运行对象执行套件对象
# 在一个项目中Testcase(测试用例)的代码,一般放在一个单独的目录(case)

"""学习TestLoader的使用"""
# 1.导包(unittest)
import unittest

# 2,实例化加载对象并添加用例
# unittest.TestLoader( ).discover( '用例所在的路径','用例的代码文件名')
# 用例所在的路径,建议使用相对路径,用例的代码文件名可以使用*(任意多个任意字符)通配符
suite = unittest.TestLoader().discover('./case', 'test*.py')  # 'test*.py' 所有以test开头的都匹配 ;'*.py' 所有文件

# 3.实例化运行对象
runner = unittest.TextTestRunner()

# 4.使用运行对象去执行套件对象
# 运行对象.run(套件对象)
runner.run(suite)

# unittest.TextTestRunner.run(suite)

===============================================================================

Fixture(测试夹具)

Fixture(测试夹具)是一种代码结构
在某些特定的情况下会自动执行
方法级别[掌握]
在每个测试方法(用例代码)执行前后都会自动调用的结构
#方法执行之前
def setup(self): # 每个测试方法执行之前都会执行
    pass
#方法执行之后
def teardown(self):
    pass
# 每个测试方法执行之后都会执行

类级别[掌握]
在每个测试类中所有方法执行前后都会自动调用的结构(在整个类中执行之前执行之后个一次)
#类级别的Fixture方法,是一个类方法
#类中所有方法之前
@classmethod
def setupclass(cls):
    pass
#类中所有方法之后@classmethod
def teardownClass(cls):
    pass


模块级别[了解]
模块:代码文件
在每个代码文件执行前后执行的代码结构
#模块级别的要写在类的外边直接定义函数即可#代码文件之前
def setupModule() :
    pass
#代码文件之后
def teardownModule():
    pass

方法级别和类级别的前后的方法,不需要同时出现,根据用例代码的需要自行的选择使用

案例
1.打开浏览器(整个测试过程中就打开一次浏览器)类级别
2.输入网址(每个测试方法都需要一次)方法级别
3.输入用户名密码验证码点击登录(不同的测试数据)测试方法
4.关闭当前页面(每个测试方法都需要一次)方法级别
5.关闭浏览器(整个测试过程中就关闭一次浏览器)类级别

1.打开浏览器(整个测试过程中就打开一次浏览器)类级别
2.输入网址(每个测试方法都需要一次)方法级别
3.输入用户名密码验证码点击登录(不同的测试数据)测试方法
4.关闭当前页面(每个测试方法都需要一次)方法级别
2.输入网址(每个测试方法都需要一次)方法级别
3.输入用户名密码验证码点击登录(不同的测试数据)测试方法
4.关闭当前页面(每个测试方法都需要一次)方法级别
2.输入网址(每个测试方法都需要一次)方法级别
3.输入用户名密码验证码点击登录(不同的测试数据)测试方法
4.关闭当前页面(每个测试方法都需要一次)方法级别
5.关闭浏览器(整个测试过程中就关闭一次浏览器)类级别
import unittest


class TestLogin(unittest.TestCase):
    @classmethod
    def setupclass(cls) -> None:
        print("1,打开浏览器")

    # 类中所有方法之后@classmethod
    @classmethod
    def teardownClass(cls) -> None:
        print("5,关闭浏览器")

    # 方法执行之前
    def setUp(self) -> None:  # 每个测试方法执行之前都会执行
        print("2,输入网站")

    def tearDown(self) -> None:
        print("4,关闭页面")

    # 方法执行之后

    def test_1(self):
        print('输入正确用户名密码验证码,点击登录1')

    def test_2(self):
        print('输入错误用户名密码验证码,点击登录2')


# 2,实例化加载对象并添加用例
suite = unittest.TestSuite()

suite.addTest(unittest.makeSuite(TestLogin))
# 3.实例化运行对象
runner = unittest.TextTestRunner()

# 4.使用运行对象去执行套件对象
# 运行对象.run(套件对象)
runner.run(suite)

# unittest.TextTestRunner.run(suite)

=================================================================

断言

让程序代替人工自动的判断预期结果和实际结果是否相符.
断言的结果有两种:
> True,用例通过
> False,代码抛出异常,用例不通过
在unittest中使用断言,都需要通过self.断言方法来试验
常见断言方法:
assertTrue(expr, msg=None)                       验证expr是true,如果为false,则fail
assertFalse(expr, msg=None)                        验证expr是false,如果为true,则fai
assertEqual(expected, actual,msg=None)            验证expected==actual,不等则fail【掌握】
assertNotEqual(first, second,msg=None)            验证first != second,相等则fail
assertlsNon(obj, msg=None)                     验证obj是None,不是则fail
assertlsNotNone(obj, msg=None)                    验证obj不是None,是则fail
assertln(member, container,msg=None)             验证是否member in container【掌握】
assertNotIn(member, container,msg=None)              验证是否member not in container

assertEqual

assertEqual(预期结果,实际结果)#判断预期结果和实际结果是否相等
1.如果相等,用例通过
2.如果不相等,用例不通过,抛出异常

assertIn

assertIn(预期结果,Y实际结果)#判断预期结果是否包含在实际结果中
1.包含,用例通过
2.不包含,用例不通过,抛出异常
assertIn( 'admin ' , 'admin')#包含
assertIn( 'admin', 'adminnnnnnnn ')#包含
assertIn( ' admin', 'aaaaaadmin')# 包含
assertIn( ' admin ', 'aaaaaadminnnnnnn ')#包含
assertIn( ' admin' , 'addddddmin ')#不是包含
import unittest


def login(name, pwd):
    """正确的用户名和密码:admin,123456,登录成功"""
    if name == 'admin' and pwd == '123456':
        return "登录成功"
    else:
        return "登录失败"


# 在一个项目中Testcase(测试用例)的代码,一般放在一个单独的目录(case)

"""学习TestLoader的使用"""
# 1.导包(unittest)
import unittest


class TestLogin(unittest.TestCase):
    def test__username_password_ok(self):
        """正确的用户名和密码:admin。123456。登录成功"""
        self.assertEqual('登录成功', login('admin', '123456'))

    def test_username_error(self):
        """正确的用户名和密码:root。123456。登录失败"""
        self.assertEqual('登录失败', login('root', '123456'))

    def test_password_error(self):

        """正确的用户名和密码:admin。123123。登录失败"""
        self.assertEqual('登录失败', login('admin', '123123'))


登录失败 != 登录成功

Expected :登录成功
Actual   :登录失败

========================================================

参数化

参数化在测试方法中,使用变量来代替具体的测试数据,然后使用传参的方法将测试数据传递给方法的变量
好处:相似的代码不需要多次书写.
工作中场景:
1.测试数据─般放在json文件中
2.使用代码读取json文件,提取我们想要的数据--->[(),()] or [[],[]]
安装插件
unittest框架本身是不支持参数化,想要使用参数化,需要安装插件来完成
pip install parameterized
验证
pip list #查看到parameterized

参数化代码步骤

1.导包unittest/ pa
2.定义测试类
3.书写测试方法(用到的测试数据使用变量代替)
4.组织测试数据并传参
def Budil_Data():
    with open("./case/data.json", encoding="utf-8") as fp:
        data = []
        result = json.load(fp)
        for i in result:
            data.append((i.get('name'), i.get('pwd'), i.get('expect')))
    return data


class TestLogin(unittest.TestCase):
    @parameterized.parameterized.expand(Budil_Data)
    def test_login(self, name, pwd, expect):
        """正确的用户名和密码:admin。123456。登录成功"""
        self.assertEqual(expect, login(name, pwd))
-------------------------------------------------------------

跳过

对于一些未完成的或者不满足测试条件的测试函数和测试类,不想执行,可以使用跳过使用方法,装饰器完成
代码书写在Testcase文件

直接将测试函数标记成跳过

@unittest.skip(‘跳过额原因’)

根据条件判断测试函数是否跳过,判断条件成立,跳过

@unittest.skipIf(判断条件,'跳过原因)

# 1,导包
import unittest

ver = 30


# 2,自定义测试类,需要继承unittest模块中的 Testcase类即可
class TestDemo1(unittest.TestCase):
    def test_method1(self):
        print('测试方法1-1')

    @unittest.skip('没用')
    def test_method2(self):
        print('测试方法1-2')

    @unittest.skipIf(ver > 70, '跳过')
    def test_method3(self):
        print('测试方法2-1')

    def test_method4(self):
        print('测试方法2-2')


suite = unittest.TestSuite()

suite.addTest(unittest.makeSuite(TestDemo1))

runner = unittest.TextTestRunner()

runner.run(suite)

----------------------------------------------

3.HTMLTestRunner【重点】

3.1 HTMLTestRunner介绍
.HTMLTestRunner是一个第三方的类库,用来执行测试用例并生成HTML格式的测试报告·网上有多种不同的实现版本,用法都类似,只是生成的HTML报告样式有差别
·注意:下载的文件要与Python的版本兼容(有些版本只支持Python2.x)
本课程中介绍两种模板文件,HTMLTestRunner .py 和 HTMLTestRunner_PY3.py
HTMLTestRunner.py :样式比较简单,不需要依赖外部JS和CSS文件
HTMLTestRunner_PY3.py :样式比较美观,需要依顿外部JS和CSS文件
3.2测试报告截图

#1。获取第三方的测试运行类模块,将其放在代码的目录中

2。导包unittest

3.使用套件对象,加载对象去添加用例方法

#4.实例化第三方的运行对象并运行套件对象

# 1。获取第三方的测试运行类模块,将其放在代码的目录中

# 2。导包unittest
import unittest
from HtmlTestRunner import HTMLTestRunner

# 3.使用套件对象,加载对象去添加用例方法
suite = unittest.defaultTestLoader.discover('.', 'TestParameterized.py')

# 4.实例化第三方的运行对象并运行套件对象
# self, output="./reports/", verbosity=2, stream=sys.stderr,
#                  descriptions=True, failfast=False, buffer=False,
#                  report_title=None, report_name=None, template=None, resultclass=None,
#                  add_timestamp=True, open_in_browser=False,
#                  combine_reports=False, template_args=None

# stream=sys.stdout,必填,测试报告的文件对象(open ),注意点,要使用wb打开
# verbosity=1,可选,报告的详细程度,默认1简略,2详细
# titLe=None,可选,测试报告的标题
# description=None可选,描述信息,Python 的版本,pycharm 版本
fileName = "./reports.html"
with open(fileName, 'wb') as fp:
    runner = HTMLTestRunner(fp)

    runner = unittest.TextTestRunner(suite)

==========================================================================

总结 整体流程:

1.组织用例文件(TestCase 里边),书写参数化,书写断言,书写Fixture,书写跳过,如果单个测试测试文件,直接运行,得到测试报告,如果有多个测试文件,需要组装运行生成测试报告
2.使用套件对象组装,或者使用加载对象组装
3.运行对象运行
3.1运行对象=第三方的运行类(文件对象(打开文件需要使用wb方式))
3.2运行对象.run(套件对象)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值