Vert.x Unit

已弃用

异步多语言单元测试。

简介

Vert.x Unit 旨在编写异步单元测试,提供多语言API,并在 JVM 中运行这些测试。Vert.x Unit API 借鉴了现有测试框架(如 JUnitQUnit)的经验,并遵循 Vert.x 的实践。

因此,Vert.x Unit 是测试 Vert.x 应用程序的自然选择。

要使用 Vert.x Unit,请将以下依赖项添加到构建描述符的 dependencies 部分

  • Maven(在您的 pom.xml 中)

<dependency>
  <groupId>io.vertx</groupId>
  <artifactId>vertx-unit</artifactId>
  <version>5.0.1</version>
  <scope>test</scope>
</dependency>
  • Gradle(在您的 build.gradle 文件中)

testCompile ${io.vertx}:${vertx-unit}:5.0.1

Vert.x Unit 可以通过不同的方式使用,并在您的代码运行的任何地方运行,这只是以正确的方式报告结果的问题,本示例展示了最基本的测试套件

TestSuite suite = TestSuite.create("the_test_suite");
suite.test("my_test_case", context -> {
  String s = "value";
  context.assertEquals("value", s);
});
suite.run();

run 方法将执行套件并遍历套件中的所有测试。套件可以失败或通过,如果外部世界不知道测试结果,这并不重要。

执行后,测试套件现在将向控制台报告测试套件的步骤

Begin test suite the_test_suite
Begin test my_test
Passed my_test
End test suite the_test_suite , run: 1, Failures: 0, Errors: 0

reporters 选项配置了套件运行器用于报告测试执行情况的报告器,有关更多信息,请参阅报告部分。

编写测试套件

测试套件是测试用例的命名集合,测试用例是直接执行的回调。套件可以具有在测试用例或测试套件之前和/或之后执行的生命周期回调,这些回调用于初始化或处置测试套件使用的服务。

TestSuite suite = TestSuite.create("the_test_suite");
suite.test("my_test_case_1", context -> {
  // Test 1
});
suite.test("my_test_case_2", context -> {
  // Test 2
});
suite.test("my_test_case_3", context -> {
  // Test 3
});

API 是流畅的,因此测试用例可以链式调用

TestSuite suite = TestSuite.create("the_test_suite");
suite.test("my_test_case_1", context -> {
  // Test 1
}).test("my_test_case_2", context -> {
  // Test 2
}).test("my_test_case_3", context -> {
  // Test 3
});

不保证测试用例的声明顺序,因此测试用例不应依赖于其他测试用例的执行。这种做法被认为是不好的。

Vert.x Unit 提供 beforeafter 回调用于全局设置或清理

TestSuite suite = TestSuite.create("the_test_suite");
suite.before(context -> {
  // Test suite setup
}).test("my_test_case_1", context -> {
  // Test 1
}).test("my_test_case_2", context -> {
  // Test 2
}).test("my_test_case_3", context -> {
  // Test 3
}).after(context -> {
  // Test suite cleanup
});

方法的声明顺序不重要,示例在测试用例之前声明 before 回调,在测试用例之后声明 after 回调,但它可以在任何地方,只要在运行测试套件之前完成即可。

before 回调在任何测试之前执行,如果它失败,测试套件的执行将停止并报告失败。after 回调是测试套件执行的最后一个回调,除非 before 回调报告了失败。

同样,Vert.x Unit 提供了 beforeEachafterEach 回调,它们做同样的事情,但对每个测试用例执行

TestSuite suite = TestSuite.create("the_test_suite");
suite.beforeEach(context -> {
  // Test case setup
}).test("my_test_case_1", context -> {
  // Test 1
}).test("my_test_case_2", context -> {
  // Test 2
}).test("my_test_case_3", context -> {
  // Test 3
}).afterEach(context -> {
  // Test case cleanup
});

beforeEach 回调在每个测试用例之前执行,如果它失败,则不执行测试用例并报告失败。afterEach 回调在测试用例回调之后立即执行,除非 beforeEach 回调报告了失败。

断言

Vert.x Unit 提供了 TestContext 对象用于在测试用例中进行断言。context 对象提供了处理断言时常用的方法。

assertEquals

断言两个对象相等,适用于 basic 类型或 json 类型。

suite.test("my_test_case", context -> {
  context.assertEquals(10, callbackCount);
});

还有一个重载版本,用于提供消息

