当前位置: 首页 > 编程日记 > 正文

JUnit4.11 理论机制 @Theory 完整解读

最近在研究JUnit4,大部分基础技术都是通过百度和JUnit的官方wiki学习的,目前最新的发布版本是4.11,结合代码实践,发现官方wiki的内容或多或少没有更新,Theory理论机制章节情况尤为严重,不知道这章wiki对应的是第几版,笔主在4.11版本中是完全跑不通的,因为接口结构已经改变了,而百度出来的博客文档更是只有Theory的基础部分,更具实际应用价值的扩展部分完全不见踪影,本文根据笔主实际编码总结经验,详细讲述如何使用4.11版JUnit的Theory理论机制。

ps. 最近发现网上有一小撮别有用心的国人转载笔主文章时,顺手丢羊把笔主文章头部标注的原文地址恶意马赛克掉,也没有在文后贴出转载地址,为了普及技术笔主就不追究了,这次故意在贴在这里,本文地址:JUnit4.11 理论机制 @Theory 完整解读

笔主下面所使用代码,仅依赖于 junit-4.11.jar,建议同时导入 hamcrest-core-1.3.jar、hamcrest-library-1.3.jar 以提供完整的assertThat支持

简单介绍Theory

使用注解@Theory取代@Test标记测试方法,可以支持带形参的测试方法签名,并使用指定的数据集自动代入进行连续多次测试,虽然暂未看到官方或其他个人的文字表述,但笔主觉得这个机制是参数化测试 Parameterized tests 的优化扩展版(Parameterized tests需要独占一个测试类,兼容性灵活性都太差了)。

使用@Theory测试方法需要在测试类头部声明@RunWith(Theories.class)

传统Theory

Theory的基础部分,通过显式预定义各种Class类型变量,在@Theory的带参测试方法中自动逐次传入相同Class类型的变量值,运行多次测试(依据预定义变量数量而定),复数形参情况使用预定义变量排列组合出实参对进行代入测试。

1、使用@DataPoint标记待用实参数据

1 @DataPoint
2 public static String **1 = “####”;
3 @DataPoint
4 public static String **2 = “####”;
5 @DataPoint
6 public static String **3 = “####”;

2.1、使用@Theory标记单形参测试方法

1 @Theory
2 // 仅输入与形参相同类型(String)的预定义@DataPoint数据,此处会自动轮流代入上面的 **1 - **3 作为实参测试数据,运行3次test1测试
3 public void test1(String ***) {
4         // 使用assume设置过滤
5         assumeThat(***);
6         assertThat(***);
7 }

2.2、复数形参测试方法

1 @Theory
2 // 使用排列组合与形参同类型(String)@DataPoint自动化输入,与命名、顺序无关,此处s1、s2将轮流使用 **1 - **3 的排列组合,如s1=**1,s2=**2或s1=**2,s2=**1,运行次数依据排列组合方案数量而定
3 public void test2(String s1, String s2) { 
4         assumeThat(***);
5         assertThat(***);
6 }

Theory扩展(Popper project)

这是本文的核心部分,传统Theory指定实参变量的方式存在非常明显的局限性,无法精确控制每个形参的可用变量值范围,因此JUnit引入Popper 项目的技术,提供一种完全自定义指定实参数据集的方法。

定制@Theory测试方法实参变量值范围,主要使用 Parameter Supplier 结构

系统自带默认实现

JUnit中自带一个默认的 Parameter Supplier 实现:@TestedOn(ints = int[])

使用方式示例:

1 @Theory
2 public final void test(@TestedOn(ints = { 0, 1, 2 }) int i) {
3     assertTrue(i >= 0);
4 }

在这个例子中,可以很直观的看到形参 i 在实际运行测试中,会依次自动代入取值为 ints 指定的数组{0, 1, 2}中每个元素

完全自定义实现

