本文来自网易云社区

作者:范旭斐

大家在使用testng、junit做自动化测试的过程中,经常会用到testng、junit自带的断言器,有时候对一个字符串、日期、列表进行断言很麻烦,需要借助到jdk或者第三方包的方法进行处理后断言,无形之中增加了代码量,测试用例方法的代码看起来也不够友好,很臃肿。总体来说,junit&testng的断言API还可以,功能不算强大,只能说是满足我们日常测试的需求。这里向大家推荐一款功能强大的流式断言器——AssertJ,所谓的流式断言就是相较于Assert的单个校验点断言,支持一条断言语句对实际值同时断言多个校验点。

POM依赖

		<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
<version>3.9.1</version>
</dependency>

示例

1.字符串断言

		// 字符串断言
assertThat("test").isNotBlank() // 是否为" "字符串
.as("字符串断言描述").isSubstringOf("test1") // 是否为test1的一部分
.isSameAs("test") // 对象内元素是否相等
.isNotEmpty() // 是否为空字符串
.isEqualTo("test") // 是否相等
.isEqualToIgnoringCase("Test") // 是否相等(忽略大小写)
.isExactlyInstanceOf(String.class) // 是否是实例
.isIn(Arrays.asList("test", "hello")) // 是否在列表中
.isIn("test", "hello") // 是否在参数列表中
.isInstanceOfAny(String.class, Integer.class) // 是否是实例中任何一个
.isNotNull() // 是否不为空
.contains("es") // 是否包含es子串
.startsWith("te") // te开始
.endsWith("st") // st结束
.matches(".e.t"); // 是否匹配 .e.t 格式
assertThat("").isNullOrEmpty();

2. 数字断言

		// 数字断言
assertThat(new Integer(100))
.as("数字断言描述").isEqualTo(100) // 是否相等
.isBetween(0, 300) // 是否在0,300之间
.isNotNull() // 是否非空
.isNotZero() // 是否不等于0
.isGreaterThanOrEqualTo(80) // 是否大约等于80
.isLessThan(200) // 是否小于200
.isPositive() // 是否是正数
.isNotNegative() // 是否是非负数
.isIn(Arrays.asList(100, 200)) // 是否在列表中
.isInstanceOf(Integer.class); // 是否是Integer类型

3. 日期断言

		// 日期断言
assertThat(new Date())
.as("日期断言描述")
.isAfter("2018-08-01")
.isAfterYear(2017)
.isBetween("2018-01-01", "2018-08-31")
.isEqualToIgnoringHours(new Date().toLocaleString())
.isExactlyInstanceOf(Date.class)
.isInSameHourAs(new Date())
.isInThePast()
.isToday();

4. 列表断言

		// 列表断言
assertThat(Arrays.asList("world", "hello"))
.as("列表断言描述")
.isNotEmpty() 
.isNotNull()
.isInstanceOf(List.class)
.isSubsetOf("hello", "world")
.contains("hello")
.containsOnlyOnce("world")
.startsWith("world")
.endsWith("hello");

5. 字典断言

		// 字典断言
Map foo = Maps.newHashMap();
foo.put("A", 1);
foo.put("B", 2);
foo.put("C", 3);
assertThat(foo)
.as("字典断言描述")
.isNotNull() // 是否不为空
.isNotEmpty() // 是否size为0
.hasSize(3) // size是否为3
.contains(entry("A", 1)) // 是否包含entry
.containsKeys("A") // 是否包含key
.containsValue(1); // 是否包含value

6. 对象断言

		// 对象断言
User user1 = new User();
user1.setName("Tom");
user1.setAge(12); User user2 = new User();
user2.setName("Tom");
user2.setAge(12); User user3 = user1; assertThat(user1)
.as("对象断言描述")
.isEqualToComparingFieldByField(user2) //user1的每个字段是否与user2相同
.isExactlyInstanceOf(User.class) //user1是否是User类的对象
.isSameAs(user3) //是否是同一个对象
.isNotNull() //是否非空
.hasFieldOrProperty("name") //是否含有name字段
.hasFieldOrPropertyWithValue("age", 12); //是否含有age字段,且值为12