suite.test("my_test_case", context -> {
  context.assertEquals(10, callbackCount, "Should have been 10 instead of " + callbackCount);
});

通常,每个断言都提供一个重载版本。

assertNotEquals

assertEquals 的对应部分。

suite.test("my_test_case", context -> {
  context.assertNotEquals(10, callbackCount);
});

assertNull

断言对象为 null,适用于 basic 类型或 json 类型。

suite.test("my_test_case", context -> {
  context.assertNull(null);
});

assertNotNull

assertNull 的对应部分。

suite.test("my_test_case", context -> {
  context.assertNotNull("not null!");
});

assertInRange

assertInRange 针对实数。

suite.test("my_test_case", context -> {

  // Assert that 0.1 is equals to 0.2 +/- 0.5

  context.assertInRange(0.1, 0.2, 0.5);
});

assertTrue 和 assertFalse

断言布尔表达式的值。

suite.test("my_test_case", context -> {
  context.assertTrue(var);
  context.assertFalse(value > 10);
});

失败

最后但同样重要的是,test 提供了一个 fail 方法,它将抛出断言错误

suite.test("my_test_case", context -> {
  context.fail("That should never happen");
  // Following statements won't be executed
});

失败可以是之前看到的 string,也可以是 errorerror 对象取决于目标语言,对于 Java 或 Groovy,它可以是任何扩展 `Throwable` 的类,对于 JavaScript 是一个 error,对于 Ruby 是一个 Exception

使用第三方断言框架

也可以使用任何其他断言框架,如流行的 hamcrestassertj。推荐的方法是使用 verify 并在提供的 Handler 中执行断言。通过这种方式,异步测试的终止将得到正确处理。

suite.test("my_test_case", context -> context.verify(v -> {
  // Using here Assert from junit, could be assertj, hamcrest or any other
  // Even manually throwing an AssertionError.
  Assert.assertNotNull("not null!");
  Assert.assertEquals(10, callbackCount);
}));

异步测试

前面的示例假设测试用例在其各自的回调之后终止,这是测试用例回调的默认行为。通常,希望在测试用例回调之后终止测试,例如

Async 对象异步完成测试用例
suite.test("my_test_case", context -> {
  Async async = context.async();
  eventBus.consumer("the-address", msg -> {
    (2)
    async.complete();
  });
  (1)
});
1 回调退出但测试用例未终止
2 总线发出的事件回调终止测试

使用 async 方法创建 Async 对象会将执行的测试用例标记为未终止。当调用 complete 方法时,测试用例终止。

如果未调用 complete 回调,则测试用例会在一定超时后失败。

在同一个测试用例中可以创建多个 Async 对象,所有这些对象都必须“完成”才能终止测试。

多个 Async 对象提供协调
suite.test("my_test_case", context -> {

  HttpClient client = vertx.createHttpClient();
  client.request(HttpMethod.GET, 8080, "localhost", "/").onComplete(context.asyncAssertSuccess(req -> {
      req.send().onComplete(context.asyncAssertSuccess(resp -> {
        context.assertEquals(200, resp.statusCode());
      }));
    }));

  Async async = context.async();
  vertx.eventBus().consumer("the-address", msg -> {
    async.complete();
  });
});

Async 对象也可以在 beforeafter 回调中使用,在 before 回调中实现依赖于一个或多个异步结果的设置可能非常方便

Async 在测试用例之前启动 HTTP 服务器
suite.before(context -> {
  Async async = context.async();
  HttpServer server = vertx.createHttpServer();
  server.requestHandler(requestHandler);
  server.listen(8080).onComplete(ar -> {
    context.assertTrue(ar.succeeded());
    async.complete();
  });
});

可以等待特定 Async 的完成,类似于 Java 的倒计时锁存器

等待完成
Async async = context.async();
HttpServer server = vertx.createHttpServer();
server.requestHandler(requestHandler);
server.listen(8080).onComplete(ar -> {
  context.assertTrue(ar.succeeded());
  async.complete();
});

// Wait until completion
async.awaitSuccess();
这不应该从事件循环中执行!

Async 也可以使用初始计数值创建,当倒计时通过 countDown 达到零时完成

等待直到完整倒计时达到零
Async async = context.async(2);
HttpServer server = vertx.createHttpServer();
server.requestHandler(requestHandler);
server.listen(8080).onComplete(ar -> {
  context.assertTrue(ar.succeeded());
  async.countDown();
});

