python-UnitTest框架笔记

news2025/2/4 23:10:30

UnitTest框架的基本使用方法

UnitTest框架介绍
框架:framework,为了解决一类事情的功能集合

UnitTest框架:是python自带的单元测试框架
自带的,可以直接使用,不需要格外安装
测试人员用来做自动化测试,作为自动化测试的执行框架,即管理和执行测试用例的

使用原因:
能够组织多个用例去执行
提供丰富的断言方法
能够生成测试报告

核心要素(组成):
-TestCase测试用例,这个测试用例是UnitTest的组成部分,作用是用来书写真正的用例代码(脚本)
-TestSuite测试套件,作用是用来组装TestCase的,即可以将多个用例脚本文件组装到一起
-TestRunner测试执行,作用是用来执行TestSuite的
-TestLoader测试加载,是对TestSuite功能的补充,作用是用来组装TestCase的
-Fixture测试夹具,是一种代码结构,书写前置方法代码和后置方法代码,即用例执行顺序:前置–>用例–>后置

TestCase测试用例
书写真正的用例代码(脚本)
步骤:
-1.导包unittest
-2.定义测试类
-3.书写测试方法
-4.执行
注意事项:
代码文件名字要满足标识符的规则
代码文件名不要使用中文
代码:

#导包
import unittest
#定义测试类,只要继承unittest.TestCase类,就是测试类
class TestDemo(unittest.TestCase):
    #书写测试方法,方法中的代码就是真正的用例代码,方法名必须以test开头
    def test_method1(self):
        print("测试方法一")
    def test_method2(self):
        print("测试方法二")
#执行
#在类名或者方法名后边右键运行
#在类名后边,执行类中的所有测试方法
#在方法名后边,只执行当前的测试方法

#在主程序中使用unittest.main()来执行
if __name__ == '__main__':
    unittest.main()

TestCase常见错误
1.文件名包含中文-------执行可能报错
2.右键运行没有unittest for …
解决方法一:新建一个代码文件,将之前的代码复制过来
解决方法二:使用unittest.main()运行
解决方法三:在这里插入图片描述
TestSuite和TestRunner的使用
TestSuite测试套件:将多条脚本集合在一起,就是套件,即用来组装用例的
1.导包unittest
2.实例化套件对象unittest.TestSuite()
3.添加用例方法,套件对象.addTest(测试类名(测试方法名))

TestRunner测试执行:用来执行套件对象
1.导包unittest
2.实例化执行对象unittest.TextTestRunner()
3.执行对象执行套件对象,执行对象.run(套件对象)

整体步骤:
1.导包unittest
2.实例化套件对象unittest.TestSuite()
3.添加用例方法,套件对象.addTest(测试类名(测试方法名))
4.实例化执行对象unittest.TextTestRunner()
5.执行对象执行套件对象,执行对象.run(套件对象)

代码案例
套件可以用来组装用例,创建多个代码用例

#导包
import unittest
#定义测试类,只要继承unittest.TestCase类,就是测试类
class TestDemo1(unittest.TestCase):
    #书写测试方法,方法中的代码就是真正的用例代码,方法名必须以test开头
    def test_method1(self):
        print("测试方法1-1")
    def test_method2(self):
        print("测试方法1-2")
#导包
import unittest
#定义测试类,只要继承unittest.TestCase类,就是测试类
class TestDemo2(unittest.TestCase):
    #书写测试方法,方法中的代码就是真正的用例代码,方法名必须以test开头
    def test_method1(self):
        print("测试方法2-1")
    def test_method2(self):
        print("测试方法2-2")
#1.导包unittest
import unittest

from unittest1.TestCase.yongli1 import TestDemo2
from unittest1.TestCase.yongli2 import TestDemo1

#2.实例化套件对象unittest.TestSuite()
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'))
#4.实例化执行对象unittest.TextTestRunner()
runner=unittest.TextTestRunner()
#5.执行对象执行套件对象,执行对象.run(套件对象)
runner.run(suite)

添加整个测试类中的方法
方法一
套件对象.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(测试类名))
#把指定测试类中的测试用例全部添加到测试套件中
方法二
套件对象.addTest(unittest.makeSuite(测试类名))

#1.导包unittest
import unittest

from unittest1.TestCase.yongli1 import TestDemo2
from unittest1.TestCase.yongli2 import TestDemo1

#2.实例化套件对象unittest.TestSuite()
suite=unittest.TestSuite()
#3.添加用例方法,套件对象.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(测试类名))
suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(TestDemo1))
suite.addTest(unittest.makeSuite(TestDemo2))
#4.实例化执行对象unittest.TextTestRunner()
runner=unittest.TextTestRunner()
#5.执行对象执行套件对象,执行对象.run(套件对象)
runner.run(suite)

