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

单元测试JUnit

  前言👀~

上一章我们介绍了自动化测试工具Selenium,今天讲解单元测试工具JUnit

JUnit

JUnit的使用

JUnit注解

BeforeAll和AfterAll注解

BeforeEach和AfterEach注解

参数化

方法获取参数(动态参数)

断言

用例执行顺序

测试套件


如果各位对文章的内容感兴趣的话,请点点小赞,关注一手不迷路,讲解的内容我会搭配我的理解用我自己的话去解释如果有什么问题的话,欢迎各位评论纠正 🤞🤞🤞

12b46cd836b7495695ce3560ea45749c.jpeg

个人主页:N_0050-CSDN博客

相关专栏:java SE_N_0050的博客-CSDN博客  java数据结构_N_0050的博客-CSDN博客  java EE_N_0050的博客-CSDN博客


JUnit

JUnit 是针对 Java 语言的单元测试框架,前面讲的selenium3,我们通过这个工具写出来的一个个自动化测试用例会发现有很多冗余的内容代码看起来不雅观且不好管理,所以就引出了JUnit相当于我们拿着一个技术来对已经编写好的测试用例进行管理

通过selenium自动化测试工具以及junit单元测试框架结合,针对项目来实现自动化测试,有哪些亮点?

1)使用注解:避免生成过多对象,造成了资源和时间的浪费

2)通过static修饰静态变量,全局只创建一次驱动对象,避免重复创建驱动对象造成时间的浪费

3)使用参数化:保持用例的简洁,提高了代码的可读性

4)使用测试套件:一次执行所有我们想要运行的自动化用例

5)使用等待(隐式等待+强制等待):提高自动化指定的稳定性—降低自动化出现误报的概率

6) 使用屏幕截图:方便问题的追溯和问题的解决

JUnit的使用

首先添加依赖,去中央存储库中搜索

找到对应的依赖,我这边选择的是5.8.2,代码如下

<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.8.2</version><scope>test</scope>
</dependency>

JUnit注解

下面对JUnit中的注解进行演示,默认使用public修饰

首先导入注解的依赖,代码如下

        <dependency><!--注解用到的API--><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.8.2</version><scope>compile</scope></dependency>

@Test:表示当前的这个方法是一个测试用例

public class JUnitTest {@Test//表示当前的这个方法是一个测试用例void test1() {System.out.println("我是Test注解");}
}

@Disabled:表示忽略当前这个测试用例,直接跳过测试。方便修改这个测试用例

public class JUnitTest {@Test//表示当前的这个方法是一个测试用例void test1() {System.out.println("我是Test注解");}@Disabled//表示忽略当前这个测试用例,直接跳过测试void test2() {System.out.println("我是Disabled注解");}
}

输出结果,只输出了上面test1方法的内容


BeforeAll和AfterAll注解

下面两者注意使用static修饰!

@BeforeAll:表示所有测试用例在跑之前,先去执行BeforeAll注解里的代码。所以做UI自动化通常情况把创建驱动打开网页放在BeforeAll里

public class JUnitTest {@Test//表示当前的这个方法是一个测试用例void test1() {System.out.println("我是Test注解");}@Testvoid test2() {System.out.println("我是test2注解");}@BeforeAll//所有测试用例执行之前 先执行BeforeAll里的代码static void test3() {System.out.println("我是BeforeAll注解");}
}

输出结果

@AfterAll:表示所有测试用例跑完之后,再去跑AfterAll注解里的代码。关闭浏览器放在BeforeAll

public class JUnitTest {@Test//表示当前的这个方法是一个测试用例void test1() {System.out.println("我是Test注解");}@Testvoid test2() {System.out.println("我是test2注解");}@BeforeAll//所有测试用例执行之前 先执行BeforeAll里的代码static void test3() {System.out.println("我是BeforeAll注解");}@AfterAll//所有测试用例执行之后 再去执行AfterAll里的代码static void test4() {System.out.println("我是AfterAll注解");}
}

输出结果

BeforeEach和AfterEach注解

@BeforeEach:表示每一个测试用例执行之前BeforeEach里面的代码都要执行一遍

public class JUnitTest {@Test//表示当前的这个方法是一个测试用例void test1() {System.out.println("我是Test注解");}@Testvoid test2() {System.out.println("我是test2注解");}@BeforeEach//表示每一个方法执行前都会执行一遍BeforeEach里的内容void test3() {System.out.println("我是BeforeEach注解");}
}

输出结果

@AfterEach:表示每一个测试用例执行之后AfterEach里面的代码都要执行一遍

