JUnit 4 超详细教程(一)
下篇文档地址:JUnit 4 超详细教程(二)
JUnit是Java编程语言的单元测试框架,用于编写和可重复运行的自动化测试。
JUnit4通过注解的方式来识别测试方法。目前支持的主要注解有(下列注解标示了单元测试的不同运行阶段执行的代码):
JUnit为所有原语类型、对象和数组(原语或对象)提供重载断言方法。参数顺序为预期值后接实际值。或者,第一个参数可以是失败时输出的字符串消息。
有一个稍有不同的断言,assertThat具有可选失败消息的参数、实际值和Matcher对象。请注意,与其他assert方法相比,它的预期值和实际值是相反的(实际值后接预期值)。
下面例子列举了所有可用的assert方法,可以在使用时作用法参考
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.both;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.everyItem;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import org.hamcrest.core.CombinableMatcher;
import org.junit.Test;
public class AssertTests {
@Test
public void testAssertArrayEquals() {
byte[] expected = "trial".getBytes();
byte[] actual = "trial".getBytes();
assertArrayEquals("failure - byte arrays not same", expected, actual);
}
@Test
public void testAssertEquals() {
assertEquals("failure - strings are not equal", "text", "text");
}
@Test
public void testAssertFalse() {
assertFalse("failure - should be false", false);
}
@Test
public void testAssertNotNull() {
assertNotNull("should not be null", new Object());
}
@Test
public void testAssertNotSame() {
assertNotSame("should not be same Object", new Object(), new Object());
}
@Test
public void testAssertNull() {
assertNull("should be null", null);
}
@Test
public void testAssertSame() {
Integer aNumber = Integer.valueOf(768);
assertSame("should be same", aNumber, aNumber);
}
// JUnit Matchers assertThat
@Test
public void testAssertThatBothContainsString() {
assertThat("albumen", both(containsString("a")).and(containsString("b")));
}
@Test
public void testAssertThatHasItems() {
assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));
}
@Test
public void testAssertThatEveryItemContainsString() {
assertThat(Arrays.asList(new String[] { "fun", "ban", "net" }), everyItem(containsString("n")));
}
// Core Hamcrest Matchers with assertThat
@Test
public void testAssertThatHamcrestCoreMatchers() {
assertThat("good", allOf(equalTo("good"), startsWith("good")));
assertThat("good", not(allOf(equalTo("bad"), equalTo("good"))));
assertThat("good", anyOf(equalTo("bad"), equalTo("good")));
assertThat(7, not(CombinableMatcher.<Integer> either(equalTo(3)).or(equalTo(4))));
assertThat(new Object(), not(sameInstance(new Object())));
}
@Test
public void testAssertTrue() {
assertTrue("failure - should be true", true);
}
}
import org.junit.*;
/**
* JunitTest
*
* @author Brian Tse
* @since 2021/10/19 9:10
*/
public class JunitTest {
@BeforeClass
public static void beforeClass() {
System.out.println("@BeforeClass --> 全局只会执行一次,而且是第一个运行");
}
@AfterClass
public static void afterClass() {
System.out.println("@AfterClass --> 全局只会执行一次,而且是最后一个运行");
}
@Before
public void before() {
System.out.println("@Before --> 在测试方法运行之前运行(每个测试方法之前都会执行一次)");
}
@After
public void after() {
System.out.println("@After --> 在测试方法运行之后允许(每个测试方法之后都会执行一次)");
}
@Test
public void testCase1() {
System.out.println("@Test --> 测试方法1");
}
@Test
public void testCase2() {
System.out.println("@Test --> 测试方法2");
}
}
执行结果如下:
@BeforeClass --> 全局只会执行一次,而且是第一个运行
@Before --> 在测试方法运行之前运行(每个测试方法之前都会执行一次)
@Test --> 测试方法1
@After --> 在测试方法运行之后允许(每个测试方法之后都会执行一次)
@Before --> 在测试方法运行之前运行(每个测试方法之前都会执行一次)
@Test --> 测试方法2
@After --> 在测试方法运行之后允许(每个测试方法之后都会执行一次)
@AfterClass --> 全局只会执行一次,而且是最后一个运行
Process finished with exit code 0
如何验证代码是否按预期抛出异常?验证代码是否正常完成很重要,但确保代码在异常情况下按预期运行也很重要。
例如:
new ArrayList<Object>().get(0);
此代码也许会引发IndexOutOfBoundsException。JUnit中有多种方法可以编写测试来验证此行为。
assertThrows方法JUnit 4.13版本可以使用assertThrows方法。此方法可以断言给定的函数调用(例如,指定为lambda表达式或方法引用)会导致引发特定类型的异常。此外,它还返回抛出的异常,以便进一步断言(例如,验证抛出的消息和原因是否符合预期)。此外,可以在引发异常后对域对象的状态进行断言。
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.*;
/**
* ExceptionTest
*
* @author Brian Tse
* @since 2021/10/19 9:25
*/
public class ExceptionTest {
@Test
public void testExceptionAndState() {
List<Object> list = new ArrayList<>();
// 可以断言给定的函数调用会导致引发特定类型的异常
IndexOutOfBoundsException thrown = assertThrows(
IndexOutOfBoundsException.class,
() -> list.add(1, new Object()));
// 根据返回抛出的异常,进一步断言抛出的消息和原因是否符合预期
assertEquals("Index: 1, Size: 0", thrown.getMessage());
// 在引发异常后对域对象的状态进行断言
assertTrue(list.isEmpty());
}
}
如果项目中尚未使用JUnit 4.13或代码库不支持lambdas,则可以使用JUnit 3.x中流行的try/catch习惯用法:
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
/**
* ExceptionTest
*
* @author Brian Tse
* @since 2021/10/19 9:25
*/
public class ExceptionTest {
@Test
public void testExceptionAndState() {
List<Object> list = new ArrayList<>();
try {
Object o = list.get(0);
fail("Expected an IndexOutOfBoundsException to be thrown");
} catch (IndexOutOfBoundsException anIndexOutOfBoundsException) {
assertThat(anIndexOutOfBoundsException.getMessage(), is("Index: 0, Size: 0"));
}
}
}
Junit 用代码处理提供了一个追踪异常的选项。你可以测试代码是否它抛出了想要得到的异常。expected 参数和 @Test 注释一起使用。现在让我们看看 @Test(expected)。
import org.junit.Test;
import java.util.ArrayList;
/**
* ExceptionTest
*
* @author Brian Tse
* @since 2021/10/19 9:25
*/
public class ExceptionTest {
@Test(expected = IndexOutOfBoundsException.class)
public void testExceptionAndState() {
new ArrayList<Object>().get(0);
}
}
应谨慎使用’expected’参数。如果方法中的any代码抛出’IndexOutOfBoundsException’,则上述测试将通过。使用该方法,无法测试异常中消息的值,或引发异常后域对象的状态。
另一种测试异常的方法是’预期异常’规则,但这种方法在JUnit4.13中已被弃用。通过此规则,您不仅可以指示所需的异常,还可以指示所需的异常消息。
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.util.ArrayList;
import java.util.List;
/**
* ExceptionTest
*
* @author Brian Tse
* @since 2021/10/19 9:25
*/
public class ExceptionTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void shouldTestExceptionMessage() throws IndexOutOfBoundsException {
List<Object> list = new ArrayList<Object>();
thrown.expect(IndexOutOfBoundsException.class);
thrown.expectMessage("Index: 0, Size: 0");
// execution will never get past this line
list.get(0);
}
}
expectMessage还允许使用Matchers,这为您的测试提供了更大的灵活性。例如:
thrown.expectMessage(CoreMatchers.containsString("Size: 0"));
此外,可以使用匹配器来检查异常,如果它具有您希望验证的嵌入状态,这将非常有用。例如
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.startsWith;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
public class TestExy {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void shouldThrow() {
TestThing testThing = new TestThing();
thrown.expect(NotFoundException.class);
thrown.expectMessage(startsWith("some Message"));
thrown.expect(hasProperty("response", hasProperty("status", is(404))));
testThing.chuck();
}
private class TestThing {
public void chuck() {
Response response = Response.status(Status.NOT_FOUND).entity("Resource not found").build();
throw new NotFoundException("some Message", response);
}
}
}
有关“ExpectedException”规则的详细讨论,请参阅此博文.
请注意,当测试调用抛出异常的被测方法时,该方法之后的测试中不会执行任何代码(因为被测方法正在抛出异常)。这可能会导致混淆,也是JUnit 4.13废弃’ExpectedException.none()'的原因之一。
带有@Ignore注解的测试方法不会被执行
@Ignore
@Test
public void testCase2() {
System.out.println("@Test --> 测试方法2");
}
JUnit提供了一个超时选项,如果一个测试用例比起指定的毫秒数花费了更多的时间,那么JUnit将自动将它标记为失败,timeout参数和@Test注解一起使用,例如@Test(timeout=1000)。 继续使用刚才的例子,现在将testCase1的执行时间延长到2000毫秒,并加上时间参数,设置超时为1000毫秒,然后执行测试类
@Test(timeout = 1000)
public void testCase1() throws InterruptedException {
TimeUnit.SECONDS.sleep(2);
System.out.println("@Test --> 测试方法1");
}
结果如下:
org.junit.runners.model.TestTimedOutException: test timed out after 1000 milliseconds
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at com.brian.junit4.demo.JunitTest.testCase1(JunitTest.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:298)
at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:748)
JUnit 4引入了一项名为参数化测试的新功能。参数化测试允许开发人员使用不同的值反复运行相同的测试。创建参数化测试需要遵循五个步骤:
对于每行数据,将调用一次测试用例。让我们看看参数化测试的实际效果。
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
/**
* PrimeNumberCheckerTest
*
* @author Brian Tse
* @since 2021/10/19 10:44
*/
//使用 @RunWith(Parameterized.class)注释测试类
@RunWith(Parameterized.class)
public class PrimeNumberCheckerTest {
// 为测试数据的每个“列”创建一个实例变量
private Integer inputNumber;
private Boolean expectedResult;
private PrimeNumberChecker primeNumberChecker;
@Before
public void initialize() {
primeNumberChecker = new PrimeNumberChecker();
}
// 创建一个公共构造函数,它接受相当于一行“测试数据”的内容
public PrimeNumberCheckerTest(Integer inputNumber, Boolean expectedResult) {
this.inputNumber = inputNumber;
this.expectedResult = expectedResult;
}
//创建一个使用 @Parameters注释的公共静态方法,该方法返回一个对象集合作为测试数据集
@Parameterized.Parameters
public static Collection primeNumbers() {
return Arrays.asList(new Object[][]{{2, true}, {6, false}, {19, true}, {22, false}, {23, true}});
}
@Test
public void testPrimeNumberChecker() {
// 使用实例变量作为测试数据的来源创建测试用例
System.out.println("Parameterized Number is : " + inputNumber);
assertEquals(expectedResult, primeNumberChecker.validate(inputNumber));
}
}
结果如下:
Parameterized Number is : 2
Parameterized Number is : 6
Parameterized Number is : 19
Parameterized Number is : 22
Parameterized Number is : 23
此断言语法的优点包括:更具可读性和可键入性。
JUnit中的部分断言的可读性并不是很好,有时我们不得不自己编写表达式并断言其结果,并且因为我们没有提供失败的信息,当这个断言失败时只会抛出java.lang.AssertionError,无法知道到底是哪一部分出错。
assertTrue(responseString.contains("color") || responseString.contains("colour"));
// ==> failure message:
// java.lang.AssertionError:
assertThat(responseString, anyOf(containsString("color"), containsString("colour")));
// ==> failure message:
// java.lang.AssertionError:
// Expected: (a string containing "color" or a string containing "colour")
// but: was "responseString字符串"
JUnit4.4引入了Hamcrest框架,Hamcest提供了一套匹配符Matcher,这些匹配符更接近自然语言,可读性高,更加灵活。并且使用全新的断言语法:assertThat,结合Hamcest提供的匹配符,只用这一个方法,就可以实现所有的测试。
assertThat语法如下:
其中reason为断言失败时的输出信息,actual为断言的值或对象,matcher为断言的匹配器,里面的逻辑决定了给定的actual对象满不满足断言。
JUnit4的匹配器定义在org.hamcrest.CoreMatchers 和 org.junit.matchers.JUnitMatchers 中。通过静态导入的方式引入相应的匹配器。
org.junit.matchers.JUnitMatchers比较器中大部分都被标记为Deprecated,并使用org.hamcrest.CoreMatchers对应方法进行取代,但有两个方法得到了保留:
static <T extends Exception> Matcher<T> isException(Matcher<T> exceptionMatcher)
static <T extends Throwable> Matcher<T> isThrowable Matcher<T> throwableMatcher)
Hamcrest CoreMatchers在JUnit4.9版本被包含在JUnit的分发包中。
@Test
public void test() {
// 一般匹配符
// allOf:所有条件必须都成立,测试才通过
assertThat(actual, allOf(greaterThan(1), lessThan(3)));
// anyOf:只要有一个条件成立,测试就通过
assertThat(actual, anyOf(greaterThan(1), lessThan(1)));
// anything:无论什么条件,测试都通过
assertThat(actual, anything());
// is:变量的值等于指定值时,测试通过
assertThat(actual, is(2));
// not:和is相反,变量的值不等于指定值时,测试通过
assertThat(actual, not(1));
// 数值匹配符
// closeTo:浮点型变量的值在3.0±0.5范围内,测试通过
assertThat(actual, closeTo(3.0, 0.5));
// greaterThan:变量的值大于指定值时,测试通过
assertThat(actual, greaterThan(3.0));
// lessThan:变量的值小于指定值时,测试通过
assertThat(actual, lessThan(3.5));
// greaterThanOrEuqalTo:变量的值大于等于指定值时,测试通过
assertThat(actual, greaterThanOrEqualTo(3.3));
// lessThanOrEqualTo:变量的值小于等于指定值时,测试通过
assertThat(actual, lessThanOrEqualTo(3.4));
// 字符串匹配符
// containsString:字符串变量中包含指定字符串时,测试通过
assertThat(actual, containsString("ci"));
// startsWith:字符串变量以指定字符串开头时,测试通过
assertThat(actual, startsWith("Ma"));
// endsWith:字符串变量以指定字符串结尾时,测试通过
assertThat(actual, endsWith("i"));
// euqalTo:字符串变量等于指定字符串时,测试通过
assertThat(actual, equalTo("Magci"));
// equalToIgnoringCase:字符串变量在忽略大小写的情况下等于指定字符串时,测试通过
assertThat(actual, equalToIgnoringCase("magci"));
// equalToIgnoringWhiteSpace:字符串变量在忽略头尾任意空格的情况下等于指定字符串时,测试通过
assertThat(actual, equalToIgnoringWhiteSpace(" Magci "));
// 集合匹配符
// hasItem:Iterable变量中含有指定元素时,测试通过
assertThat(actual, hasItem("Magci"));
// hasEntry:Map变量中含有指定键值对时,测试通过
assertThat(actual, hasEntry("mgc", "Magci"));
// hasKey:Map变量中含有指定键时,测试通过
assertThat(actual, hasKey("mgc"));
// hasValue:Map变量中含有指定值时,测试通过
assertThat(actual, hasValue("Magci"));
}
1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,
在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主
1.1.1 YARN的介绍 为克服Hadoop1.0中HDFS和MapReduce存在的各种问题⽽提出的,针对Hadoop1.0中的MapReduce在扩展性和多框架⽀持⽅⾯的不⾜,提出了全新的资源管理框架YARN. ApacheYARN(YetanotherResourceNegotiator的缩写)是Hadoop集群的资源管理系统,负责为计算程序提供服务器计算资源,相当于⼀个分布式的操作系统平台,⽽MapReduce等计算程序则相当于运⾏于操作系统之上的应⽤程序。 YARN被引⼊Hadoop2,最初是为了改善MapReduce的实现,但是因为具有⾜够的通⽤性,同样可以⽀持其他的分布式计算模
我是Ruby新手,并被要求在我们的新项目中使用它。我们还被要求使用Padrino(Sinatra)作为后端/框架。我们被要求使用Rspec进行测试。我一直在寻找可以指导在Padrino上使用RspecforRuby的教程。我得到的主要是引用RoR。但是,我需要RubyonPadrino。请在任何入门/指南/引用/讨论等方面指导我。如有不妥之处请指正。可能是我没有针对我的问题搜索正确的词/短语组合。我正在使用Ruby1.9.3和Padrinov.0.10.6。注意:我还提到了SOquestion,但它没有帮助。 最佳答案 我没用过Pa
1.问题描述使用Python的turtle(海龟绘图)模块提供的函数绘制直线。2.问题分析一幅复杂的图形通常都可以由点、直线、三角形、矩形、平行四边形、圆、椭圆和圆弧等基本图形组成。其中的三角形、矩形、平行四边形又可以由直线组成,而直线又是由两个点确定的。我们使用Python的turtle模块所提供的函数来绘制直线。在使用之前我们先介绍一下turtle模块的相关知识点。turtle模块提供面向对象和面向过程两种形式的海龟绘图基本组件。面向对象的接口类如下:1)TurtleScreen类:定义图形窗口作为绘图海龟的运动场。它的构造器需要一个tkinter.Canvas或ScrolledCanva
文章目录1.任务背景2.任务目标3.相关知识点4.任务实操4.1安装配置JDK4.2启动FISCOBCOS4.3下载解压WeBASE-Front4.4拷贝sdk证书文件4.5启动节点4.6访问节点4.7检查运行状态5.任务总结1.任务背景FISCOBCOS其实是有控制台管理工具,用来对区块链系统进行各种管理操作。但是对于初学者来说,还是可视化界面更友好,本节就来介绍WeBASE管理平台,这是一款微众银行开源的自研区块链中间件平台,可以降低区块链使用的门槛,大幅提高区块链应用的开发效率。微众银行是腾讯牵头设立的民营银行,在国内民营银行里还是比较出名的。微众银行参与FISCOBCOS生态建设,一定
目录H2数据库入门以及实际开发时的使用1.H2数据库的初识1.1H2数据库介绍1.2为什么要使用嵌入式数据库?1.3嵌入式数据库对比1.3.1性能对比1.4技术选型思考2.H2数据库实战2.1H2数据库下载搭建以及部署2.1.1H2数据库的下载2.1.2数据库启动2.1.2.1windows系统可以在bin目录下执行h2.bat2.1.2.2同理可以通过cmd直接使用命令进行启动:2.1.2.3启动后控制台页面:2.1.3spring整合H2数据库2.1.3.1引入依赖文件2.1.4数据库通过file模式实际保存数据的位置2.2H2数据库操作2.2.1Mysql兼容模式2.2.2Mysql模式
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:FlashMessagesinPartials(Rails3)我正在做MichaelHartl的Railstutorial和listing7.26将flash消息添加到应用程序布局:...">...这很好用。但是,我试图通过在我的部分文件夹中创建一个_flash.html.erb来清理这段代码...">-->...并且比使用......在我的应用程序布局中,我的所有Rspec测试开始失败,每个测试都显示以下消息:Failure/Error:before{visitsignup_path}ActionView:
我正在使用SublimeText2,同时遵循MichaelHartl的RubyonRails教程。可以在http://ruby.railstutorial.org/book/ruby-on-rails-tutorial找到我所指的教程的具体部分。(ctrl+F“list5.26”)。我能够创建规范/支持文件。但是,在尝试创建spec/support/utilities.rb文件时,我收到消息“无法保存~/rails_projects/sample_app/spec/support/utilities.rb”。有人知道为什么会这样吗?SublimeText论坛上有人似乎遇到了完全相同的问
目录一、安装包链接二、安装详细步骤1.安装Wireshark和WinPcap2.安装OracleVMVirtualBox3.安装ensp三、安装后注册四、启动路由器出现40错误怎么解决一、安装包链接二、安装详细步骤链接:https://pan.baidu.com/s/1QbUUYMOMIV2oeIKHWP1SpA?pwd=xftx提取码:xftx1.安装Wireshark和WinPcap找到Wireshark安装包所在文件夹,双击它,按照以下步骤安装。2.安装OracleVMVirtualBox找到OracleVMVirtualBox安装包所在文件夹,双击它,按照以下步骤安装。注:可自定义安装