查看测试结果
在这里插入图片描述
TestLoader测试加载
在这里插入图片描述

作用和TestSuite作用一样,组装用例代码,同样也需要使用TextTestRunner()方法去执行
TestLoader加载用例更加方便
1.导包import unittest
2.实例化加载对象并加载用例---->得到的是套件对象
3.实例化执行对象并执行

#1.导包
import unittest
#2.实例化加载对象并加载用例---->得到的是套件对象
suite=unittest.TestLoader().discover('.','yongli*.py')   #参数1:用例所在目录,参数2:用例代码文件名
#3.实例化执行对象并执行
runner=unittest.TextTestRunner()
runner.run(suite)

练习
练习1
在这里插入图片描述
用例代码

#导包
import unittest
#定义测试类,只要继承unittest.TestCase类,就是测试类
class TestDemo1(unittest.TestCase):
    #书写测试方法,方法中的代码就是真正的用例代码,方法名必须以test开头
    def test_method(self):
        print("测试方法1")

执行代码

import unittest

suite=unittest.TestLoader().discover('./case','test_*.py')
unittest.TextTestRunner().run(suite)

在这里插入图片描述
练习2
在这里插入图片描述

import unittest
from tools1 import add
class TestDemo(unittest.TestCase):
    def test_method1(self):
        if add(1,1) == 2:
            print("测试通过")
        else:
            print("测试失败")
    def test_method2(self):
        if add(2,1) == 3:
            print("测试通过")
        else:
            print("测试失败")
    def test_method3(self):
        if add(3,4) == 7:
            print("测试通过")
        else:
            print("测试失败")
    def test_method4(self):
        if add(4,5) == 9:
            print("测试通过")
        else:
            print("测试失败")
import unittest

suite=unittest.TestLoader().discover('.','test_*.py')

unittest.TextTestRunner().run(suite)

fixture说明
代码结构,在用例执行前后会自动执行的代码结构
tpshop登录
1.打开浏览器(一次)
2.打开网页,点击登录(每次)
3.输入用户名,密码,验证码,点击登录(每次)
4.关闭页面(每次)
5.关闭浏览器(一次)

方法级别Fixture:
在每个用例执行前后都会自动调用,方法名是固定的
def setUp(self): #前置方法,每个用例执行前调用
pass
def tearDown(self): #后置方法,每个用例执行之后都会调用
pass

类级别Fixture:
在类中所有的测试方法执行前后,会自动执行的代码,类开始前执行和类执行结束时执行一次
类级别的Fixture需要写作类方法
@classmethod
def setUpClass(cls): #前置方法,类执行前调用
pass
@classmethod
def tearDownClass(cls): #后置方法,类执行之后都会调用
pass

模块级别Fixture:
模块就是代码文件,在代码文件执行前后执行一次
在类外部定义函数
def setUpModule(): #前置
pass
def tearDownpModule(): #前置
pass

Fixture实现
在这里插入图片描述
测试用例

import unittest

