unittest框架

news2025/1/15 17:22:47

unittest框架

  • 1.通过unittest框架创建测试
  • 2.通过unittest框架添加断言
  • 3.自动化用例管理TestLoader类的用法
  • 4.unittest智能封装等待

1.通过unittest框架创建测试

1.必须继承于unittest.TestCase类
2.可以定义setUp和tearDown方法进行初始化,每条测试用例开始或结束会执行。也可以使用setUpClass和tearDownClass来进行初始化,整个程序开始或结束会执行。
3.所有测试方法必须以test开头。测试方法会在运行时自动被调用。
4.可以pycharm自带的unittest框架运行,Run ‘Unittest for…’。也可以以普通方式运行。
在这里插入图片描述

  • setUp:每个测试方法执行前执行一次。
  • tearDown:每个测试方法结束后执行一次。
  • setUpClass:整个测试执行前执行一次。
  • tearDownClass: 整个测试执行后执行一次。

2.通过unittest框架添加断言

断言是为了判断实际结果与预期结果是否一致,任何测试都是需要断言的,否则就是操作,不能算自动化测试。在执行的过程中,断言失败了,就不会往下执行。
常见断言

  • assertIn
assertIn(key, container, message)
# key:在给定容器中检查其存在性的字符串
# container:在其中搜索关键字符串的字符串
# message:作为测试消息失败时显示的消息的字符串语句。可选项。

如果 key 包含在container字符串中,它将返回true,否则返回false,并提示message。

  • assertNotIn
  • assertEqual
assertEqual(firstValue, secondValue, message)
# firstValue按函数比较中使用的任何类型的变量
# secondValue:按函数比较时使用的任何类型的变量
# message:作为测试消息失败时显示的消息的字符串语句。
assertEqual(1, 1)

如果两个输入值相等,则assertEqual()将返回true,否则返回false。

  • assertNotEqual
  • assertTrue
assertTrue(testValue, message)
# testValue:布尔类型的变量,用于按功能比较
# message:作为测试消息失败时显示的消息的字符串语句。

如果测试值是true,则assertTrue()将返回true,否则返回false。

  • assertFalse

3.自动化用例管理TestLoader类的用法

测试用例有几百个,有时候只执行一部分,比如执行冒烟测试用例,回归测试用例,每次迭代的测试范围可能不一样。
TestLoader类常见方法

  • loadTestsFromTestCase()

smoketests.py 冒烟测试用例

import unittest
class SmokeTests(unittest.TestCase):  # 测试类必须继承unittest.TestCase类
      # 测试方法命名必须以test开头
        def testSk1(self):  # 测试用例1
            self.assertIn('hello', 'hell world')

        def testSk2(self):  # 测试用例2
            self.assertNotIn('hello', 'world')

requirementtests.py 需求测试用例

import unittest
class RequirementTests(unittest.TestCase):  # 测试类必须继承unittest.TestCase类
      # 测试方法命名必须以test开头
        def testRmt1(self):  # 测试用例1
            self.assertEqual(1, 1)

        def testRmt2(self):  # 测试用例2
            self.assertEqual(1, 1)

regressiontests.py 回归测试用例

import unittest
class RegressionTests(unittest.TestCase):  # 测试类必须继承unittest.TestCase类
      # 测试方法命名必须以test开头
        def testRg(self):  # 测试用例1
            self.assertIn(1, 1)

        def testRg(self):  # 测试用例2
            self.assertNotIn(1, 1)

performtests.py 执行用例

from smoketests import SmokeTests
from requirementtests import RequirementTests
from regressiontests import RegressionTests
import unittest
if __name__ == '__main__':
    sk = unittest.defaultTestLoader.loadTestsFromTestCase(SmokeTests) # 执行冒烟测试类里面的测试用例
    rq = unittest.defaultTestLoader.loadTestsFromTestCase(RequirementTests) # 执行需求测试类里面的测试用例
    rg = unittest.defaultTestLoader.loadTestsFromTestCase(RegressionTests) # 执行回归测试类里面的测试用例
    suite = unittest.TestSuite([sk])  # 执行一个测试类
    suite = unittest.TestSuite([sk, rq, rg])  # 执行冒烟,需求,回归测试
    unittest.TextTestRunner.run(suite)
  • loadTestsFromModule()
    从一个python文件里面导入测试方法
    performtests.py 执行用例