vertx.setTimer(1000, id -> {
  async.complete();
});

// Wait until completion of the timer and the http request
async.awaitSuccess();

在 `async` 上调用 `complete()` 会像往常一样完成异步操作,它实际上将值设置为 `0`。

异步断言

TestContext 提供了有用的方法,为异步测试提供了强大的结构

asyncAssertSuccess 方法返回一个 Handler<AsyncResult<T>> 实例,其行为类似于 Async,在成功时解析 Async,在失败时使测试失败并报告失败原因。

Async async = context.async();
vertx.deployVerticle("my.verticle").onComplete(ar -> {
  if (ar.succeeded()) {
    async.complete();
  } else {
    context.fail(ar.cause());
  }
});

// Can be replaced by

vertx.deployVerticle("my.verticle").onComplete(context.asyncAssertSuccess());

asyncAssertSuccess 方法返回一个 Handler<AsyncResult<T>> 实例,其行为类似于 Async,在成功时调用委托的 Handler<T>,在失败时使测试失败并报告失败原因。

AtomicBoolean started = new AtomicBoolean();
Async async = context.async();
vertx.deployVerticle(new AbstractVerticle() {
  public void start() throws Exception {
    started.set(true);
  }
}).onComplete(ar -> {
  if (ar.succeeded()) {
    context.assertTrue(started.get());
    async.complete();
  } else {
    context.fail(ar.cause());
  }
});

// Can be replaced by

vertx.deployVerticle("my.verticle").onComplete(context.asyncAssertSuccess(id -> {
  context.assertTrue(started.get());
}));

Handler 退出时,异步操作完成,除非在调用期间创建了新的异步操作,这对于链式异步行为可能很方便

Async async = context.async();
vertx.deployVerticle("my.verticle").onComplete(ar1 -> {
  if (ar1.succeeded()) {
    vertx.deployVerticle("my.otherverticle").onComplete(ar2 -> {
      if (ar2.succeeded()) {
        async.complete();
      } else {
        context.fail(ar2.cause());
      }
    });
  } else {
    context.fail(ar1.cause());
  }
});

// Can be replaced by

vertx.deployVerticle("my.verticle").onComplete(context.asyncAssertSuccess(id ->
        vertx.deployVerticle("my_otherverticle").onComplete(context.asyncAssertSuccess())
));

asyncAssertFailure 方法返回一个 Handler<AsyncResult<T>> 实例,其行为类似于 Async,在失败时解析 Async,在成功时使测试失败。

Async async = context.async();
vertx.deployVerticle("my.verticle").onComplete(ar -> {
  if (ar.succeeded()) {
    context.fail();
  } else {
    async.complete();
  }
});

// Can be replaced by

vertx.deployVerticle("my.verticle").onComplete(context.asyncAssertFailure());

asyncAssertFailure 方法返回一个 Handler<AsyncResult<T>> 实例,其行为类似于 Async,在失败时调用委托的 Handler<Throwable>,在成功时使测试失败。

Async async = context.async();
vertx.deployVerticle("my.verticle").onComplete(ar -> {
  if (ar.succeeded()) {
    context.fail();
  } else {
    context.assertTrue(ar.cause() instanceof IllegalArgumentException);
    async.complete();
  }
});

// Can be replaced by

vertx.deployVerticle("my.verticle").onComplete(context.asyncAssertFailure(cause -> {
  context.assertTrue(cause instanceof IllegalArgumentException);
}));

Handler 退出时,异步操作完成,除非在调用期间创建了新的异步操作。

重复测试

当测试随机或不经常失败时(例如竞态条件),多次运行相同的测试以增加测试失败的可能性会很方便。

重复测试
TestSuite.create("my_suite").test("my_test", 1000, context -> {
  // This will be executed 1000 times
});

声明后,beforeEachafterEach 回调将与测试执行的次数一样多次执行。

测试重复是顺序执行的

共享对象

TestContext 具有 get/put/remove 操作,用于在回调之间共享状态。

before 回调期间添加的任何对象都可以在任何其他回调中使用。每个测试用例都将操作共享状态的副本,因此更新将仅对一个测试用例可见。

