【软件测试开发】Junit5单元测试框架
目录
- 1. 注解
- @Test 注解
- @BeforeEach @BeforeAll
- @AfterEach @AfterAll
- 2. 断言 assert
- assertequals
- assertTrue assertFalse
- assertNull assertNotNull
- 3. 用例执行顺序
- 方法排序,通过 @Order 注解来排序
- 4. 测试套件 Suite
- 5. 参数化单参数
- strings
- ints
- 6. 参数化多参数
- @CsvSource
- @CsvFileSource
- 7. 动态参数
- 动态参数单参数
- 动态参数多参数
● 实现自动化测试需要 selenium基本语法+Junit单元测试框架才能完成自动化测试
Junit是一个开源的Java语言的单元测试框架,Junit是Java方向使用最广泛的单元测试框架,使用Java开发者都应当学习Junit并且掌握单元测试的编写
selenium和Junit:假如要实现一个灯泡,selenium就是灯泡,Junit就是电源
首先需要在pom文件中引入Junit依赖:
<dependencies><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>4.0.0</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency><!-- https://mvnrepository.com/artifact/junit/junit --><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.8.2</version><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-launcher --><!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-suite-api --><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-suite</artifactId><version>1.8.2</version><scope>test</scope></dependency><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-reporting</artifactId><version>1.8.2</version><scope>test</scope></dependency></dependencies>
1. 注解
@Test 注解
@Test 能够表示一个方法/用例
在不引入注解的情况下执行测试方法需要在Java main方法中去执行,使用注解之后只需要在要执行的测试方法上面加上 @Test 注解即可直接进行测试方法的执行:
public class JunitAutoTest {private final ChromeDriver chromeDriver=new ChromeDriver();public void start(){chromeDriver.get("https://www.baidu.com/");}@Testpublic void zhujieTest() throws InterruptedException {start();chromeDriver.findElement(By.cssSelector("#kw")).sendKeys("junit");chromeDriver.findElement(By.cssSelector("#su")).click();Thread.sleep(3000);end();}public void end(){chromeDriver.quit();}
}
不需要再次创建一个runtest类来执行,大大加快了测试执行;
@BeforeEach @BeforeAll
@BeforeEach :表示被注解的方法应该在其他方法执行之前都执行一遍
public class JunitAutoTest {@BeforeEachpublic void aaa(){System.out.println("pre");}@Testpublic void bbb(){System.out.println("bbb");}@Testpublic void ccc(){System.out.println("ccc");}}
在 aaa 方法上加了 @BeforeEach 注解表示在执行 bbb,ccc方法之前都会各自执行一次aaa方法,打印 pre:
@BeforeAll :表示在其他方法执行之前只需要执行一遍
● 使用 @BeforeAll 注解的方法必须定义为static静态方法
public class JunitAutoTest {@BeforeAll // 必须定义为static方法,否则报错public static void aaa(){System.out.println("pre");}@Testpublic void bbb(){System.out.println("bbb");}@Testpublic void ccc(){System.out.println("ccc");}}
在执行 bbb ccc 方法之前先执行一遍 aaa 方法,只打印一次 pre:
@AfterEach @AfterAll
用法和之前的 @BeforeEach 和 @BeforeAll 类似,表示注解的方法应该在其他方法执行之后执行:
@AfterEach:表示被注解的方法应该在其他方法执行之后都执行一遍:
public class JunitAutoTest {@AfterEachpublic void aaa(){System.out.println("pre");}@Testpublic void bbb(){System.out.println("bbb");}@Testpublic void ccc(){System.out.println("ccc");}}
@AfterAll:表示在其他方法执行之后只需要执行一遍
● 使用 @AfterAll 注解的方法必须定义为static静态方法
public class JunitAutoTest {@AfterAllpublic static void aaa(){System.out.println("pre");}@Testpublic void bbb(){System.out.println("bbb");}@Testpublic void ccc(){System.out.println("ccc");}}
2. 断言 assert
写自动化测试,结果分为成功或者失败的,怎么评判结果是成功还是失败,就需要用到 assert 断言操作
assertequals
● assertequals(expect,actual)
public class AssertTest {private final ChromeDriver chromeDriver=new ChromeDriver();/*** 测试百度首页元素是否正确*/@Testvoid equalsTest(){chromeDriver.get("https://www.baidu.com/");String value = chromeDriver.findElement(By.cssSelector("#su")).getAttribute("value");Assertions.assertEquals("百度一下",value);}
}
断言成功:
断言失败:
同理还可以判断不相等:assertNotEquals
@Testvoid equalsTest(){chromeDriver.get("https://www.baidu.com/");String value = chromeDriver.findElement(By.cssSelector("#su")).getAttribute("value");Assertions.assertNotEquals("百s度一下",value);chromeDriver.quit();}
此时不相等,断言成功:
assertTrue assertFalse
assertTrue assertFalse 参数是表达式,也就是Boolean类型的
@Testvoid assertTrueTest(){chromeDriver.get("https://www.baidu.com/");String value = chromeDriver.findElement(By.cssSelector("#su")).getAttribute("value");Assertions.assertTrue(value.equals("百度一下")); // true 执行通过chromeDriver.quit();}
assertFalse 同理
assertNull assertNotNull
@Testvoid assertNull(){String a=null;Assertions.assertNull(a);}
a是null,执行通过
@Testvoid assertNull(){String a=null;Assertions.assertNotNull(a);}
a是null,执行不通过
3. 用例执行顺序
Junit默认执行顺序是不确定的,官方文档没有明确给出
官方文档地址:https://junit.org/junit5/
但是我们仍然可以使用Junit里提供的方法来手动设置用例的执行顺序
文档中给出的排序方法非常多,诸如方法的排序,标签的排序。。。。
方法排序,通过 @Order 注解来排序
当多个测试用例之间没有解耦,存在前后关联关系,就需要手动指定用例的执行顺序,否则就无法控制用例的执行先后顺序出现错误
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) // 标注当前类使用方法来进行排序
public class RunOrderTest {@Test@Order(1) // 明确标注具体执行顺序void print(){System.out.println("aaa");}@Test@Order(2)void show(){System.out.println("bbb");}@Test@Order(3)void dayin(){System.out.println("ccc");}@Test@Order(4)void shuchu(){System.out.println("ddd");}
}
所以在编写测试用例时候尽量保持测试用例的独立性,如果存在关联关系记得手动指定用例的执行顺序
● @TestMethodOrder(MethodOrderer.OrderAnnotation.class) +
@Order(顺序)
4. 测试套件 Suite
平时执行一次单元测试只能执行一个类,要是想一次性执行多个类中的测试用例方法,就需要用到测试套件
- 指定类,添加到套件中并执行
打包执行成功:
- 选择指定的包,添加到套件中执行
● 使用指定的包来添加套件的前提,所有的文件都需要以Test,tests命名(包含),同时我们的用例都必须要加上 @Test 注解
包里面的类命名要带上 test 才能够被识别到
打包执行成功:
5. 参数化单参数
参数化用到的注解: @Parameterizetest 标注方法类型为参数化
强调参数的来源:
需要添加参数的来源:
@ValueSource(类型={参数1,参数2,…}) (类型:ints,String,floats ,… 使用原生类型)
valuesource中支持的类型:
参数化举列:
strings
public class ParameterizdTest {@ParameterizedTest // 不需要添加 @test 注解,否则方法会多执行一遍@ValueSource(strings = {"昕上","萌萌","旺财","咪咪"})void myTest(String name){System.out.println(name);}
}
ints
@ParameterizedTest@ValueSource(ints = {10,20,30,40})void printAge(int age){System.out.println(age);}
6. 参数化多参数
@CsvSource
用到的核心注解: @CsvSource(value={“心上,20”,“萌萌,10”,“旺财,70”,“咪咪,99”})
默认的分隔符是逗号“,”
@ParameterizedTest@CsvSource(value = {"心上,20","萌萌,10","旺财,70","咪咪,99"})void printNameAndAge(String name,int age){System.out.println("name:"+name+","+"age:"+age);}
如果觉得逗号不好看,也可以自定义分隔符,通过 delimiterString = “xx” 进行设置:
@ParameterizedTest@CsvSource(value = {"心上-20","萌萌-10","旺财-70","咪咪-99"},delimiterString = "-")void printNameAndAge(String name,int age){System.out.println("name:"+name+","+"age:"+age);}
如果遇到赋值的值包含了分隔符的特殊情况,需要使用单引号 ‘’ 来进行转义,否则会报错:
加上单引号:
@ParameterizedTest@CsvSource(value = {"'心,上',20","萌萌,10","旺财,70","咪咪,99"})void printNameAndAge(String name,int age){System.out.println("name:"+name+","+"age:"+age);}
正确赋值,执行通过
@CsvFileSource
如果参数非常的多,在代码中编写不太好看,就可以借助文件注入的方法来添加;
@CsvFileSource(指定文件路径)
@ParameterizedTest@CsvFileSource(resources = "/my.csv")void csvFileSource(String name,int age){System.out.println("name:"+name+","+"age:"+age);}
指定文件路径为当前项目下resources文件夹中的.csv文件:
读取成功,成功赋值:
也可以读取本地目录下的任意csv文件:
@ParameterizedTest@CsvFileSource(files = "D:\\code\\file.csv")void csvFileSource2(String name,int age){System.out.println("name:"+name+","+"age:"+age);}
读取成功:
同时也可以赋null值,也就是对应的位置不填写值即可:
@ParameterizedTest@CsvSource(value = {",20","萌萌,10","旺财,70","咪咪,99"})void printNameAndAge(String name,int age){System.out.println("name:"+name+","+"age:"+age);}
数字类型的参数必须有值,否则导致用例执行失败
7. 动态参数
动态参数单参数
核心注解:@MethodSource(“”)
参数为数据来源的方法名
// 动态参数@ParameterizedTest // 参数化注解@MethodSource("getName") // 提供参数数据的方法,双引号内填写具体方法名void dongtaiParamet(String name){System.out.println(name);}// 提供数据的方法,返回值可以是stream流static Stream<String> getName(){return Stream.of("心上","萌萌","旺财");}
需要注意提供参数数据的方法返回值可以是 stream流,stream流里面设置填写返回值:
● 同时需要设置返回数据的方法是静态方法,static
获取成功:
同样,也可以不进行具体获取参数值方法名称设置,只需要获取参数值的方法名称和测试方法名称保持一致即可识别:
获取成功:
动态参数多参数
返回多参数使用 Arguments.arguments(参数1,参数2) …
@ParameterizedTest@MethodSourcevoid dongtaiParamsTest(String name,int age){System.out.println("name:"+name+","+"age:"+age);}// 返回多参数使用 Arguments.arguments(参数1,参数2) ...static Stream<Arguments> dongtaiParamsTest() {return Stream.of(Arguments.arguments("心上",10),Arguments.arguments("萌萌",20));}
参数获取成功
- Junit5 over ~
相关文章:
【软件测试开发】Junit5单元测试框架
目录1. 注解Test 注解BeforeEach BeforeAllAfterEach AfterAll2. 断言 assertassertequalsassertTrue assertFalseassertNull assertNotNull3. 用例执行顺序方法排序,通过 Order 注解来排序4. 测试套件 Suite5. 参数化单参数stringsints6. 参数化多参数CsvSourceCsv…...
【C语言技能树】程序环境和预处理
Halo,这里是Ppeua。平时主要更新C语言,C,数据结构算法......感兴趣就关注我吧!你定不会失望。 🌈个人主页:主页链接 🌈算法专栏:专栏链接 我会一直往里填充内容哒! &…...
数据库的三大范式
1.为什么需要数据库设计 设计数据表的时候,要考虑很多的问题: 用户需要哪些数据,我们在数据表中要保存哪一些数据怎么保证数据表中的数据的正确性如何降低数据表的冗余度开发人员怎么才能更方便的使用数据库 如果数据库设计得不合理的话,可…...
【MT7628】开发环境搭建-Fedora12安装之后无法上网问题解决
1.按照如下图所示,打开Network Connections 2.点击Network Connections,弹出如下界面...
[Android Studio]Android 数据存储-文件存储学习笔记-结合保存QQ账户与密码存储到指定文件中的演练
🟧🟨🟩🟦🟪 Android Debug🟧🟨🟩🟦🟪 Topic 发布安卓学习过程中遇到问题解决过程,希望我的解决方案可以对小伙伴们有帮助。 📋笔记目…...
【openGauss实战9】深度分析分区表
📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…...
XSS跨站脚本攻击剖析与防御:初识XSS
目录 跨站脚本介绍 1. 什么是XSS跨站脚本 2. XSS跨站脚本实例 3. XSS漏洞的危害 XSS的分类 1. 反射型XSS 2. 持久性XSS XSS构造 1. 利用< >标记注射Html /Javascript 2. 利用HTML标签属性值执行XSS 3. 空格回车Tab 4. 对标签属性值转码 5. 产生自己的事件…...
Python 高级编程之网络编程 Socket(六)
文章目录一、概述二、Python socket 模块1)Socket 类型1、创建 TCP Socket2、创建 UDP Socket2)Socket 函数1、服务端socket函数2、客户端socket函数3、公共socket函数三、单工,半双工以及全双工通信方式的区别四、单工,半双工以及…...
centos学习记录
遇到的问题及其解决办法 centos7安装图形化界面 yum groupinstall ‘X Window System’ yum groupinstall -y ‘GNOME Desktop’ 安装完成后输入init 5进入图形化界面 centos7安装vmware-tools 第一步卸载open-vm-tools 输入命令 yum remove open-vm-tools 输入命令 reboot 在…...
为什么说网络安全是风口行业?
前言 “没有网络安全就没有国家安全”。当前,网络安全已被提升到国家战略的高度,成为影响国家安全、社会稳定至关重要的因素之一。 网络安全行业特点 1、就业薪资非常高,涨薪快 2021年猎聘网发布网络安全行业就业薪资行业最高人均33.77万&…...
12-PHP使用过的函数 111-120
111、rowCount if ($stmt->execute($data)) {//true//读:select//写:insert,update,delete,成功后会返回表中受影响的记录数量//!rowCount() 返回受影响的记录数量if ($stmt->rowCount() > 0) {echo 新增成功,id . $db->lastInsertId() . <hr>;} else {//…...
【JavaWeb项目】简单搭建一个前端的博客系统
博客系统项目 本项目主要分成四个页面: 博客列表页博客详情页登录页面博客编辑页 该系统公共的CSS样式 common.css /* 放置一些各个页面都会用到的公共样式 */* {margin: 0;padding: 0;box-sizing: 0; }/* 给整个页面加上背景 */ html, body{height: 100%; }body {backgrou…...
iPerf3 -M参数详解,场景分析
本文目录iPerf3 -M参数说明几个典型测试场景中应该如何设定合适的-M参数值理想局域网模型(无丢包,无抖动)高丢包,无抖动模型高丢包,高抖动模型(网络质量比较差,IP转发路径变化频繁)总…...
java的基本语法以及注意事项
Java 基础语法一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它…...
matlab搭建IAE,ISE,ITAE性能指标
目录前言准备IAEISEITAE前言 最近在使用matlab搭建控制系统性能评价指标模型,记录一下 准备 MATLAB R2020 IAE IAE函数表达式如下所示: IAE函数模型如下所示: ISE ISE函数表达式如下所示: ISE函数模型如下所示ÿ…...
docker安装mysql
在安装Mysql之前,我们可以先查看一下我们的镜像,输入命令: docker images 能发现,镜像里面只有一个Nginx,并没有Mysql 然后我们可以像上一篇安装Nginx一样,安装Mysql镜像。 输入以下命令,安装…...
Leetcode 回溯详解
回溯法 回溯法有“通用解题法”之称,用它可以系统地搜索问题的所有解。回溯法是一个既带有系统性又带有跳跃性的搜索算法。 在包含问题的所有解的解空间树中,按照深度优先搜索(DFS))的策略,从根结点出发深度探索解空间树。当探索…...
AI_Papers:第一期
2023.02.06—2023.02.12 文摘词云 Top Papers Subjects: cs.CL 1.Multimodal Chain-of-Thought Reasoning in Language Models 标题:语言模型中的多模式思维链推理 作者:Zhuosheng Zhang, Aston Zhang, Mu Li, Hai Zhao, George Karypis, Alex Sm…...
C/C++内存管理
C/C内存管理C/C内存分布C语言中内存管理的方式:malloc/calloc/realloc/freeC内存管理方式内置类型自定义类型operator new 与operator deletenew和delete的实现原理内置类型自定义类型定位new表达式(placement-new)new/delete与malloc/free的区别C/C内存分布 我们先…...
【大数据hive】hive 函数使用详解
一、前言 在任何一种编程语言中,函数可以说是必不可少的,像mysql、oracle中,提供了很多内置函数,或者通过自定义函数的方式进行定制化使用,而hive作为一门数据分析软件,随着版本的不断更新迭代,…...
彻底搞懂分布式系统服务注册与发现原理
目录 引入服务注册与发现组件的原因 单体架构 应用与数据分离...
安卓Camera2用ImageReader获取NV21源码分析
以前如何得到Camera预览流回调 可以通过如下方法,得到一路预览回调流 Camera#setPreviewCallbackWithBuffer(Camera.PreviewCallback),可以通过如下方法,设置回调数据的格式,比如 ImageFormat.NV21 Camera.Parameters#setPreview…...
24. 两两交换链表中的节点
文章目录题目描述迭代法递归法参考文献题目描述 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 示例 1: 输入&a…...
linux006之帮助命令
linux帮助命令简介: linux的命令是非常多的,光靠人是记不住的,在工作中一般都会去网上查,这是有外网的情况下,如果项目中不允许访问外网,那么linux的帮助命令就可以派上用场了, linux帮助命令是…...
【C++初阶】十三、模板进阶(总)|非类型模板参数|模板的特化|模板分离编译|模板总结(优缺点)
目录 一、非类型模板参数 二、模板的特化 2.1 模板特化概念 2.2 函数模板特化 2.3 类模板特化 2.3.1 全特化 2.3.2 偏特化 三、模板分离编译 四、模板总结(优缺点) 前言:之前模板初阶并没有把 C模板讲完,因为当时没有接触…...
Linux之文本搜索命令
文本搜索命令学习目标能够知道文本搜索使用的命令1. grep命令的使用命令说明grep文本搜索grep命令效果图:2. grep命令选项的使用命令选项说明-i忽略大小写-n显示匹配行号-v显示不包含匹配文本的所有行-i命令选项效果图:-n命令选项效果图:-v命令选项效果图:3. grep命令结合正则表…...
微信小程序Springboot 校园拼车自助服务系统java
系统管理员: 管理员账户管理:在线对管理员的账户信息进行管理,包括对管理员信息的增加修改以及密码的修改等。 站内新闻管理:在后台对站内新闻信息进行发布,并能够对站内新闻信息进行删除修改等。 论坛版块管理&#x…...
【Unity3D 常用插件】Haste插件
一,Haste介绍 Haste插件是一款针对 Unity 3D 的 Everthing软件,可以实现基于名称快速定位对象的功能。Unity 3D 编辑器也自带了搜索功能,但是在 project视图 和 Hierarchy视图 中的对象需要分别查找,不支持模糊匹配。Haste插件就…...
【c++面试问答】全局变量和局部变量的区别
问题 C中的全局变量和局部变量有什么区别? 注:内容全部参考自文末的参考资料 全局变量和局部变量的区别 可以从以下4个角度来区分: 区别全局变量局部变量作用域全局作用域局部作用域内存分配全局变量在静态数据区静态局部变量在静态数据区…...
Java List集合
6 List集合 List系列集合:添加的元素是有序,可重复,有索引 ArrayList: 添加的元素是有序,可重复,有索引LinkedList: 添加的元素是有序,可重复,有索引Vector :是线程安全的ÿ…...
赣榆县建设局网站/顺德搜索seo网络推广
前言 alpine 提供了非常好用的apk软件包管理工具,通过apk –help命令查看完整的包管理命令。更新索引 update:从远程镜像源中更新本地镜像源索引,update命令会从各个镜像源列表下载APKINDEX.tar.gz并存储到本地缓存,一般在/var/ca…...
网站策划建设方法/seo与sem的区别
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼顺便大佬帮看下代码,是不是代码写的太笨拙了,跟语言没关系import java.util.Scanner;import java.util.Queue;import java.util.LinkedList;public class Main{private static int[][][] maze;private stati…...
qian p.wordpress/百度网站排名seo
1.图片下方3像素:在div中插如图片时,图片会将div下方撑大3px; 解决方案:(a)将<div>和<img>写在一行上(IE6、ie7); (b)将<img>转为块状元素…...
白城学做网站/深圳网络优化推广公司
C语言与OO思想介绍 C的特点与OO思想 C语言有一个优点,即它的速度可以很快。写出来的程序可以很精练、简单、小巧,不用为了解决某个问题环绕太平洋一大圈。 但如果将C和C相比较,C就经常会为了解决某个问题绕一个大圈,所以代码量相对…...
做pc端网站平台/百度seo优化是做什么的
成熟又有钱的是父亲,成熟又没钱的是舅舅,不成熟有没钱的是儿子,看来自己只能做个儿子了。...
做移动类网站的书推荐/免费自学电商教程
一、题目 演示示例: 二、测试代码 class Solution {public boolean hasGroupsSizeX(int[] deck) {boolean flagfalse;HashMap<Integer,Integer> mapnew HashMap<>();if(deck.length<2)//数组长度小于2直接返回false{return false;}else{for(int i…...