import smoketests, requirementtests, regressiontests 
import unittest
if __name__ == '__main__':
    names = [smoketests, requirementtests, regressiontests]  # 存放需要执行的测试类
    modules = []
    for item in names:
    	module = unittest.defaultTestLoader.loadTestsFromModule(item)
    	modules.append(module)
    suite = unittest.TestSuite(modules)  
    unittest.TextTestRunner.run(suite)
  • loadTestsFromNames()
    1)执行测试类里面的部分测试用例,意思是执行冒烟,需求,回归测试用例里面的几个测试用例
    performtests.py 执行用例
from smoketests import SmokeTests
from requirementtests import RequirementTests
from regressiontests import RegressionTests
import unittest
if __name__ == '__main__':
	names = ['smoketests.SmokeTests.testSk1', 'requirementtests.RequirementTests.testRmt1', 'regressiontests.RegressionTests.testRg1']  # 注意这里必须要从文件名.类名.方法写完整路径
	perform_test = unittest.defaultTestLoader.loadTestsFromNames(names)
	suite = unittest.TestSuite(perform_test) 
    unittest.TextTestRunner.run(suite)

2)如果想执行某个功能模块,这个模块在冒烟测试用例中有一些用例。
smoketests.py 冒烟测试用例

import unittest
class SmokeTests(unittest.TestCase):  # 测试类必须继承unittest.TestCase类
      # 测试方法命名必须以test开头,同一个模块测试方法命名有相同的字段
      # 登录模块的测试用例
        def testLoginSk1(self):  # 测试用例1
            self.assertIn('hello', 'hell world1')
		def testLoginSk2(self):  # 测试用例2
            self.assertIn('hello', 'hell world2')
        def testLoginSk3(self):  # 测试用例3
            self.assertIn('hello', 'hell world3')
      # 注册模块的测试用例
        def testregistSk1(self):  # 测试用例4
            self.assertNotIn('hello', 'world')
        def testregistSk2(self):  # 测试用例5
            self.assertNotIn('hello', 'world')

performtests.py 执行用例

from smoketests import SmokeTests
import unittest
def getFullTestCaseNames(names):
	full_nams = []
	for item in names:
		if 'Login' in item:
			full_names.append('smoketests.SmokeTests.' + item)
if __name__ == '__main__':
	names = unittest.defaultTestLoader.getTestCaseNames(SmokeTests)
	perform_test = unittest.defaultTestLoader.loadTestsFromNames(getFullTestCaseNames(names))
	suite = unittest.TestSuite(perform_test) 
    unittest.TextTestRunner.run(suite)
  • discover()

项目中最常用的方法,根据测试路径去选择执行哪些测试用例,冒烟,需求,回归测试用例用包分类存放用例
cases包 存放测试文件smoke包 ,requirement包,regression包
smoke包 存放冒烟测试用例的py文件
requirement包 存放冒烟测试用例的py文件
regression包 存放冒烟测试用例的py文件

performtests.py 执行用例

if __name__ == '__main__':
	case_dir = 'cases'  # cases包
	perform_test = unittest.defaultTestLoader.discover(case_dir + '/smoke', pattern='*.py')  # cases包下的smoke包下的所有py文件
	suite = unittest.TestSuite(perform_test) 
    unittest.TextTestRunner.run(suite)

4.unittest智能封装等待

webdriver有强制等待,显示等待,隐式等待,详解见web自动化测试-等待

import unittest
from selenium import webdriver
from selenium.common.exceptions import NoSuchFrameException
from selenium.webdriver.support.wait import WebDriverWait