在回调之间共享状态
TestSuite.create("my_suite").before(context -> {

  // host is available for all test cases
  context.put("host", "localhost");

}).beforeEach(context -> {

  // Generate a random port for each test
  int port = helper.randomPort();

  // Get host
  String host = context.get("host");

  // Setup server
  Async async = context.async();
  HttpServer server = vertx.createHttpServer();
  server.requestHandler(req -> {
    req.response().setStatusCode(200).end();
  });
  server.listen(port, host).onComplete(ar -> {
    context.assertTrue(ar.succeeded());
    context.put("port", port);
    async.complete();
  });

}).test("my_test", context -> {

  // Get the shared state
  int port = context.get("port");
  String host = context.get("host");

  // Do request
  HttpClient client = vertx.createHttpClient();
  client.request(HttpMethod.GET, port, host, "/resource").onComplete(context.asyncAssertSuccess(req -> {
    req.send().onComplete(context.asyncAssertSuccess(resp -> {
      context.assertEquals(200, resp.statusCode());
    }));
  }));
});
共享任何对象仅在 Java 中受支持,其他语言只能共享基本类型或 JSON 类型。其他对象应使用该语言的特性进行共享。

运行

创建测试套件后,它不会执行,直到调用 run 方法。

运行测试套件
suite.run();

测试套件也可以使用指定的 Vertx 实例运行

提供一个 Vert.x 实例来运行测试套件
suite.run(vertx);

当使用 Vertx 实例运行时,测试套件使用 Vert.x 事件循环执行,有关更多详细信息,请参阅事件循环部分。

可以在同一个 verticle 中执行多个测试套件,Vert.x Unit 会等待所有执行的套件完成。

测试套件完成

无法假设测试套件何时完成,如果需要在测试套件之后执行某些代码,则应将其放在测试套件的 after 回调中或作为 Completion 的回调

测试套件执行回调
TestCompletion completion = suite.run(vertx);

// Simple completion callback
completion.handler(ar -> {
  if (ar.succeeded()) {
    System.out.println("Test suite passed!");
  } else {
    System.out.println("Test suite failed:");
    ar.cause().printStackTrace();
  }
});

Completion 对象还提供了一个 resolve 方法,该方法接受一个 Promise 对象,此 Promise 将收到测试套件执行的通知

使用测试套件解析启动 Promise
TestCompletion completion = suite.run();

// When the suite completes, the promise is resolved
completion.resolve(startPromise);

这使得可以轻松创建一个测试 verticle,其部署就是测试套件的执行,从而使部署它的代码能够轻松了解成功或失败。

completion 对象也可以像一个锁存器一样使用,以阻塞直到测试套件完成。当运行测试套件的线程与当前线程不同时,应使用此方法

阻塞直到测试套件完成
Completion completion = suite.run();

// Wait until the test suite completes
completion.await();

当线程被中断或触发超时时,await 会抛出异常。

awaitSuccess 是一个变体,当测试套件失败时会抛出异常。

阻塞直到测试套件成功
Completion completion = suite.run();

// Wait until the test suite succeeds otherwise throw an exception
completion.awaitSuccess();

超时

测试套件的每个测试用例必须在达到特定超时之前执行。默认超时为 2 分钟,可以使用 test options 进行更改

设置测试套件超时
TestOptions options = new TestOptions().setTimeout(10000);

// Run with a 10 seconds time out
suite.run(options);

事件循环

Vert.x Unit 的执行是一个待执行任务列表,每个任务的执行都由前一个任务的完成驱动。这些任务应尽可能利用 Vert.x 事件循环,但这取决于当前的执行上下文(即测试套件是在 main 中执行还是嵌入在 Verticle 中)以及是否配置了 Vertx 实例。

setUseEventLoop 配置事件循环的使用

表 1. 事件循环使用情况
useEventLoop:null useEventLoop:true useEventLoop:false

Vertx 实例

使用 Vert.x 事件循环

使用 Vert.x 事件循环

强制不使用事件循环

Verticle

使用当前事件循环

使用当前事件循环

强制不使用事件循环

main

不使用事件循环

抛出错误

不使用事件循环

默认的 useEventLoop 值为 null,这意味着它在可能的情况下将使用事件循环,并在没有可用事件循环时回退到不使用事件循环。

报告

报告是测试套件的重要组成部分,Vert.x Unit 可以配置为使用不同类型的报告器运行。

默认情况下未配置报告器,运行测试套件时,test options 可以提供来配置一个或多个

使用控制台报告器和 JUnit XML 文件
ReportOptions consoleReport = new ReportOptions().
    setTo("console");

