当前位置: 首页 > 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…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...