可以看到assertj提供的断言功能非常强大,往往junit&testng的assert需要多行代码来断言,用assertj只需要一步就够了。

TestNG&Junit转换工具

如果想将junit&testng的断言转换为assertj,官方还提供了转换工具:

http://joel-costigliola.github.io/assertj/assertj-core-converting-junit-assertions-to-assertj.html

http://joel-costigliola.github.io/assertj/assertj-core-converting-testng-assertions-to-assertj.html

自定义断言条件与自定义断言

如果觉得这个功能不够用,assertj还可以自定义断言条件:

		Set expectedSet = new HashSet();
expectedSet.add("haha");
expectedSet.add("hehe"); Condition setConainsCondition = new Condition("setConainsCondition") {
@Override
public boolean matches(String value) { return expectedSet.contains(value);
}
}; assertThat("haha").is(setConainsCondition);
assertThat("xxx").isNot(setConainsCondition);

也可以自动义断言,这里是写的一个对string类型是否包含char字符的一个自定义断言:

package com.netease.kaola.onlinetest.test.bvt.dubbok;import org.assertj.core.api.AbstractAssert;public class CharacterAssert extends AbstractAssert {	public CharacterAssert(String actual) {		super(actual, CharacterAssert.class);
} public static CharacterAssert assertThat(String actual) { return new CharacterAssert(actual);
} public CharacterAssert hasChar(char c) { isNotNull(); if (!actual.contains(Character.toString(c))) {
failWithMessage("Expected string <%s> contains character <%s>, but not", actual, Character.toString(c));
} return this;
} public CharacterAssert notHasChar(char c) { isNotNull(); if (actual.contains(Character.toString(c))) {
failWithMessage("Expected string <%s> don't contains character <%s>, but yes", actual,
Character.toString(c));
} return this;
}
}

引用自定义断言:

CharacterAssert.assertThat("string").hasChar('s').notHasChar('a');

官方文档:http://joel-costigliola.github.io/assertj/

参考博客:https://blog.csdn.net/u011054333/article/details/55156896

网易云大礼包:https://www.163yun.com/gift

本文来自网易云社区,经作者范旭斐授权发布。

相关文章:
【推荐】 什么是高防服务器?

