1. Overview
1.概述
JGoTesting is a JUnit-compatible testing framework inspired by Go’s testing package.
JGoTesting是一个与JUnit兼容的测试框架,其灵感来源于Go的测试包。
In this article, we’ll explore the key features of the JGoTesting framework and implement examples to showcase its capabilities.
在这篇文章中,我们将探讨JGoTesting框架的主要功能,并实施实例来展示其功能。
2. Maven Dependency
2.Maven的依赖性
First, let’s add the jgotesting dependency to our pom.xml:
首先,让我们把jgotesting依赖性添加到我们的pom.xml。
<dependency>
<groupId>org.jgotesting</groupId>
<artifactId>jgotesting</artifactId>
<version>0.12</version>
</dependency>
The latest version of this artifact can be found here.
该工件的最新版本可以在这里找到。
3. Introduction
3.简介
JGoTesting allows us to write tests that are compatible with JUnit. For every assertion method JGoTesting provides, there is one in JUnit with the same signature, thus implementing this library is really straightforward.
JGoTesting使我们能够编写与JUnit兼容的测试。对于JGoTesting提供的每一个断言方法,在JUnit中都有一个相同的签名,因此实现这个库是非常简单的。
However, unlike JUnit, when an assertion fails, JGoTesting doesn’t stop the execution of the test. Instead, the failure is recorded as an event and presented to us only when all assertions have been executed.
然而,与JUnit不同,当断言失败时,JGoTesting并不停止测试的执行。相反,失败被记录为一个事件,只有在所有断言都被执行后才会呈现给我们。
4. JGoTesting in Action
4.JGoTesting在行动
In this section, we will see examples of how to setup JGoTesting and explore its possibilities.
在本节中,我们将看到关于如何设置JGoTesting和探索其可能性的例子。
4.1. Getting Started
4.1.起步
In order to write our tests, let’s first import JGoTesting’s assertion methods:
为了编写我们的测试,让我们首先导入JGoTesting的断言方法。
import static org.jgotesting.Assert.*; // same methods as JUnit
import static org.jgotesting.Check.*; // aliases starting with "check"
import static org.jgotesting.Testing.*;
The library requires a mandatory JGoTestRule instance marked with the @Rule annotation. This indicates that all tests in the class will be will be managed by JGoTesting.
该库需要一个强制性的JGoTestRule实例,并标有@Rule注解。这表明该类中的所有测试都将由JGoTesting管理。
Let’s create a class declaring such rule:
让我们创建一个声明这种规则的类。
public class JGoTestingUnitTest {
@Rule
public final JGoTestRule test = new JGoTestRule();
//...
}
4.2. Writing Tests
4.2.编写测试
JGoTesting provides two set of assertion methods to write our tests. The names of the methods in the first set start with assert and are the ones compatible with JUnit, and the others start with a check.
JGoTesting提供了两组断言方法来编写我们的测试。第一组方法的名称以assert开头,是与JUnit兼容的方法,其他的以check开头。
Both sets of methods behave the same, and the library provides a one-to-one correspondence between them.
这两组方法的行为都是一样的,库中提供了它们之间的一对一对应关系。
Here’s an example to test whether a number is equal to another, using both versions:
下面是一个测试一个数字是否等于另一个数字的例子,使用两个版本。
@Test
public void whenComparingIntegers_thenEqual() {
int anInt = 10;
assertEquals(anInt, 10);
checkEquals(anInt, 10);
}
The rest of the API is self-explanatory, so we won’t go into further details. For all examples that follow, we are going to focus only on the check version of the methods.
API的其余部分是不言自明的,所以我们不会进一步讨论细节。在接下来的所有例子中,我们将只关注check版本的方法。
4.3. Failure Events and Messages
4.3.故障事件和信息
When a check fails, JGoTesting records the failure in order for the test case to continue its execution. After the test ends, the failures are reported.
当检查失败时,JGoTesting 会记录失败,以便测试案例继续执行。测试结束后,会报告失败的情况。
Here’s an example to show what this looks like:
下面是一个例子,说明这看起来像什么。
@Test
public void whenComparingStrings_thenMultipleFailingAssertions() {
String aString = "The test string";
String anotherString = "The test String";
checkEquals("Strings are not equal!", aString, equalTo(anotherString));
checkTrue("String is longer than one character", aString.length() == 1);
checkTrue("A failing message", aString.length() == 2);
}
After executing the test, we get the following output:
执行测试后,我们得到以下输出。
org.junit.ComparisonFailure: Strings are not equal!
expected:<[the test s]tring> but was:<[The Test S]tring>
// ...
java.lang.AssertionError: String is longer than one character
// ...
java.lang.AssertionError: Strings are not the same
expected the same:<the test string> was not:<The Test String>
Besides passing the failure messages in each method, we can also log them so that they only appear when a test has at least one failure.
除了在每个方法中传递失败信息外,我们还可以记录它们,以便它们只在一个测试至少有一个失败时出现。
Let’s write a test method that puts this into practice:
让我们写一个测试方法,将其付诸实践。
@Test
public void whenComparingNumbers_thenLoggedMessage() {
log("There was something wrong when comparing numbers");
int anInt = 10;
int anotherInt = 10;
checkEquals(anInt, 10);
checkTrue("First number should be bigger", 10 > anotherInt);
checkSame(anInt, anotherInt);
}
After test execution, we get the following output:
测试执行后,我们得到以下输出。
org.jgotesting.events.LogMessage: There was something wrong
when comparing numbers
// ...
java.lang.AssertionError: First number should be bigger
Notice that in addition to logf(), which can format messages as the String.format() method, we can also use the logIf() and logUnless() methods to log messages based on a conditional expression.
注意,除了logf()可以像String.format()方法那样格式化消息外,我们还可以使用logIf()和logUnless()方法来根据条件表达式记录消息。
4.4. Interrupting Tests
4.4.中断测试
JGoTesting provides several ways to terminate tests cases when they fail to pass a given precondition.
JGoTesting提供了几种方法,当测试案例未能通过给定的前提条件时,可以终止它们。
Here is an example of a test that ends prematurely because a required file doesn’t exist:
下面是一个测试过早结束的例子,因为一个需要的文件不存在。
@Test
public void givenFile_whenDoesnotExists_thenTerminated() throws Exception {
File aFile = new File("a_dummy_file.txt");
terminateIf(aFile.exists(), is(false));
// this doesn't get executed
checkEquals(aFile.getName(), "a_dummy_file.txt");
}
Notice that we can also use the terminate() and terminateUnless() methods to interrupt test execution.
注意,我们也可以使用terminate()和terminateUnless()方法来中断测试执行。
4.5. Chaining
4.5.连环画
The JGoTestRule class also has a fluent API that we can use to chain checks together.
JGoTestRule类也有一个流畅的API,我们可以用它来连锁检查。
Let’s look at an example that uses our instance of JGoTestRule to chain together multiple checks on String objects:
让我们看看一个例子,它使用我们的JGoTestRule实例,对String对象进行连锁的多重检查。
@Test
public void whenComparingStrings_thenMultipleAssertions() {
String aString = "This is a string";
String anotherString = "This Is a String";
test.check(aString, equalToIgnoringCase(anotherString))
.check(aString.length() == 16)
.check(aString.startsWith("This"));
}
4.6. Custom Checks
4.6.定制支票
In addition to boolean expressions and Matcher instances, JGoTestRule‘s methods can accept a custom Checker object to do the checking. This is a Single Abstract Method interface which can be implemented using a lambda expression.
除了boolean表达式和Matcher实例之外,JGoTestRule的方法可以接受一个自定义的Checker对象来进行检查。这是一个单一的抽象方法接口,可以使用lambda表达式来实现。
Here’s an example that verifies if a String matches a particular regular expression using the aforementioned interface:
下面是一个使用上述接口验证一个String是否匹配特定正则表达式的例子。
@Test
public void givenChecker_whenComparingStrings_thenEqual() throws Exception {
Checker<String> aChecker = s -> s.matches("\\d+");
String aString = "1235";
test.check(aString, aChecker);
}
5. Conclusion
5.结论
In this quick tutorial, we explored the features JGoTesting provides us for writing tests.
在这个快速教程中,我们探讨了JGoTesting为我们提供的编写测试的功能。
We showcased the JUnit-compatible assert methods as well as their check counterparts. We also saw how the library records and reports failure events, and we wrote a custom Checker using a lambda expression.
我们展示了与JUnit兼容的assert方法,以及它们的check对应方法。我们还看到了库是如何记录和报告失败事件的,并且我们使用lambda表达式写了一个自定义的Checker。
As always, complete source code for this article can be found over on Github.
一如既往,本文的完整源代码可以在Github上找到over。