JUnit默认只提供了一个int型的简单 Parameter Supplier 实现,而Theory机制真正的价值在于,能参考@TestedOn的做法,相对简单的完全自定义出可重用 Parameter Supplier,适应于各种复杂要求的限定范围参数值测试场景,满足开发者所需的高度动态自定义范围取值自动化测试,同时保留与一般@Test相同的强大兼容性,作为本文核心中的战斗机,下面将通过两个栗子,详细描述如何一步步实现自定义 Parameter Supplier。

自定义实现I(动态实参值表)

本方式以一个自定义注解接口@Between为例,展示如何通过读取注解属性变量值,动态创建相应的实参数据集。

1、定义annotation注解接口 Between:

1 @Retention(RetentionPolicy.RUNTIME)
2 // 声明注解接口所使用的委托处理类
3 @ParametersSuppliedBy(BetweenSupplier.class)
4 public @interface Between{
5     // 声明所有可用参数,效果为 @Between([first = int,] last = int)
6     int first() default 0;  // 声明默认值,成为非必须提供项
7     int last();
8 }

2、定义委托处理类 BetweenSupplier:

 1 public class BetweenSupplier extends ParameterSupplier{
 2 
 3     @Override
 4     public List<PotentialAssignment> getValueSources(ParameterSignature sig) {
 5 
 6         // 自定义实参值列表
 7         List<PotentialAssignment> list = new ArrayList<PotentialAssignment>();
 8 
 9         // 获取注解变量
10         Between between = sig.getAnnotation(Between.class);
11 
12         // 获取通过注解@Between传入的first值
13         int first = between.first();
14 
15         // 获取通过注解@Between传入的last值
16         int last = between.last();
17  
18         for (int i = first; i <= last; i++){
19           // PotentialAssignment.forValue(String name, Object value)
20           // name为value的描述标记,没实际作用
21           // value为实参可选值
22             list.add(PotentialAssignment.forValue("name", i));
23         }
24         return list;
25     }
26 }

3、调用方式:

1 @Theory
2 public final void test(@Between(last = 0) int i, @Between(first = 3, last= 10) int j) {
3     // i 取值为 0(first默认=0,last=0),j 取值为 3-10
4     assertTrue(i + j >= 0);
5 }

自定义实现II(静态实参值表):

本方式以一个自定义注解接口@AllValue为例,展示如何静态地内部创建固定的实参数据集。

1、定义annotation注解接口 AllValue(按“使用II”方式调用可省略此步骤):

1 @Retention(RetentionPolicy.RUNTIME)
2 // 声明注解接口所使用的委托处理类
3 @ParametersSuppliedBy(AllValueSupplier.class)
4 // 空接口,不需要接受任何参数变量
5 public @interface AllValue{ }  

2、定义委托处理类 AllValueSupplier:

 1 public class AllValueSupplier extends ParameterSupplier{
 2 
 3     @Override
 4     public List<PotentialAssignment> getValueSources(ParameterSignature sig) {
 5         
 6         List<PotentialAssignment> list = new ArrayList<PotentialAssignment>();
 7   
 8       // 内定提供固定的可用实参值表
 9         for (int i = 0; i <= 100; i++){
10             list.add(PotentialAssignment.forValue("name", i));
11         }
12         return list;
13     }
14 }

3.1、使用I(使用自定义注解):

1 @Theory
2 public final void test(@AllValue int i) {
3     // i 取值为 0-100
4     assertTrue(i >= 0);
5 }

3.2、使用II(可省略第1步注解接口AllValue的定义):

1 @Theory
2 public final void test(@ParametersSuppliedBy(AllValueSupplier.class) int i) {
3     // i 取值为 0-100
4     assertTrue(i >= 0);
5 }

JUnit官方wiki及下载地址:https://github.com/junit-team/junit/wiki

Theory理论机制英文原文wiki(注:已过期,不适用于4.11):https://github.com/junit-team/junit/wiki/Theories