流式断言器AssertJ介绍的更多相关文章

  1. JAVA 流式布局管理器

    //流式布局管理器 import java.awt.*; import javax.swing.*; public class Jiemian2 extends JFrame{ //定义组件 JBut ...

  2. JAVA流式布局管理器--JAVA基础

    JAVA流式布局管理器的使用: FlowLayoutDeme.java: import java.awt.*;import javax.swing.*;public class FlowLayoutD ...

  3. Spark流式编程介绍 - 编程模型

    来源Spark官方文档 http://spark.apache.org/docs/latest/structured-streaming-programming-guide.html#programm ...

  4. java 图形化小工具Abstract Window Toolit ;布局管理器FlowLayout流式布局;BorderLayout边界布局;GridLayout网格布局;CardLayou重叠卡片布局;BoxLayout方框布局;绝对定位

    1.FlowLayout流式布局管理器: FlowLayout布局管理器中,组件像水流一样向某方向流动(排列),遇到障碍(边界)就折回,重头开始排列 .在默认情况下,FlowLayout局管理器从左向 ...

  5. 移动web中的流式布局和viewport知识介绍

    1   流式布局 其实  流式布局  就是百分比布局,通过盒子的宽度设置成百分比来根据屏幕的宽度来进行伸缩,不受固定像素的限制,内容向两侧填充. 这样的布局方式  就是移动web开发使用的常用布局方式 ...

  6. Storm简介——实时流式计算介绍

    概念 实时流式计算: 大数据环境下,流式数据将作为一种新型的数据类型,这种数据具有连续性.无限性和瞬时性.是实时数据处理所面向的数据类型,对这种流式数据的实时计算就是实时流式计算. 特征 实时流式计算 ...

  7. 分布式流式处理框架:storm简介 + Storm术语解释

    简介: Storm是一个免费开源.分布式.高容错的实时计算系统.它与其他大数据解决方案的不同之处在于它的处理方式.Hadoop 在本质上是一个批处理系统,数据被引入 Hadoop 文件系统 (HDFS ...

  8. 流式处理的新贵 Kafka Stream - Kafka设计解析(七)

    原创文章,转载请务必将下面这段话置于文章开头处. 本文转发自技术世界,原文链接 http://www.jasongj.com/kafka/kafka_stream/ Kafka Stream背景 Ka ...

  9. 【官方文档】Nginx模块Nginx-Rtmp-Module学习笔记(三)流式播放Live HLS视频

    源码地址:https://github.com/Tinywan/PHP_Experience HTTP Live Streaming(HLS)是由Apple Inc.实施的非常强大的流视频协议.HLS ...

随机推荐

  1. tmux分屏

    网上很多教程: 新手教程: tmux进入 ctrl + b 命令 % 纵向分屏 命令 方向键 切换 https://lukaszwrobel.pl/blog/tmux-tutorial-split-t ...

  2. __future__模块

    Python提供了__future__模块,把下一个新版本的特性导入到当前版本,于是我们就可以在当前版本中使用一些新版本的特性,比如除法: 在Python 2.x中,对于除法有两种情况,如果是整数相除 ...

  3. springmvc和easyui使用ajax前台后台互传数据,假删除提示警告问题。

    前台 //删除 多/单条数据 function del(cid){ var id=''; if(cid=='-1'){ if(getSelections().length > 0){ id=ge ...

  4. FastReport.net分组排序、打印顺序、分页、函数使用语法、数据块编辑

    本人使用的是FastReport.net1.0版,不涉及到任何代码,只是在FastReport中对打印模板的属性进行调整 1.设置打印顺序需要注意的属性 1)分组页眉中有个属性叫“condition” ...

  5. SharePoint2013之双语切换

    最近遇到个项目需要用SharePoint2013实现双语.看了篇老外的博客,经过项目经理的指点,终于算是搞定了(后面解释为什么说是"算是"). 在SharePoint2013中不像 ...

  6. 安装sqlserver2016出现的错误

    今天安装sharepoint 2016,projectserver 2016,在安装sqlserver2016的时候突然报错了,提示需要安装oracle java se, Rule “Oracle J ...

  7. 『ACM C++』 Codeforces | 1005D - Polycarp and Div 3

    今天佛了,魔鬼周一,在线教学,有点小累,但还好,今天AC了一道,每日一道,还好达成目标,还以为今天完不成了,最近任务越来越多,如何高效完成该好好思考一下了~最重要的还是学业的复习和预习. 今日兴趣新闻 ...

  8. JQuery制作网页—— 第六章 jQuery选择器

    1.jQuery选择器:jQuery选择器类似于CSS选择器,用来选取网页中的元素.       Eg:$("h3").css("background",&qu ...

  9. 高性能MySQL--innodb中事务的隔离级别与锁的关系

    最近买了<高性能MySQL>这本书回来看,从中收益颇多!我来一吐为快! 我们都知道事务,那么在什么情况下我们需要使用事务呢? 银行应用是解释事务的一个经典例子.假设一个银行的数据库有两张表 ...

  10. 2.1 摄像头V4L2驱动框架分析

    学习目标:学习V4L2(V4L2:vidio for linux version 2)摄像头驱动框架,分析vivi.c(虚拟视频硬件相关)驱动源码程序,总结V4L2硬件相关的驱动的步骤:  一.V4L ...