class waitTest(unittest.TestCase):

    def setUp(self) -> None:
        self.driver = webdriver.Chrome()
        self.driver.get('')

    def tearDown(self) -> None:
        self.driver.quit()

    def find_element(self, locator):
    # 封装driver.find_element方法
    # locator参数是元素定位
        try:
            element = WebDriverWait(self.driver, 30 ,0.5).until(lambda x: x.find_element(*locator))
            return element
        except NoSuchFrameException as e:
            print('Error details:{}'.format(e.args[0])) # e.args[0]指错误的原因
            
    def test1(self):  # 测试用例1,这里元素操作就可以不用等待
        self.find_element(('id', 'username')).send_keys('admin')
        self.find_element(('id', 'password')).send_keys('123456')
        self.find_element(('id', 'login')).click()
        self.find_element(('partial link text', '会议'))

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

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

相关文章

谷歌浏览器-chrome浏览器占用电脑CPU过高、容易崩溃的解决办法

一、问题背景 最近特别难受的一点——谷歌浏览器总是莫名其妙崩溃,而且明明是只开了两三个标签页的情况下。 不管是谷歌自己的任务管理器,还是win10自带的任务管理器;在崩溃情况下,谷歌浏览器的电脑cpu占用率高达80以上。 网上…

Java01-JDK1.8下载安装教程(win11版)

文章导航JDK 1.8 官网下载(下载慢)百度网盘下载(下载快)安装过程JDK环境配置教程验证JDK是否安装成功使用JDK1.8的原因当下互联网行情以及个人建议JDK 1.8 官网下载(下载慢) 点击跳转至JDK1.8官方网址 32…

暴雪和网易分手百万玩家何去何从

暴雪和网易分手百万玩家何去何从 这两天看到很多报道说网易与暴雪分手的消息,作为一个游戏玩家我甚是感到很意外。 看了不少相关的报道消息才有了今天的这篇文章 暴雪和其旗下《魔兽世界》等游戏陪伴了我们这一代人成长,或许终究不属于这个时代。看到暴…

智慧路灯解决方案-最新全套文件

智慧路灯解决方案-最新全套文件一、建设背景二、思路架构三、建设方案四、获取 - 智慧路灯全套最新解决方案合集一、建设背景 智慧城市是利用信息通信技术感知、分析、整合城市运行核心系统的各种关键信息,从而改善民生、环保、公共安全、城市服务、智能响应包括工…

【Java八股文总结】之反射

文章目录Java反射一、泛型1、何为泛型?2、泛型通配符Q:泛型擦除是什么?3、泛型上限和下限二、反射1、何为反射?2、反射有什么用?3、反射应用场景有哪些?Q:反射的优缺点?4、反射获取C…

三极管集电极电阻的作用

放大状态:电流信号转变为电压信号 饱和状态 ;发射极正偏,集电极反偏 当有无电阻的作用。当集电极有电阻时,可以得到随IC电流变化的电压信号,当工作在饱和状态。集电阻电阻越大。越容易进入饱和状态.当Ib有个小电流,Ic会出现大的…

Dubbo的SPI机制

目录 什么是 SPI Java SPI 示例 Java SPI 源码分析 想一下 Java SPI 哪里不好 Dubbo SPI Dubbo SPI 简单实例 Dubbo 源码分析 getExtensionClasses Adaptive 注解 - 自适应扩展 Adaptive 注解在类上 Adaptive 注解在方法上 WrapperClass - AOP injectExtension - …

webpack 官方文档解读一(详细使用教程) 起步

什么是webpack 就是个打包工具。通过一系列插件帮你优化项目,压缩,混淆等。总之什么脏活累活都能干。 入门案例 创建一个目录,并安装webpack和webpack-cli这两个包。webpack包是webpack本体,webpack-cli是他提供的工具包。 mk…

RTL8380M/RTL8382M管理型交换机系统软件操作指南二:转发表

前面介绍了端口配置,这次对转发表进行详细的描述,主要包括以下三方面内容:基础配置、转发表、删除1.1 基础配置 1.1.1 老化时间 老化时间是一个影响交换机学习进程的参数。从一个地址记录加入地址表以后开始计时,如果在老化时间内各端口未收…

ResNet网络详解