转载于:https://www.cnblogs.com/wavky/p/JUnit4_Theory.html

相关文章:

树链剖分——线段树区间合并bzoj染色

线段树区间合并就挺麻烦了&#xff0c;再套个树链就更加鬼畜&#xff0c;不过除了代码量大就没什么其他的了。。 一些细节&#xff1a;线段树每个结点用结构体保存&#xff0c;pushup等合并函数改成返回一个结构体&#xff0c;这样好写一些 struct Seg{int lc,rc,tot;Seg(){lcr…

MyRocks: 为facebool 的社交图谱服务的LSM-tree存储引擎

文章目录概览1. UDB 架构2. UDB 表格式3. Rocksdb&#xff1a;针对flash存储优化过的第三方库3.1 Rocksdb架构3.2 为什么选择Rocksdb4. MyRocks / Rocksdb 开发历程4.1 设计目标4.2 性能挑战4.2.1 降低CPU的消耗4.2.2 降低range-scan 的延时消耗4.2.3 磁盘空间和Compaction 的一…

Java项目:精品酒店管理系统(java+SSM+mysql+maven+tomcat)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能&#xff1a;主要功能主要功能会员管理&#xff0c;住客管理&#xff0c;房间管 理&#xff0c;系统管理&#xff0c;以及一些重要数据的展示导出维护等等; 二、项目运行 环境配置&…

iOS自动布局一

Align: Pin&#xff1a; 转载于:https://www.cnblogs.com/123qw/p/4404167.html

C#实现路由器断开连接,更改公网ip