class TestDemo(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print("打开浏览器")
    @classmethod
    def tearDownClass(cls):
        print("关闭浏览器")
    def setUp(self):
        print("打开网页,点击登录")
    def tearDown(self):
        print("关闭页面")
    def test_method1(self):
        print("输入用户名密码验证码1,点击登录")
    def test_method2(self):
        print("输入用户名密码验证码2,点击登录")
    def test_method3(self):
        print("输入用户名密码验证码1,点击登录")

测试运行

import unittest

suite=unittest.TestLoader().discover('.','test_*.py')

unittest.TextTestRunner().run(suite)

断言的使用

断言
使用代码自动判断预期结果和实际结果是否相等
在这里插入图片描述
练习
在这里插入图片描述

import unittest
from tools1 import add
class TestDemo(unittest.TestCase):
    def test_method1(self):
        self.assertEqual(2,add(1,1))
    def test_method2(self):
        self.assertEqual(3,add(1, 2))
    def test_method3(self):
        self.assertEqual(7,add(3, 4))
    def test_method4(self):
        self.assertEqual(9,add(4, 5))
import unittest
suite=unittest.TestLoader().discover('.','test_*.py')
unittest.TextTestRunner().run(suite)

实现参数化

参数化环境安装
通过参数的方式来传递数据,从而实现数据和脚本分离,并且可以实现用例的重复执行。(在书写用例方法的时候,测试数据使用变量代替,在执行的时候进行数据传递)
-unittest测试框架,本身不支持参数化,但是可以通过安装unittest扩展插件parameterized来实现。
因为参数化的插件不是unittest自带的,所以想要使用,需要进行安装
安装:pip install -i http://pypi.douban.com/simple parameterized

参数化
1.导包 from parameterized import parameterized
2.修改测试方法,将测试方法中的测试数据使用变量表示
3.组织测试数据,格式[(),(),()],一个元组就是一组测试数据
4.参数化,在测试方法上方使用装饰器@parameterized.expand(测试数据)
5.运行(直接运行TestCase或者使用suite运行)

import unittest
from parameterized import parameterized
from tools1 import add

class TestDemo(unittest.TestCase):
    list = [(1, 1, 2), (1, 2, 3), (3, 4, 7), (2, 3, 5)]
    @parameterized.expand(list)
    def test_method1(self,a,b,expect):
        self.assertEqual(expect,add(a,b))

练习1
在这里插入图片描述

import json
def getDate():
    with open('../package1/one.json', 'r', encoding='utf-8') as f:
        list=json.load(f)
        list1=[]
        for i in list:
            list1.append(tuple(i.values()))
    return list1
import unittest
from parameterized import parameterized
from lianxi2.getDate import getDate
from tools1 import add

class TestDemo(unittest.TestCase):
    @parameterized.expand(getDate())
    def test_method1(self,a,b,expect):
        self.assertEqual(expect,add(a,b))

测试报告和跳过

测试报告
使用第三方的报告模板,生成报告HTMLTestReport,本质是TestRunner
安装
pip install -i http://pypi.doouban.com/simple/ HTMLTestReport
使用
1.导包unittest;HTMLTestReport
2.组装用例(套件,loader)
3.使用HTMLTestReport中的runner执行
4.查看报告

import unittest
from htmltestreport import HTMLTestReport

if __name__ == '__main__':
    #套件
    suite = unittest.TestLoader().discover('.', 'test_*.py')
    #运行runner=HTMLTestReport(报告文件目录, 报告标题,其他描述信息)
    runner=HTMLTestReport('report.html', '测试报告','add')
    runner.run(suite)

在这里插入图片描述
使用绝对路径
将来的项目是分目录书写的,使用相对路径,可能会出现找不到文件的情况,此时需要使用绝对路径
方法:
1.在项目的根目录,创建一个python文件(app.py或者config.py)
2.在这个文件中获取项目的目录,在其他代码中使用路径拼接完成绝对路径的书写

在这里插入图片描述

import os
#获取项目绝对路径
path1=os.path.abspath(__file__)   #__file__ 是特殊变量,表示当前代码文件名
base_addr=os.path.dirname(path1)
import os
import unittest
from htmltestreport import HTMLTestReport
from base_addr import base_addr

if __name__ == '__main__':
    #套件
    suite = unittest.TestLoader().discover('.', 'test_*.py')
    #运行runner=HTMLTestReport(报告文件目录, 报告标题,其他描述信息)
    #runner=HTMLTestReport('report.html', '测试报告','add')
    #绝对路径
    filepath=os.path.join(base_addr,'lianxi2/report/report.html')
    runner=HTMLTestReport(filepath, '测试报告','add')
    runner.run(suite)

案例
在这里插入图片描述
tools.py

def login(username,password):
    if username=='admin' and password=='123456':
        return '登录成功'
    else:
        return '登录失败'

测试数据one.json

[{
	"desc": "正确的用户名和密码",
	"username": "admin",
	"password":"123456",
	"excpet":"登录成功"
}, {
	"desc": "错误密码",
	"username": "admin",
	"password":"admin",
	"excpet":"登录失败"
}, {
	"desc": "错误用户名",
	"username": "admin1",
	"password":"123456",
	"excpet":"登录失败"
}]

获取测试数据getDate.py

import json
def getDate():
    with open('../package1/one.json', 'r', encoding='utf-8') as f:
        list=json.load(f)
        list1=[]
        for i in list:
            list1.append(tuple(i.values())[1:])
    return list1

测试用例

import unittest
from parameterized import parameterized
from lianxi2.getDate import getDate
from tools import login

class TestDemo(unittest.TestCase):
    @parameterized.expand(getDate())
    def test_method1(self,a,b,expect):
        self.assertEqual(expect,login(a,b))

执行并生成测试报告

import os
import unittest
from htmltestreport import HTMLTestReport
from base_addr import base_addr

if __name__ == '__main__':
    #套件
    suite = unittest.TestLoader().discover('.', 'test_*.py')
    #运行runner=HTMLTestReport(报告文件目录, 报告标题,其他描述信息)
    #绝对路径
    filepath=os.path.join(base_addr,'lianxi2/report/report.html')
    runner=HTMLTestReport(filepath, '测试报告','login')
    runner.run(suite)

报告
在这里插入图片描述
跳过
对于一些未完成的或者不满足测试条件的测试函数和测试类,可以执行跳过(简单来说,不想执行的代码的存测试方法,可以设置跳过)

直接将测试函数标记成跳过
@unittest.skip(“跳过原因”)
根据条件判断测试函数是否跳过
@unittest.skipIf(判断条件,reason=‘原因’) #判断条件为True,执行跳过

import unittest
from parameterized import parameterized
from lianxi2.getDate import getDate
from tools1 import login

version=30
class TestDemo(unittest.TestCase):
    @parameterized.expand(getDate())
    def test_method1(self,a,b,expect):
        self.assertEqual(expect,login(a,b))
    @unittest.skip("跳过举例")
    def test_method2(self):
        print("测试方法二")
    @unittest.skipIf(version>30,"版本大于30跳过")
    def test_method3(self):
        print("测试方法三")
    @unittest.skipUnless(version<30,"版本小于30跳过")
    def test_method4(self):
        print("测试方法四")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2292024.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

掌握API和控制点(从Java到JNI接口)_35 JNI开发与NDK 03

3、 如何载入 .so档案 VM的角色 由于Android的应用层级类别都是以Java撰写的&#xff0c;这些Java类别转译为Dex型式的Bytecode之后&#xff0c;必须仰赖Dalvik虚拟机器(VM: Virtual Machine)来执行之。 VM在Android平台里&#xff0c;扮演很重要的角色。此外&#xff0c;在执…

CDDIS从2025年2月开始数据迁移

CDDIS 将从 2025 年 2 月开始将我们的网站从 cddis.nasa.gov 迁移到 earthdata.nasa.gov&#xff0c;并于 2025 年 6 月结束。 期间可能对GAMIT联网数据下载造成影响。

VSCode设置内容字体大小

1、打开VSCode软件&#xff0c;点击左下角的“图标”&#xff0c;选择“Setting”。 在命令面板中的Font Size处选择适合自己的字体大小。 2、对比Font Size值为14与20下的字体大小。

嵌入式学习---蜂鸣器篇

1. 蜂鸣器分类 蜂鸣器是一种电子发声器件&#xff0c;采用直流电压供电&#xff0c;能够发出声音。广泛应用于计算机、打印机、报警器、电子玩具等电子产品中作为发声部件。一般仅从外形不易分辨蜂鸣器的种类。但是有些蜂鸣器使用广泛&#xff0c;见得多了就很容易分辨。例如常…

【优先算法】专题——前缀和

目录 一、【模版】前缀和 参考代码&#xff1a; 二、【模版】 二维前缀和 参考代码&#xff1a; 三、寻找数组的中心下标 参考代码&#xff1a; 四、除自身以外数组的乘积 参考代码&#xff1a; 五、和为K的子数组 参考代码&#xff1a; 六、和可被K整除的子数组 参…

【Linux】使用管道实现一个简易版本的进程池

文章目录 使用管道实现一个简易版本的进程池流程图代码makefileTask.hppProcessPool.cc 程序流程&#xff1a; 使用管道实现一个简易版本的进程池 流程图 代码 makefile ProcessPool:ProcessPool.ccg -o $ $^ -g -stdc11 .PHONY:clean clean:rm -f ProcessPoolTask.hpp #pr…

找不到msvcp140.dll解决方法

您可以尝试以下方案进行修复&#xff0c;看看是否可以解决这个问题&#xff1a; 一、重新注册 msvcp140.dll 运行库文件&#xff1a; “WinR”打开运行&#xff0c;键入&#xff1a;regsvr32 MSVCP140.dll&#xff0c;回车即可&#xff1b; 如果出现找不到该文件的提示&…

【优先算法】专题——位运算

在讲解位运算之前我们来总结一下常见的位运算 一、常见的位运算 1.基础为运算 << &&#xff1a;有0就是0 >> |&#xff1a;有1就是1 ~ ^&#xff1a;相同为0&#xff0c;相异位1 /无进位相加 2.给一个数 n&#xff0c;确定它的二进制表示…

【Cadence仿真技巧学习笔记】求解65nm库晶体管参数un, e0, Cox

在设计放大器的第一步就是确定好晶体管参数和直流工作点的选取。通过阅读文献&#xff0c;我了解到L波段低噪声放大器的mos器件最优宽度计算公式为 W o p t . p 3 2 1 ω L C o x R s Q s p W_{opt.p}\frac{3}{2}\frac{1}{\omega LC_{ox}R_{s}Q_{sp}} Wopt.p​23​ωLCox​Rs…

Docker入门篇(Docker基础概念与Linux安装教程)

目录 一、什么是Docker、有什么作用 二、Docker与虚拟机(对比) 三、Docker基础概念 四、CentOS安装Docker 一、从零认识Docker、有什么作用 1.项目部署可能的问题&#xff1a; 大型项目组件较多&#xff0c;运行环境也较为复杂&#xff0c;部署时会碰到一些问题&#xff1…

开源智慧园区管理系统对比其他十种管理软件的优势与应用前景分析

内容概要 在当今数字化快速发展的时代&#xff0c;园区管理软件的选择显得尤为重要。而开源智慧园区管理系统凭借其独特的优势&#xff0c;逐渐成为用户的新宠。与传统管理软件相比&#xff0c;它不仅灵活性高&#xff0c;而且具有更强的可定制性&#xff0c;让各类园区&#…

【C++】P5734 【深基6.例6】文字处理软件

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;题目描述&#x1f4af;题目描述输入格式输出格式示例输入与输出输入&#xff1a;输出&#xff1a; &#x1f4af;我的做法操作1&#xff1a;在文档末尾插入字符串操作2&…

CSS核心

CSS的引入方式 内部样式表是在 html 页面内部写一个 style 标签&#xff0c;在标签内部编写 CSS 代码控制整个 HTML 页面的样式。<style> 标签理论上可以放在 HTML 文档的任何地方&#xff0c;但一般会放在文档的 <head> 标签中。 <style> div { color: r…

013-51单片机红外遥控器模拟控制空调,自动制冷制热定时开关

主要功能是通过红外遥控器模拟控制空调&#xff0c;可以实现根据环境温度制冷和制热&#xff0c;能够通过遥控器设定温度&#xff0c;可以定时开关空调。 1.硬件介绍 硬件是我自己设计的一个通用的51单片机开发平台&#xff0c;可以根据需要自行焊接模块&#xff0c;这是用立创…

CMake项目编译与开源项目目录结构

Cmake 使用简单方便&#xff0c;可以跨平台构建项目编译环境&#xff0c;尤其比直接写makefile简单&#xff0c;可以通过简单的Cmake生成负责的Makefile文件。 如果没有使用cmake进行编译&#xff0c;需要如下命令&#xff1a;&#xff08;以muduo库echo服务器为例&#xff09;…

OPENPPP2 —— VMUX_NET 多路复用原理剖析

在阅读本文之前&#xff0c;必先了解以下几个概念&#xff1a; 1、MUX&#xff08;Multiplexer&#xff09;&#xff1a;合并多个信号到单一通道。 2、DEMUX&#xff08;Demultiplexer&#xff09;&#xff1a;从单一通道分离出多个信号。 3、单一通道&#xff0c;可汇聚多个…

语言月赛 202412【正在联系教练退赛】题解(AC)

》》》点我查看「视频」详解》》》 [语言月赛 202412] 正在联系教练退赛 题目背景 在本题中&#xff0c;我们称一个字符串 y y y 是一个字符串 x x x 的子串&#xff0c;当且仅当从 x x x 的开头和结尾删去若干个&#xff08;可以为 0 0 0 个&#xff09;字符后剩余的字…

【数据结构】_链表经典算法OJ:复杂链表的复制

目录 1. 题目链接及描述 2. 解题思路 3. 程序 1. 题目链接及描述 题目链接&#xff1a;138. 随机链表的复制 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;…

python的pre-commit库的使用

在软件开发过程中&#xff0c;保持代码的一致性和高质量是非常重要的。pre-commit 是一个强大的工具&#xff0c;它可以帮助我们在提交代码到版本控制系统&#xff08;如 Git&#xff09;之前自动运行一系列的代码检查和格式化操作。通过这种方式&#xff0c;我们可以确保每次提…

【C语言入门】解锁核心关键字的终极奥秘与实战应用(三)

目录 一、auto 1.1. 作用 1.2. 特性 1.3. 代码示例 二、register 2.1. 作用 2.2. 特性 2.3. 代码示例 三、static 3.1. 修饰局部变量 3.2. 修饰全局变量 3.3. 修饰函数 四、extern 4.1. 作用 4.2. 特性 4.3. 代码示例 五、volatile 5.1. 作用 5.2. 代码示例…