public class JUnitTest {@Test//表示当前的这个方法是一个测试用例void test1() {System.out.println("我是Test注解");}@Testvoid test2() {System.out.println("我是test2注解");}@AfterEach//表示每一个方法执行后都会执行一遍BeforeEach里的内容void test4() {System.out.println("我是AfterEach注解");}
}

输出结果


参数化

使用@ParameterizedTest标注方法类型为参数化,然后搭配下面讲解的注解使用

使用@ParameterizedTest注解前也需要导入对应的依赖,代码如下

        <dependency><!--参数化用到的API--><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-params</artifactId><version>5.8.2</version></dependency>

注意使用了这个注解就不要再添加@Test注解,加了的话执行的时候会抛异常!

单参数: @ValueSource(类型={参数1,参数2等}})

public class JUnitTest {@Test//表示当前的这个方法是一个测试用例void test1() {System.out.println("我是Test注解");}@ParameterizedTest@ValueSource(strings = "我是ValueSource注解")void test2(String s) {System.out.println(s);}
}

输出结果

使用CSV注解获取参数:注意和单参数一样只能传同种类型的参数!

@CsvFileSource:如果参数非常的多我们可以通过这个注解借助文件注入的方式来添加,路径可以指定为当前项目下resource文件中的csv文件(内容使用逗号分割),也可以指定为本地任意文件夹下的csv文件

public class JUnitTest {@Test//表示当前的这个方法是一个测试用例void test1() {System.out.println("我是Test注解");}@ParameterizedTest@CsvFileSource(resources = "test.csv")void test2(String s) {System.out.println(s);}
}

输出结果


多参数:上面的只能传同种类型的参数,使用多参数注解就可以传递多个不同的参数

@CsvSource:可以传递多个不同类型的参数,参数之间默认的分隔符是逗号,还能手动指定分隔符

public class JUnitTest {@Test//表示当前的这个方法是一个测试用例void test1() {System.out.println("我是Test注解");}@ParameterizedTest@CsvSource(value = {"1,老六", "2,老八"})void test2(int n, String name) {System.out.println(n + " " + name);}
}

输出结果

还能传入空的字符串!

public class JUnitTest {@Test//表示当前的这个方法是一个测试用例void test1() {System.out.println("我是Test注解");}@ParameterizedTest@CsvSource(value = {"1,老六", "2,老八","3,''"})void test2(int n, String name) {System.out.println(n + " " + name);}
}

输出结果

方法获取参数(动态参数)

使用@MethodSource注解,如果没有指定数据来源,则默认找跟用例同名的静态方法

单参数:可以就传同种类型的参数,将方法返回类型改为对应的类型即可

public class JUnitTest {@Test//表示当前的这个方法是一个测试用例void test1() {System.out.println("我是Test注解");}public static Stream<String> method() {return Stream.of("坤坤", "坤舞", "坤");}@ParameterizedTest@MethodSource("method")void test2(String name) {System.out.println(name);}
}

输出结果

多参数:可以传不同种类型的参数

public class JUnitTest {@Test//表示当前的这个方法是一个测试用例void test1() {System.out.println("我是Test注解");}public static Stream<Arguments> method() {return Stream.of(Arguments.arguments(1, "签哥"), Arguments.arguments(2, "坤哥"));}@ParameterizedTest@MethodSource("method")void test2(int n, String name) {System.out.println(n + " " + name);}
}

输出结果

断言

写自动化测试,测试的结果就两种要么成功要么失败,我们可以使用断言进行判断,省去那种ifelse语句

使用Assertions类调用assertEquals方法:判断预期值和实际值相等

public class JUnitTest {@ParameterizedTest@ValueSource(ints = 1)void test2(int n) {Assertions.assertEquals(2, n);}
}

输出结果,如果不相等就会报错

使用Assertions类调用assertNotEquals方法:判断预期值和实际值不相等

public class JUnitTest {@ParameterizedTest@ValueSource(ints = 1)void test2(int n) {Assertions.assertNotEquals(1, n);}
}

输出结果,如果相等就会报错

使用Assertions类调用assertNull方法:判断为空

public class JUnitTest {@Testvoid test2() {String s = "s";Assertions.assertNull(s);}
}

输出结果,如果不空就会报错

使用Assertions类调用assertNotNull方法:判断不为空

public class JUnitTest {@Testvoid test2() {String s = null;Assertions.assertNotNull(s);}
}

输出结果,如果为空就会报错


用例执行顺序

junit的默认执行顺序是不确定的 采用的是自己执行顺序对应的算法,但用例执行顺序是固定的。什么意思呢?你可以试试第一次运行的结果和后面运行的结果对比一下,下面进行演示