publicstaticvoidDisconnect(){stringurl "断 线"; stringuri "http://192.168.1.1/userRpm/StatusRpm.htm?Disconnect"System.Web.HttpUtility.UrlEncode(url, System.Text.Encoding.GetEncoding("gb2312")) "&wan1"; str…

Go中的iota

当时在学习Iota这个知识点的时候仅仅是一笔掠过&#xff0c;比如这种 const(aiotab c) 一眼看出他怎么使用的时候就觉得自己已经懂得了 再到后来看到这样的例子 const&#xff08;a 5*iotab c &#xff09;以及 const&#xff08;a 1<<(10*iota)bc &#xff09; 第一…

从 SSLTLS 的底层实现来看 网络安全的庞大复杂体系

文章目录前言1. HTTP协议通信的问题1.1 tcpdump 抓取http 请求包1.2 报文分析1.3 HTTP 协议问题2. SSL & TLS 协议的基本介绍和历史演进3. TLS 1.2 实现加密传输的过程3.1 TLS HandShake 协议概览3.2 第一次握手&#xff1a;ClientHello3.3 第二次握手&#xff1a;从Server…

UICollectionView

UICollectionView 多列的UITableView,最简单的形式&#xff0c;类似于iBooks中书架的布局&#xff0c;书架中放着你下载的和购买的电子书。 最简单的UICollectionView是一个GridView&#xff0c;可以多列的方式进行展示。 包含三部分&#xff0c;都是UIView的子类&#xff1a; …

Java项目:课程资源管理+在线考试平台(java+SSH+mysql+maven+tomcat)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能包括&#xff1a; 管理员可以增删改查教材、教材商、入库教材、用户(用 户包括学生和教师)可以对教材商、教材进行。xcel的导入 导出操作。教师可以领取入库的教材&#xff0c;可以退还教…

python twisted 笔记

2019独角兽企业重金招聘Python工程师标准>>> 1.Twisted框架构建简单的C/S 要写一个基于twisted框架的服务器&#xff0c;你要实现事件处理器&#xff0c;它处理诸如一个新的客户端连接、新的数据到达和客户端连接中断等情况。 在Twisted中,你的事件处理器定义在一个…

决策树J48算法

1. J48原理 2. 举例 3. 总结 1. J48原理 基于从上到下的策略&#xff0c;递归的分治策略&#xff0c;选择某个属性放置在根节点&#xff0c;为每个可能的属性值产生一个分支&#xff0c;将实例分成多个子集&#xff0c;每个子集对应一个根节点的分支&#xff0c;然后在每个分支…

分布式系统 一致性模型的介绍 以及 zookeeper的 “线性一致性“ 讨论

文章目录1. 一致性 概览1.1 分布式系统的 “正确性”1.2 线性一致性(Linearizability)1.3 顺序一致性(Sequential consistency)1.4 因果一致性(Casual consistency)1.5 最终一致性(Eventual consistency)2. Zookeeper 的 “线性一致性” 问题3. 参考一致性算是分布式系统的定位…

Java项目:(小程序)全套商城系统(spring+spring mvc+mybatis+layui+微信小程)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 本系统功能包括: 商品模块: 商品添加、规格设置&#xff0c;商品上下架等 订单模块: 下单、购物车、支付&#xff0c;发货、收货、评 退款等 营销模块: 积分、优惠券、分销、砍价、拼团、秒 多…

【转】[退役]纪念我的ACM——headacher@XDU

转自&#xff1a;http://hi.baidu.com/headacher/item/5a2ce1d50609091b20e25022 退役了&#xff0c;是时候总结一下我ACM的生涯了。虽然很舍不得&#xff0c;但这段回忆很值得纪念。ACM生涯虽然结束&#xff0c;但是新生活总要继续&#xff0c;还有很多东西需要我去学习&#…

VMware扩大硬盘后修改Linux逻辑卷大小

一、背景随着业务的不断成熟&#xff0c;数据库积累的数据也越来越多了。前些天发现服务器的磁盘将要满了。因此向虚拟化管理员申请增加磁盘空间。由于这个系统是建立在威睿的vSphere平台上的&#xff0c;因此虚拟化管理员只简单地通过 VMware vSphere Client 扩大了磁盘空间&a…

axios与ajax区别

1.jQuery ajax $.ajax({ type: POST, url: url, data: data, dataType: dataType, success: function () {}, error: function () {}});优缺点&#xff1a; 本身是针对MVC的编程,不符合现在前端MVVM的浪潮基于原生的XHR开发&#xff0c;XHR本身的架构不清晰&#xff0c;已经有…

单机 “5千万以上“ 工业级 LRU cache 实现

文章目录前言工业级 LRU Cache1. 基本架构2. 基本操作2.1 insert 操作2.2 高并发下 insert 的一致性/性能 保证2.3 Lookup操作2.4 shard 对 cache Lookup 性能的影响2.4 Erase 操作2.5 内存维护3. 优化前言 近期做了很多 Cache 优化相关的事情&#xff0c;因为对存储引擎较为熟…

Java项目:校园人力人事资源管理系统(java+Springboot+ssm+mysql+jsp+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 校园人力资源管理系统&#xff1a;学校部门管理&#xff0c;教室管理&#xff0c;学历信息管理&#xff0c;职务&#xff0c;教师职称&#xff0c;奖励&#xff0c;学历&#xff0c;社会关系&#xff0c;工作…

GPS部标平台的架构设计(十)-基于Asp.NET MVC构建GPS部标平台

在当前很多的GPS平台当中&#xff0c;有很多是基于asp.NETsiverlight开发的遗留项目&#xff0c;代码混乱而又难以维护&#xff0c;各种耦合和关联&#xff0c;要命的是界面也没见到比Javascript做的控件有多好看&#xff0c;随着需求的增多&#xff0c;平台已经臃肿不堪。 设计…

关于CSDN不给任何通知强制关闭我的6年博客,我深表痛心

关于CSDN不给任何通知强制关闭我的6年博客&#xff0c;我深表痛心。最近有很长一段时间没有去csdn博客了&#xff0c; 前几天去看的时候发现博客被封闭了。 我联系了管理员&#xff0c;但是没有得到任何回复。 我猜想&#xff0c;可能是不是我在博客文章里面加入 自己网站的网…

Vue 环境搭建(win10)

1.安装node node官网安装地址 推荐安装稳定版本&#xff08;LTS&#xff09;以及安装路径为系统盘&#xff08;C&#xff09; 查看node安装成功否 注释&#xff1a;以下命令使用 命令提示符&#xff08;管理员&#xff09;权限,win10 对user权限的限制了访问权限。node -v 查看…

Java项目:化妆品商城系统(java+Springboot+ssm+mysql+jsp+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 本系统主要实现的功能有&#xff1a; 网上商城系统&#xff0c;前台后台管理&#xff0c;用户注册&#xff0c;登录&#xff0c;上架展示&#xff0c;分组展示&#xff0c;搜索&#xff0c;收…

python 绘图脚本系列简单记录

简单记录平时画图用到的python 便捷小脚本 1. 从单个文件输入 绘制坐标系图 #!/usr/bin/python # coding: utf-8 import matplotlib.pyplot as plt import numpy as np import matplotlib as mpl import sysfile_name1 sys.argv[1] data_title sys.argv[2] print(file_name1…

iOS-c语言小练习01

// // main.c // C&#xff0d;变量的地址 // // Created by cgq on 15/4/9. // Copyright (c) 2015年 cgq. All rights reserved. // #include <stdio.h> //访问变量的地址 void test1() { char a A; int b 44; printf("a的值&#xff1a;%d\n",a); pri…

蓝桥杯 【基础练习】 十六进制转八进制

问题描述给定n个十六进制正整数&#xff0c;输出它们对应的八进制数。输入格式输入的第一行为一个正整数n &#xff08;1<n<10&#xff09;。接下来n行&#xff0c;每行一个由0~9、大写字母A~F组成的字符串&#xff0c;表示要转换的十六进制正整数&#xff0c;每个十六进…

泛在网:泛在网

ylbtech-泛在网&#xff1a;泛在网泛在网络来源于拉丁语Ubiquitous&#xff0c;从字面上看就是广泛存在的&#xff0c;无所不在的网络。也就是人置身于无所不在的网络之中&#xff0c;实现人在任何时间、地点&#xff0c;使用任何网络与任何人与物的信息交换&#xff0c;基于个…

Mac 从Makefile 编译 Rocksdb 源码的一些注意事项

文章目录前言Makefile 编译流程1. 平台变量/环境变量的初始化。2. 编译需要的源码文件变量初始化。3. include 目录的设置。4. 编译的执行逻辑。问题记录1&#xff1a;可能的打包命令ar 失效问题5. 执行具体的编译指令问题记录2: jar 包编译前言 最近在Mac 本地编译Rocksdb 过…

Java项目:在线考试系统(单选,多选,判断,填空,简答题)(java+Springboot+ssm+mysql+html+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 功能&#xff1a; 学生信息 班级 专业 学号 姓名 在线考试 成绩查询 个人信息 密码修改 教师管理 教师编号 姓名 所教科目 题库管理 单选题 多选题 填空题 判断题&#xff0c;简答题&#xff08;人工…

看了极光推送技术原理的几点思考

看了极光推送技术原理的几点思考 分类&#xff1a; android2012-11-26 20:50 16586人阅读 评论(18) 收藏 举报目录(?)[] 移动互联网应用现状 因为手机平台本身、电量、网络流量的限制&#xff0c;移动互联网应用在设计上跟传统 PC 上的应用很大不一样&#xff0c;需要根据手机…

查询远程或本地计算机的登录账户

用下面这个函数能获取远程或本地电脑的当前登录用户&#xff0c;同时附加了它的计算机名&#xff0c;所以当你查询多台电脑时将知道结果从哪里来。function Get-LoggedOnUser {param([String[]]$ComputerName $env:COMPUTERNAME)$ComputerName | ForEach-Object {(quser /SERV…