// Report junit files to the current directory
ReportOptions junitReport = new ReportOptions().
    setTo("file:.").
    setFormat("junit");

suite.run(new TestOptions().
        addReporter(consoleReport).
        addReporter(junitReport)
);

控制台报告

报告到 JVM 的 System.outSystem.err

控制台

格式

simplejunit

文件报告

报告到文件,必须提供一个 Vertx 实例

file : 目录名

格式

simplejunit

示例

file:.

文件报告器将在配置的目录中创建文件,文件将根据执行的测试套件名称和格式命名(即 simple 创建 txt 文件,junit 创建 xml 文件)。

日志报告

报告到日志记录器,必须提供一个 Vertx 实例

log : 日志记录器名称

示例

log:mylogger

事件总线报告

报告事件到事件总线,必须提供一个 Vertx 实例

bus : 事件总线地址

示例

bus:the-address

它允许将测试套件的执行与报告解耦。

通过事件总线发送的消息可以通过 EventBusCollector 收集,并实现自定义报告

EventBusCollector collector = EventBusCollector.create(
    vertx,
    new ReportingOptions().addReporter(
        new ReportOptions().setTo("file:report.xml").setFormat("junit")));

collector.register("the-address");

Vert.x 集成

默认情况下,断言和失败必须在 TestContext 上完成,并且抛出断言错误仅在 Vert.x Unit 调用时有效

suite.test("my_test_case", ctx -> {

  // The failure will be reported by Vert.x Unit
  throw new RuntimeException("it failed!");
});

在常规的 Vert.x 回调中,失败将被忽略

suite.test("test-server", testContext -> {
  HttpServer server = vertx.createHttpServer().requestHandler(req -> {
    if (req.path().equals("/somepath")) {
      throw new AssertionError("Wrong path!");
    }
    req.response().end();
  });
});

自 Vert.x 3.3 起,可以设置一个全局异常处理器来报告事件循环中未捕获的异常

suite.before(testContext -> {

  // Report uncaught exceptions as Vert.x Unit failures
  vertx.exceptionHandler(testContext.exceptionHandler());
});

suite.test("test-server", testContext -> {
  HttpServer server = vertx.createHttpServer().requestHandler(req -> {
    if (req.path().equals("/somepath")) {
      throw new AssertionError("Wrong path!");
    }
    req.response().end();
  });
});

异常处理器在 before 阶段设置,TestContext 在每个 beforetestafter 阶段之间共享。因此,在 before 阶段获得的异常处理器是正确的。

JUnit 集成

尽管 Vert.x Unit 是多语言的且不基于 JUnit,但可以从 JUnit 运行 Vert.x Unit 测试套件或测试用例,从而允许您将测试与 JUnit 以及您的构建系统或 IDE 集成。

将 Java 类作为 JUnit 测试套件运行
@RunWith(VertxUnitRunner.class)
public class JUnitTestSuite {
  @Test
  public void testSomething(TestContext context) {
    context.assertFalse(false);
  }
}

VertxUnitRunner 使用 JUnit 注解来内省类并在类之后创建测试套件。方法应该声明一个 TestContext 参数,如果不声明也可以。然而,TestContext 是检索关联的 Vert.x 实例或执行异步测试的唯一方法。

JUnit 集成也适用于 Groovy 语言,使用 io.vertx.groovy.ext.unit.junit.VertxUnitRunner 运行器。

在 Vert.x 上下文中运行测试

默认情况下,调用测试方法的线程是 JUnit 线程。RunTestOnContext JUnit 规则可用于改变此行为,以便使用 Vert.x 事件循环线程运行这些测试方法。

因此,当测试方法和 Vert.x 处理器之间共享状态时必须小心,因为它们不会在同一个线程上运行,例如在 Vert.x 处理器中增加计数器并在测试方法中断言计数器。解决这个问题的一种方法是使用适当的同步,另一种方法是在 Vert.x 上下文中执行测试方法,该上下文将传播到创建的处理程序。

为此,RunTestOnContext 规则需要一个 Vertx 实例。可以提供此类实例,否则该规则将在内部管理一个实例。当测试运行时可以检索此类实例,这使得该规则也成为管理 Vertx 实例的一种方式。

将 Java 类作为 JUnit 测试套件运行
@RunWith(VertxUnitRunner.class)
public class RunOnContextJUnitTestSuite {

  @Rule
  public RunTestOnContext rule = new RunTestOnContext();