下面这段代码按道理应该先输出test1方法的内容,再输出A方法的内容,再输出test2方法的内容

public class JUnitTest {@Testvoid test1() {System.out.println("这是junit测试1");}@Testvoid A() {System.out.println("这是junit测试A");}@Testvoid test2() {System.out.println("这是junit测试2");}
}

输出结果

再运行一次输出的结果,还是一样

指定方法执行顺序:使用@TestMethodOrder(MethodOrderer.OrderAnnotation.class)注解搭配@Order注解

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class JUnitTest {@Order(1)@Testvoid test1() {System.out.println("这是junit测试1");}@Order(2)@Testvoid A() {System.out.println("这是junit测试A");}@Order(3)@Testvoid test2() {System.out.println("这是junit测试2");}
}

输出结果

方法随机执行顺序:使用@TestMethodOrder(MethodOrderer.Random.class)注解

@TestMethodOrder(MethodOrderer.Random.class)
public class JUnitTest {@Testvoid test1() {System.out.println("这是junit测试1");}@Testvoid A() {System.out.println("这是junit测试A");}@Testvoid test2() {System.out.println("这是junit测试2");}
}

输出结果

为什么需要用到junit里的排序方法呢?

如果用例之间存在关联关系的话就需要手动指定用例的执行顺序


测试套件

首先也要导入对应的依赖,代码如下

        <dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-suite</artifactId><version>1.8.2</version><scope>test</scope></dependency>

使用@Suite注解:表示当前类是个测试套件,搭配下面的注解使用

 使用@SelectClasses可以通过指定类的方式 添加到套件中并执行里面的所有测试用例

@Suite
@SelectClasses({Test01.class, Test02.class})
public class JUnitTest {}

输出结果

使用@SelectPackages可以通过指定包的方式 添加到套件中并执行测试用例

@Suite
@SelectPackages(value = {"Test1", "Test2"})
public class JUnitTest {}

输出结果

以上便是本章内容关于JUnit一些概念和使用,在自动化测试中还是尤为重要的一部分,我们下一章再见💕

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • eslint配置忽略目录和文件
  • 国内开源软件镜像站点参考
  • 【STL】String的底层构造
  • Executable Code Actions Elicit Better LLM Agents
  • 国球荣耀背后的笑与泪——陈梦夺冠现象有感
  • 银河麒麟V10 审计工具 auditd 内存泄漏问题
  • Stable Diffusion绘画 | 图生图-基础使用介绍—提示词反推
  • 监控员工电脑的软件有哪些?四款监控员工电脑的软件分享!
  • fatal error: concurrent map iteration and map write - 关于Go中并发访问Map的操作
  • android compose设置圆角不起作用
  • Visual Studio 和 VSCode 哪个好?
  • mac下载exe后不自动打开虚拟机
  • 全自动真空拌馅机 肠类肉丸类馅料搅拌机:
  • 系统 hap
  • 2021年庐阳区青少年信息学科普日真题- 跳跃(jump)
  • 【跃迁之路】【444天】程序员高效学习方法论探索系列(实验阶段201-2018.04.25)...
  • 2019.2.20 c++ 知识梳理
  • 4个实用的微服务测试策略
  • Druid 在有赞的实践
  • input的行数自动增减
  • Java|序列化异常StreamCorruptedException的解决方法
  • leetcode98. Validate Binary Search Tree
  • maven工程打包jar以及java jar命令的classpath使用
  • nodejs调试方法
  • Odoo domain写法及运用
  • Promise面试题2实现异步串行执行
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • Redis的resp协议
  • Redis字符串类型内部编码剖析
  • session共享问题解决方案
  • 前端知识点整理(待续)
  • 深度学习在携程攻略社区的应用
  • 网页视频流m3u8/ts视频下载
  • 系统认识JavaScript正则表达式
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • ​​​​​​​STM32通过SPI硬件读写W25Q64
  • # AI产品经理的自我修养:既懂用户,更懂技术!
  • #android不同版本废弃api,新api。
  • (2.2w字)前端单元测试之Jest详解篇
  • (C++二叉树05) 合并二叉树 二叉搜索树中的搜索 验证二叉搜索树
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (图)IntelliTrace Tools 跟踪云端程序
  • .net core 6 集成和使用 mongodb
  • .NET 事件模型教程(二)
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)
  • .NET开源、简单、实用的数据库文档生成工具
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • ;号自动换行
  • [ Algorithm ] N次方算法 N Square 动态规划解决
  • [24年新算法]NRBO-XGBoost回归+交叉验证基于牛顿拉夫逊优化算法-XGBoost多变量回归预测