当前位置: 首页 > news >正文

【测试开发篇9】Junit框架

目录

一、认识Junit框架

Junit和Selenium的关系是什么

导入Junit框架+common-io包

二、Junit框架的使用

2.1Junit有哪些常用注解

2.1.1@Test注解

2.1.2BeforeEach

2.1.3@BeforeAll

2.1.4@AfterAll

2.1.5@AfterEach

2.2Junit的断言

Assertions.assertEquals(期待值,真实值);

2.2.1Assertions.assertNotEquals("百度一下",text)

2.2.2Assertions.assertTrue(text.equals("百度一下"))

2.2.3Assertions.assertNull(a);

三、用例的执行顺序

①针对方法的排序

为什么需要用到juit的排序功能

四、测试套件(Suit)

@Suite

@SelectClasses({待测试的类.class})

@SelectPackages("包名")

五、参数化

5.1@ParameterizedTest、@ValueSource(strings = {})

5.2@CsvSource(value={"第一组数据","第二组数据"})

 如果参数当中包含逗号:",",就需要使用单引号转义字符串

5.3读取文件参数:@CsvFileSource(resources="/文件名称")

 5.3.1读取其他磁盘文件的操作:指定文件为files=...

5.4动态参数(单参数版本)

5.5动态参数(多参数版本)

六、对于重要测试场景的截图

第一步:定位到需要的页面

第二步:调用getSrceenshotAs方法,传入的擦参数是OutputTpye.FILE;

第三步:新建一个File类,指定路径;

第四步:调用copyFile方法,把生成的文件放到指定的目录当中


一、认识Junit框架

Junit是一个开源的Java语言的单元测试框架

回顾一下,单元测试就是在编码阶段,一般情况下,由开发进行的测试。

Junit和Selenium的关系是什么

      Junit是单元测试框架,而selenium是web自动化测试框架。如果把selenium比作灯泡,那么junit就是电灯。因此:一般情况下,junit负责运行selenium脚本编写的代码。


导入Junit框架+common-io包

<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>4.8.1</version></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>${junit.version}</version><scope>test</scope></dependency><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-suite</artifactId><version>1.8.2</version><scope>test</scope></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-params</artifactId><version>5.8.2</version><scope>test</scope></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-engine</artifactId><version>${junit.version}</version><scope>test</scope></dependency>

二、Junit框架的使用

2.1Junit有哪些常用注解

2.1.1@Test注解

       这一个注解作用于方法上面,表示这个方法是一个测试用例。当@Test注解作用在一个方法上面的时候,表示这一个方法是可以直接运行的,无需通过main方法来调用


2.1.2BeforeEach

在执行每一个被@Test修饰的方法之前,都会执行一次@BeforeEach注释的方法。

@BeforeEachvoid aaa(){System.out.println("pre");}@Testvoid bbb(){System.out.println("bbb");}@Testvoid ccc(){System.out.println("ccc");}

 每执行一个@Test之前,就需要执行一次@BeforeEach注释的方法

运行类上面的运行按钮:


2.1.3@BeforeAll

       首先,被@BeforeAll注释的方法一定是静态的。

       其次,不同于@BeforeEach的是,@BeforeAll注释的方法一定是静态的,并且只会在加载外部类的时候执行一次,并不会在每一个方法执行之前再次执行了。

public class Test1 {@BeforeAllstatic void aaa(){System.out.println("pre");}@Testvoid bbb(){System.out.println("bbb");}@Testvoid ccc(){System.out.println("ccc");}
}


2.1.4@AfterAll

被这个注解修饰的方法也必须是静态的,在每一个@Test之后进行修饰。

public class Test1 {@BeforeAllstatic void aaa(){System.out.println("pre");}@Testvoid bbb(){System.out.println("bbb");}@Testvoid ccc(){System.out.println("ccc");}@AfterAllstatic void afterAll(){System.out.println("end...");}
}

运行结果:


2.1.5@AfterEach