  @Test
  public void testSomething(TestContext context) {
    // Use the underlying vertx instance
    Vertx vertx = rule.vertx();
  }
}

该规则可以用 @Rule@ClassRule 注解,前者为每个测试管理一个 Vert.x 实例,后者为类的测试方法管理一个单一的 Vert.x 实例。

请记住,使用此规则时不能阻塞事件循环。使用 CountDownLatch 或类似类时必须小心。

超时

Vert.x Unit 的 2 分钟超时可以通过 @Test 注解的 timeout 成员覆盖

在测试级别配置超时
public class JunitTestWithTimeout {

  @Test(timeout = 1000l)
  public void testSomething(TestContext context) {
    //...
  }

}

对于更全局的配置,可以使用 Timeout 规则

在类级别配置超时
@RunWith(VertxUnitRunner.class)
public class TimeoutTestSuite {

  @Rule
  public Timeout rule = Timeout.seconds(1);

  @Test
  public void testSomething(TestContext context) {
    //...
  }
}
使用 io.vertx.ext.unit.junit.Timeout,而不是 org.junit.rules.Timeout

方法级别的超时会覆盖类级别的超时

将类级别规则与方法级别超时结合使用
@RunWith(VertxUnitRunner.class)
public class TimeoutOverwriteTestSuite {

  @Rule
  public Timeout rule = Timeout.millis(5_000L);

  @Test
  public void testQuick(TestContext context) {
    //...
  }

  @Test(timeout = 30_000L)
  public void testSlow(TestContext context) {
    //...
  }
}
@Test 超时会覆盖 io.vertx.ext.unit.junit.Timeout 规则,但不会覆盖 org.junit.rules.Timeout 规则。

参数化测试

JUnit 提供了有用的 Parameterized 测试,Vert.x Unit 测试可以通过 VertxUnitRunnerWithParametersFactory 这个特定的运行器运行

运行 Vert.x Unit 参数化测试
@RunWith(Parameterized.class)
@Parameterized.UseParametersRunnerFactory(VertxUnitRunnerWithParametersFactory.class)
public class SimpleParameterizedTest {

  @Parameterized.Parameters
  public static Iterable<Integer> data() {
    return Arrays.asList(0, 1, 2);
  }

  public SimpleParameterizedTest(int value) {
    //...
  }

  @Test
  public void testSomething(TestContext context) {
    // Execute test with the current value
  }
}

参数化测试也可以在 Groovy 中使用 io.vertx.groovy.ext.unit.junit.VertxUnitRunnerWithParametersFactory 完成。

重复测试

当测试随机或不经常失败时(例如竞态条件),多次运行相同的测试以增加测试失败的可能性会很方便。

使用 JUnit 时,测试必须用 @Repeat 注解才能重复执行。测试还必须在其规则中定义 RepeatRule

使用 JUnit 重复测试
@RunWith(VertxUnitRunner.class)
public class RepeatingTest {

  @Rule
  public RepeatRule rule = new RepeatRule();

  @Repeat(1000)
  @Test
  public void testSomething(TestContext context) {
    // This will be executed 1000 times
  }
}

声明后,beforeafter 生命周期将与测试执行的次数一样多次执行。

测试重复是顺序执行的

与其他断言库一起使用

Vert.x Unit 的可用性在 Vert.x 3.3 中得到了极大改进。您现在可以使用 HamcrestAssertJRest Assured 或任何您想要的断言库编写测试。这得益于Vert.x 集成中描述的全局异常处理器。

您可以在 vertx-examples 项目中找到使用 Vert.x Unit 和 Hamcrest、AssertJ 的 Java 示例。

Java 语言集成

测试套件集成

Java 语言提供了类,可以使用以下映射规则直接从 Java 类创建测试套件

testSuiteObject 参数方法被检查,带有 TestContext 参数的公共非静态方法被保留,并通过方法名称映射到 Vert.x Unit 测试套件

  • before : 前置回调

  • after : 后置回调

  • beforeEach : 每个测试前回调

  • afterEach : 每个测试后回调

  • 当名称以 test 开头时:根据方法名称命名的测试用例回调

使用 Java 类编写的测试套件
public class MyTestSuite {

  public void testSomething(TestContext context) {
    context.assertFalse(false);
  }
}

这个类可以很容易地转换为 Vert.x 测试套件

从 Java 对象创建测试套件
TestSuite suite = TestSuite.create(new MyTestSuite());