ResNet ResNet在2015年由微软实验室提出,斩获当年lmageNet竞赛中分类任务第一名,目标检测第一名。获得coco数据集中目标检测第一名,图像分割第一名。 ResNet亮点 1.超深的网络结构(突破1000层) 2.提出residual模块 3.使用Batch Normalizat…

java项目-第147期ssm社区生活超市管理系统_(spring+springmvc+mybatis+jsp)_java毕业设计_计算机毕业设计

java项目-第147期ssm社区生活超市管理系统_(springspringmvcmybatisjsp)_java毕业设计_计算机毕业设计 【源码请到资源专栏下载】 今天分享的项目是《ssm社区生活超市管理系统》 该项目分为3个角色,管理员、用户、供应商角色。 用户可以浏览前台商品,进行…

[附源码]java毕业设计软件项目过程管理系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

牛客小白月赛 61 E 排队

题目大意: n个数,共有n!种排列方式,记Pi(a)表示序列a的第i种排队方式,cnt(Pi(a))表示P(i)的逆序对个数,PLMM想知道这n!种排列方式共有多少对逆序对 给定一个 nnn 个数,在所有排列顺序…

Windows 11 Insider Preview Build 25247.1000(rs_prerelease)更新内容

微软于今日推出了新的Dev预览版25247.1000,引入了电源设置的新能源建议,“帐户”页面现在会在 OneDrive 存储空间不足时显示警告。下面就和小编一起来看看详细的更新内容吧。 更新内容 此版本包括一些新功能,包括能源建议、任务管理器的一些改…

MySQL8.0优化 - 锁 - 从数据操作的类型划分:读锁、写锁

文章目录学习资料锁的不同角度分类锁的分类图如下从数据操作的类型划分:读锁、写锁读锁写锁锁定读MySQL8.0新特性写操作学习资料 【MySQL数据库教程天花板,mysql安装到mysql高级,强!硬!-哔哩哔哩】 【阿里巴巴Java开…

【21-业务开发-基础业务-商品模块-分类管理-商品系统三级分类的新增类别前后端代码实现-商品系统三级分类的更新类别前后端代码实现-之前错误的Bug修正】

一.知识回顾 【0.三高商城系统的专题专栏都帮你整理好了,请点击这里!】 【1-系统架构演进过程】 【2-微服务系统架构需求】 【3-高性能、高并发、高可用的三高商城系统项目介绍】 【4-Linux云服务器上安装Docker】 【5-Docker安装部署MySQL和Redis服务】…

2022 全网最全最新 Java 面试题 - 独家内部教材

怎样才能拿到大厂的 offer,没有掌握绝对的技术,那么就要不断的学习 从疫情破局而出,又在毕业季一路过关斩将,我是如何笑面试官,拿到阿里,腾讯等八家大厂的 offer 的呢,在这里分享我的秘密武器&…

kubernetes(K8S)学习笔记P3:集群 YAML 文件(部署)

集群 YAML 文件(部署)4.集群 YAML 文件(部署)4.1 YAML 文件概述4.2YAML 文件书写格式4.2.1YAML 介绍4.2.2YAML 基本语法4.2.3YAML 支持的数据结构4.3资源清单描述方法4.3.1常用字段4.3.2字段解释4.4快速编写yml-->kubdectl cre…

数据结构由中序序列和后序序列构造二叉树

2022.11.19 由中序序列和后序序列构造二叉树任务描述相关知识编程要求测试说明C/C代码任务描述 本关任务要求采用中序遍历序列和后序遍历序列构造二叉树。 相关知识 给定一棵二叉树的中序遍历序列和后序遍历序列可以构造出这棵二叉树。例如后序序列是DEBFGCA,中序…

MySQL8.0优化 - 锁 - 从对待锁的态度划分:乐观锁、悲观锁

文章目录学习资料锁的不同角度分类锁的分类图如下从对待锁的态度划分:乐观锁、悲观锁悲观锁(Pessimistic Locking)乐观锁(Optimistic Locking)两种锁的适用场景学习资料 【MySQL数据库教程天花板,mysql安装…