同理,在每一个@Test注释的方法执行结束的末尾,都会执行一次@AfterEach注释的方法。

public class Test1 {@BeforeEachvoid aaa(){System.out.println("pre");}@Testvoid bbb(){System.out.println("bbb");}@Testvoid ccc(){System.out.println("ccc");}@AfterEachvoid afterAll(){System.out.println("end...");}
}

运行结果:


2.2Junit的断言

写自动化测试,结果要么是成功的,要么是失败的,不存在成功一半的情况。

那么就需要使用到断言:assert,断言预期结果真实结果是否一致。

Assertions.assertEquals(期待值,真实值);

期待值真实值一致的时候,这个断言才不会抛出异常

期待值真实值不一致的时候,就会抛出异常;


代码实现:

public class Test2 {FirefoxDriver driver;@BeforeEachpublic void get(){driver=new FirefoxDriver();//捕捉到这一个页面driver.get("https://www.baidu.com");}@Testpublic void testOne(){//尝试获取"百度一下"的文本框String text=driver.findElement(By.cssSelector("#su")).getAttribute("value");//使用AssertEquals来进行断言Assertions.assertEquals("百度一下",text);}@AfterEachpublic void after(){driver.quit();}
}

如果运行的结果一致,那么就提示测试用例通过:


2.2.1Assertions.assertNotEquals("百度一下",text)

与Assertions.assertEquals(期待值,真实值)相反。

只有不一致的时候,测试用例才会通过。


2.2.2Assertions.assertTrue(text.equals("百度一下"))

传入的参数应该是一个返回值为boolean类型的表达式

@Test
public void assertTrueTest(){String text=driver.findElement(By.cssSelector("#su")).getAttribute("value");//如果返回true,那么测试用例通过,否则测试用例不通过Assertions.assertTrue(text.equals("百度一下"));}

同理,还有AssertFalse 


2.2.3Assertions.assertNull(a);

 @Testpublic void assertNull(){String a=null;Assertions.assertNull(a);}

如果一个引用为null,那么默认测试用例通过。

同理,还有Assertions.assertNotNull(),那么一个引用不为null的时候,测试用例才通过。


三、用例的执行顺序

①针对方法的排序

第一步:在这个类上面添加注解:@TestMethodOrder(MethodOrderer.OrderAnnotation.class)


第二步:

使用@Order(执行顺序)作用在方法上面,表示是第几个执行;


@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class Test2 {FirefoxDriver driver;@BeforeEach@Order(1)public void get(){driver=new FirefoxDriver();//捕捉到这一个页面driver.get("https://www.baidu.com");}@Test@Order(2)public void testOne(){//尝试获取"百度一下"的文本框String text=driver.findElement(By.cssSelector("#su")).getAttribute("value");Assertions.assertNotEquals("百度一下",text);}@Test@Order(3)public void assertTrueTest(){String text=driver.findElement(By.cssSelector("#su")).getAttribute("value");//如果返回true,那么测试用例通过,否则测试用例不通过Assertions.assertTrue(text.equals("百度一下"));}@AfterEachpublic void after(){driver.quit();}
}

为什么需要用到juit的排序功能

       如果用例之间存在关联关系(存在耦合)(但是不是绝对有关联关系),那么就需要手动指定用例的执行顺序。因为各个测试用例的执行顺序是无序的。

       这样就可以避免出现各个测试用例之间执行顺序不正确的情况。


四、测试套件(Suit)

测试套件,用于把所有的测试用例都执行起来。

@Suite

这一个注解作用于类上面,用于执行所有的测试用例


@SelectClasses({待测试的类.class})

这个注解和上面的注解需要配合使用,这样才可以一起执行待测试类的测试用例。

当然也可以传递多个.class对象。


@Suite
@SelectClasses({Test1.class,Test2.class})
public class SuitTest {}

运行结果:


@SelectPackages("包名")

扫描这一个包下面包含了@Test注解的方法的类

@Suite
@SelectPackages("TestFile")
public class SuitTest {}

但是扫描的包不可以和当前的类在同一个包下面;

需要注意的是,这种情况下面,被扫描的类一定是xxxTest这样命名的,否则是扫描不到的。


五、参数化

对于一个测试用例,可能会测试传入的参数是多种的情况;

例如对于一个文本框进行测试,可以测试多种输入的情况

如下图:如果为每一个输入的name都定义一个方法,那么就显得非常冗余,于是就引入了参数化。


5.1@ParameterizedTest、@ValueSource(strings = {})

第一个注解@Parameterized作用在方法上面,用来表示这个方法支持传入多个参数;

第二个注解@ValueSource用于指定传入参数的类型;例如:strings={}就表示传入的是一个string类型的数组;

ints={2,3,4,5}表示传入的参数是一个int类型的数组;

但是,同一个@ValueSource注解当中只支持一种数据类型

运行结果:


5.2@CsvSource(value={"第一组数据","第二组数据"})

其中,每一组数据当中对应方法传入的参数的值。采用","来分割。 

@ParameterizedTest@CsvSource(value = {"小明,20","小红,30","小李,40"})public void printStringAndInteger(String name,int age){System.out.println("name:"+name+";age="+age);}


当然,一组数据当中的分隔符也不一定采用系统默认的","分割,也可以采用自定义的分隔符。

@ParameterizedTest@CsvSource(value = {"小明-20","小红-20","小李-40"},delimiter = '-')public void printStringAndAge(String name,int age){System.out.println("name:"+name+";age="+age);}

用户自定义的分隔符: 


 如果参数当中包含逗号:",",就需要使用单引号转义字符串


5.3读取文件参数:@CsvFileSource(resources="/文件名称")

第一步:在resources目录下面新建一个文件,并且指定名称;

第二步:在文件当中以逗号的方式分割每一组参数;

然后运行程序:


 5.3.1读取其他磁盘文件的操作:指定文件为files=...

    @ParameterizedTest@CsvFileSource(files = "E:\\OJSystem\\src\\main\\resources\\my.csv")public void printStringAndAge3(String name,int age){System.out.println("name:"+name+";age="+age);}

5.4动态参数(单参数版本)

第一步:定义提供数据的方法,必须声明为静态;返回值为一个Stream对象;方法内部调用Stream.of(参数列表);

第二步:定义dyNatickTest(String x)方法获取参数;并用@MethodSource()指定

第三步:输出参数。

@ParameterizedTest@MethodSource("methodDemo")void dyNatickTest(String x){System.out.println(x);}static Stream<String> methodDemo(){return Stream.of("张三","李四","王五");}

如果@MethodSource当中不指定参数的名称,那么就会调用跟测试用例同名的静态方法


5.5动态参数(多参数版本)

第一步:新建一个测试方法,并且指定多个参数。使用@ParameterizedTest和@MethodSource注解同时作用

第二步:新建一个和测试用例同名的静态方法;

第三步:在静态方法当中调用Stream.of()方法,并且传入的参数为多个Arguments.arguments(第一步创建方法的参数列表)


 代码实现:

@ParameterizedTest@MethodSourcevoid paramsTest(String name,int age){System.out.println("name:"+name+";age :"+age);}/*** 多参数的版本* Stream对象@return*/static Stream<Arguments> paramsTest(){return Stream.of(Arguments.arguments("lucy",29),Arguments.arguments("lili",30),Arguments.arguments("lisi",40));}

六、对于重要测试场景的截图

第一步:定位到需要的页面

第二步:调用getSrceenshotAs方法,传入的擦参数是OutputTpye.FILE;

第三步:新建一个File类,指定路径;

第四步:调用copyFile方法,把生成的文件放到指定的目录当中

@Testpublic void screenShortTest() throws IOException, InterruptedException {//百度搜索关键字driver.findElement(By.cssSelector("#kw")).sendKeys("selenium");driver.findElement(By.cssSelector("#su")).click();//屏幕截图,把截图的文件存放到指定的位置//以文件的形式存储File srcFile=driver.getScreenshotAs(OutputType.FILE);//把截图的文件存放到指定的目录下面File destFile=new File("E:/OJSystem/src/test/Files/img.png");Thread.sleep(1000);FileUtils.copyFile(srcFile,destFile);}

相关文章:

【测试开发篇9】Junit框架

目录 一、认识Junit框架 Junit和Selenium的关系是什么 导入Junit框架common-io包 二、Junit框架的使用 2.1Junit有哪些常用注解 2.1.1Test注解 2.1.2BeforeEach 2.1.3BeforeAll 2.1.4AfterAll 2.1.5AfterEach 2.2Junit的断言 Assertions.assertEquals(期待值&#…...

《Spring MVC》 第五章 实现RESTful

前言 教授大家如何实现RESTful 1、什么是RESTful resource Representational State Transfer 的缩写&#xff0c;就是“表现层资源表述状态转移” 1.1、Resource&#xff08;资源&#xff09; web应用的文件&#xff0c;uri定位 1.2、Representation&#xff08;资源的描…...

Last Week in Milvus

What’s New Core Updates #23353 在 2.3 版本中&#xff0c; milvus 和 knowhere 引擎会移除了 Annoy 索引。Annoy 索引在性能和召回率方面均不如 IVF、HNSW 等索引&#xff0c;维护成本比较高所以经过讨论决定在 2.3 中移出 Annoy 索引的支持&#xff0c;有使用的用户要注意…...

Cursor IDE一个GPT4人工智能自动程序编辑器

让我们来了解一下Cursor IDE是什么。Cursor IDE是一个新型的编程工具&#xff0c;可以通过它生成、编辑以及与人工智能进行交互分析代码。官方网站上的三个单词“Build Software. Fast.”&#xff08;快速构建软件&#xff09;以及“Write, edit, and chat about your code wit…...

PPO算法-理论篇

1. Policy Gradient 【李宏毅深度强化学习笔记】1、策略梯度方法&#xff08;Policy Gradient&#xff09; 李宏毅深度强化学习-B站 2. PPO PPO 算法 PPO算法更新过程如下&#xff1a; 初始化policy参数 θ 0 \theta^0 θ0在每一步迭代中&#xff1a; 使用 θ k \theta^k …...

【现货】AP6317 同步3A锂电充电芯片 带短温度保护

AP6317是一款面向5V交流适配器的3A锂 离子电池充电器。它是采用800KHz固定频率的同 步降压型转换器&#xff0c;因此具有高达92%以上的充电效 率&#xff0c;自身发热量极小。 包括完整的充电终止电路、自动再充 电和一个精确度达1%的4.2V预设充电电压&#xff0c;内 部集成了防…...

MyBatis详解(2)

8、自定义映射resultMap 8.1、resultMap处理字段和属性的映射关系 若字段名和实体类中的属性名不一致&#xff0c;则可以通过resultMap设置自定义映射 <!--resultMap&#xff1a;设置自定义映射属性&#xff1a;id&#xff1a;表示自定义映射的唯一标识type&#xff1a;查询…...

2023-04-14 使用纯JS实现一个2048小游戏

文章目录 一.实现思路1.2048的逻辑2.移动操作的过程中会有三种情况 二.代码部分:分为初始化部分和移动部分1.初始化部分1.1.生成第一个方块:1.2.生成第二个方块: 2.移动过程部分: 三.实现代码1.HTML部分2.CSS部分3.JS部分3.1.game对象的属性3.2.game对象的start方法3.3.game对象…...

C++入门(3)

C入门 1.auto关键字&#xff08;C11&#xff09;1.1. 类型别名的思考1.2. auto简介1.3. auto使用情景1.4. auto的使用细则1.5. auto不能推导的场景 1.auto关键字&#xff08;C11&#xff09; 1.1. 类型别名的思考 随着程序越来越复杂&#xff0c;程序中用到的类型也越来越复杂…...

【亲测有效】更新了WIN11之后 右键无 新建WORD,PPT,EXCEL 选项 问题 解决方案

原本正常的正版系统&#xff0c;在昨天4月自动更新安装之后&#xff0c;发现右键找 不到新建文档了&#xff0c;word,ppt,excel都不见了。 看了网上大神的方法 Win11安装了Office右键没有新建Excel选项怎么办&#xff1f; - 知乎 可以解决一部分 官方解决方案&#xff0c;亲…...

2023年4月北京/西安/郑州/深圳CDGA/CDGP数据治理认证考试报名

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…...

Win10桌面我的电脑怎么调出来?最简单方法教学

Win10桌面我的电脑怎么调出来&#xff1f;有用户发现自己的电脑桌面没有我的电脑这个程序图标&#xff0c;每次要访问磁盘的时候&#xff0c;开启都非常的麻烦。那么怎么将这个图标设置到桌面显示呢&#xff1f;接下来我们一起来看看以下的解决方法吧。 方法一&#xff1a; 在开…...

开启单细胞及空间组学行业发展黄金时代!首届国际单细胞及空间组学大会在穗闭幕

2023年4月16日&#xff0c;首届TICSSO国际单细胞及空间组学大会圆满闭幕&#xff0c;本次大会吸引了2000余位来自产、学、研、资、医、政、媒等业界人士齐聚羊城&#xff0c;注册总人数5398人&#xff0c;网络播放总量达548245人次&#xff0c;网络观看覆盖美国、德国、日本、澳…...

YOLOv8 更换主干网络之 GhostNetV2

《GhostNetV2:Enhance Cheap Operation with Long-Range Attention》 轻量级卷积神经网络(CNN)是专门为在移动设备上具有更快推理速度的应用而设计的。卷积操作只能捕捉窗口区域内的局部信息,这防止了性能的进一步提高。将自注意力引入卷积可以很好地捕捉全局信息,但这将大…...

高级服务框架(黑马)

一、修改order-service服务 修改OrderService&#xff0c;让其监听Nacos中的sentinel规则配置。 具体步骤如下&#xff1a; 1.引入依赖 在order-service中引入sentinel监听nacos的依赖&#xff1a; <dependency><groupId>com.alibaba.csp</groupId><…...

Go语言面试题--基础语法(29)

文章目录 1.下面的代码有什么问题&#xff1f;2.下面代码最后一行输出什么&#xff1f;请说明原因3.下面代码有什么问题&#xff1f;4.下面的代码输出什么&#xff1f; 1.下面的代码有什么问题&#xff1f; func main() {data : []int{1,2,3}i : 0ifmt.Println(data[i]) }参考…...

毕业生招聘信息的发布与管理系统(论文+设计)

前 言 当今&#xff0c;人类社会已经进入信息全球化和全球信息化、网络化的高速发展阶段。丰富的网络信息已经成为人们工作、生活、学习中不可缺少的一部分。人们正在逐步适应和习惯于网上贸易、网上购物、网上支付、网上服务和网上娱乐等活动&#xff0c;人类的许多社会活动…...

mysql安全加固配置文档(完结)

4. MySQL 权限安全配置 4.1. 确保只有管理员账号有所有数据库的访问权限 建议理由 除了管理员账号&#xff0c;其他用户没必要有所有数据库的访问权限。过高的权限会导致安全问题。检查方法 SELECT user, host FROM MySQL.user WHERE (Select_priv Y) OR (Insert_priv Y) …...

CAPL函数在实现AES加密算法时遇到的各种问题(c++中符号的含义,AES算法中padding的问题等)

本来打算把AES算法的代码移植到CAPL中的,文章:https://blog.csdn.net/qq_28205153/article/details/55798628?spm=1001.2014.3001.5506里有非常详细的代码。但是一来太麻烦,二来没必要,因为CAPL提供了Security安全相关的函数: 这里面就提供了AES加密算法的接口函数,使用…...

二叉排序树(二叉查找树)基本操作_20230417

二叉排序树&#xff08;二叉查找树&#xff09;基本操作_20230417 前言 二叉排序树首先是一颗二叉树&#xff0c;它不同于常规二叉树的地方在于&#xff0c;如果左子树不为空&#xff0c;那么左子树上所有结点的值都不大于根节点的值&#xff0c;如果右子树不为空&#xff0c…...

实现服务器版本的表白墙

目录 初始前端代码 网页初始效果 一、确定接口 二、编写代码 2.1 创建项目七步走 1、创建Maven项目 2、引入依赖 3、构建目录 4、编写代码 5、打包、部署 ​编辑 7、验证代码 三、具体的代码逻辑 3.1 服务器——两个服务接口 3.2 前端页面的代码 3.2.1 前端存档…...

TensorFlow 2 和 Keras 高级深度学习:6~10

原文&#xff1a;Advanced Deep Learning with TensorFlow 2 and Keras 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 不要担心自己的形象&#x…...

unity,制作一个环状滑动条

介绍 unity&#xff0c;制作一个环状滑动条 方法 1.导入png图片素材2.新建一个滑动条&#xff0c;两者图片都设置为图片3.调节slider的参数4.调节backgroud的参数5.fill area、fill的参数同上。 得到两个叠加的圆环。6.设置fill的背景颜色为红色7.设置fill填充方式&#xff0…...

2023-04-17 算法面试中常见的树和递归问题

二叉树和递归 0 LeetCode297 二叉树的序列化和反序列化 序列化是将一个数据结构或者对象转换为连续的比特位的操作&#xff0c;进而可以将转换后的数据存储在一个文件或者内存中&#xff0c;同时也可以通过网络传输到另一个计算机环境&#xff0c;采取相反方式重构得到原数据…...

3分钟通过日志定位bug,这个技能测试人必须会

♥ 前 言 软件开发中通过日志记录程序的运行情况是一个开发的好习惯&#xff0c;对于错误排查和系统运维都有很大帮助。 Python 标准库自带了强大的 logging 日志模块&#xff0c;在各种 python 模块中得到广泛应用。 一、简单使用 1. 入门小案例 import logging logging.ba…...

【论文总结】V-Shuttle:可扩展和语义感知的 Hypervisor 虚拟设备模糊测试

介绍 这是来自2021 CCS的一篇论文&#xff0c;作者有GaoningPan, Xingwei Lin, Xuhong Zhang, Yongkang Jia, Shouling Ji, Chunming Wu, Xinlei Ying, Jiashui Wang, Yanjun Wu。该论文提出V-shuttle的新框架来执行管控程序的模糊测试&#xff0c;该框架执行可扩展和语义感知…...

一篇文章让你搞懂TypeScript中的typeof()、keyof()是什么意思

TypeScript中的typeof&#xff08;&#xff09;、keyof&#xff08;&#xff09;是什么意思&#xff1f; 知识回调&#xff08;不懂就看这儿&#xff01;&#xff09;场景复现核心干货&#x1f447;&#x1f447;&#x1f447;举例引入字面量类型&#xff08;literal types&…...

【机会约束、鲁棒优化】机会约束和鲁棒优化研究优化【ccDCOPF】研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

4月想跳槽的同学,没有更好的选择,可以去美团

在美团干了半年&#xff0c;说一下自己的感受&#xff0c;美团是一家福利中等&#xff0c;工资待遇中上&#xff0c;高层管理团队强大&#xff0c;加班强度一般&#xff0c;技术不错&#xff0c;办公环境一般&#xff0c;工作氛围中上&#xff0c;部门差距之间工作体验差距巨大…...

从输入url到页面展现(一)从浏览器解析url开始

前端面试有一道很考验人的问题&#xff0c;那就是&#xff1a;请你说一下从用户从输入url到页面展现的过程是怎样的&#xff1f;在接下来的一段时间呢&#xff0c;狗哥会从这一问题出发&#xff0c;开始剖析这个过程&#xff0c;希望可以让更多的小伙伴掌握到这个过程&#xff…...