Skip to content
Permalink
Browse files

Junit4 @Before/After Class support (#447)

  • Loading branch information...
MykolaGolubyev committed Oct 27, 2019
1 parent 7c14045 commit 03e2a54752be2c2ada528f04941423142a3786fb
@@ -308,6 +308,12 @@
<version>3.21.0-GA</version>
</dependency>

<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.18</version>
</dependency>

<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
@@ -17,6 +17,15 @@ Groovy: :include-file: com/example/tests/junit4/CustomerCrudBeforeAfterGroovyTes
Java: :include-file: com/example/tests/junit4/CustomerCrudBeforeAfterJavaTest.java {title: "CRUD test with @Before and @After annotations", commentsType: "inline"}
```

# BeforeClass/AfterClass

Use `@BeforeClass` and `@AfterClass` to prepare and cleanup resources required for multiple test methods.

```tabs
Groovy: :include-file: com/example/tests/junit4/CustomerQueryGroovyTest.groovy {commentsType: "inline"}
Java: :include-file: com/example/tests/junit4/CustomerQueryJavaTest.java {commentsType: "inline"}
```

# Maven Import

:include-file: maven/junit4-dep.xml
@@ -31,6 +31,7 @@
<groupId>com.twosigma.webtau</groupId>
<artifactId>webtau-groovy</artifactId>
<version>${project.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
@@ -53,24 +54,6 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.twosigma.webtau</groupId>
<artifactId>webtau-http</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>com.twosigma.webtau</groupId>
<artifactId>webtau-http-groovy</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>com.twosigma.webtau</groupId>
<artifactId>webtau-testapp</artifactId>
@@ -0,0 +1,52 @@
package com.example.tests.junit4

import com.twosigma.webtau.junit4.WebTauRunner
import org.junit.AfterClass
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith

import static com.twosigma.webtau.WebTauDsl.http

@RunWith(WebTauRunner.class)
class CustomerQueryGroovyTest {
private static def id1 // keep track of created ids to assert and cleanup later
private static def id2
private static def id3

@BeforeClass
static void createCustomers() {
id1 = createCustomer("CQ_FN1", "CQ_LN1")
id2 = createCustomer("CQ_FN1", "CQ_LN2")
id3 = createCustomer("CQ_FN2", "CQ_LN2")
}

@Test
void queryByFirstName() {
http.get("/customers/search/first-name", [name: "CQ_FN1"]) {
_embedded.customers.should == ["*id" | "firstName" | "lastName"] { // star(*) marks key column so assertion is order agnostic
__________________________________
id1 | "CQ_FN1" | "CQ_LN1"
id2 | "CQ_FN1" | "CQ_LN2" }
}
}

@Test
void queryByLastName() {
http.get("/customers/search/last-name", [name: "CQ_LN2"]) {
_embedded.customers.should == ["*id" | "firstName" | "lastName"] {
__________________________________
id2 | "CQ_FN1" | "CQ_LN2"
id3 | "CQ_FN2" | "CQ_LN2" }
}
}

@AfterClass
static void cleanup() {
[id1, id2, id3].each { http.delete("/customers/$it") }
}

private static def createCustomer(String firstName, String lastName) {
return http.post("/customers", [firstName: firstName, lastName: lastName]) { id }
}
}
@@ -0,0 +1,61 @@
package com.example.tests.junit4;

import com.twosigma.webtau.junit4.WebTauRunner;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.Map;
import java.util.stream.Stream;

import static com.twosigma.webtau.WebTauDsl.*;

@RunWith(WebTauRunner.class)
public class CustomerQueryJavaTest {
private static Integer id1; // keep track of created ids to assert and cleanup later
private static Integer id2;
private static Integer id3;

@BeforeClass
public static void createCustomers() {
id1 = createCustomer("CQ_FN1", "CQ_LN1");
id2 = createCustomer("CQ_FN1", "CQ_LN2");
id3 = createCustomer("CQ_FN2", "CQ_LN2");
}

@Test
public void queryByFirstName() {
http.get("/customers/search/first-name", http.query("name", "CQ_FN1"), (header, body) -> {
body.get("_embedded.customers").should(equal(table("*id", "firstName", "lastName", // star(*) marks key column so assertion is order agnostic
________________________________,
id1, "CQ_FN1" , "CQ_LN1",
id2, "CQ_FN1" , "CQ_LN2")));
});
}

@Test
public void queryByLastName() {
http.get("/customers/search/last-name", http.query("name", "CQ_LN2"), (header, body) -> {
body.get("_embedded.customers").should(equal(table("*id", "firstName", "lastName",
________________________________,
id2, "CQ_FN1" , "CQ_LN2",
id3, "CQ_FN2" , "CQ_LN2")));
});
}

@AfterClass
public static void cleanup() {
Stream.of(id1, id2, id3).forEach(id -> http.delete("/customers/" + id));
}

private static int createCustomer(String firstName, String lastName) {
Map<String, Object> payload = aMapOf(
"firstName", firstName,
"lastName", lastName);

return http.post("/customers", payload, ((header, body) -> {
return body.get("id");
}));
}
}
@@ -22,14 +22,22 @@
import com.twosigma.webtau.report.ReportTestEntry;
import com.twosigma.webtau.reporter.StepReporters;
import com.twosigma.webtau.reporter.TestResultPayloadExtractors;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.internal.runners.statements.RunAfters;
import org.junit.internal.runners.statements.RunBefores;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;

import java.lang.reflect.Method;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

public class WebTauRunner extends BlockJUnit4ClassRunner {
private static final AtomicInteger idGenerator = new AtomicInteger();
@@ -39,13 +47,25 @@ public WebTauRunner(Class<?> klass) throws InitializationError {
}

@Override
protected void runChild(FrameworkMethod method, RunNotifier notifier) {
JavaBasedTest javaBasedTest = new JavaBasedTest(
method.getName() + idGenerator.incrementAndGet(),
method.getName());
protected Statement withBeforeClasses(Statement statement) {
List<FrameworkMethod> befores = wrapInWebTauTestEntry(getTestClass()
.getAnnotatedMethods(BeforeClass.class));
return befores.isEmpty() ? statement :
new RunBefores(statement, befores, null);
}

@Override
protected Statement withAfterClasses(Statement statement) {
List<FrameworkMethod> afters = wrapInWebTauTestEntry(getTestClass()
.getAnnotatedMethods(AfterClass.class));
return afters.isEmpty() ? statement :
new RunAfters(statement, afters, null);
}

@Override
protected void runChild(FrameworkMethod method, RunNotifier notifier) {
JavaBasedTest javaBasedTest = createJavaBasedTest(method);
ReportTestEntry reportTestEntry = javaBasedTest.getReportTestEntry();
reportTestEntry.setClassName(method.getDeclaringClass().getCanonicalName());

notifier.addListener(new RunListener() {
@Override
@@ -65,6 +85,14 @@ public void testFailure(Failure failure) {
}
}

private List<FrameworkMethod> wrapInWebTauTestEntry(List<FrameworkMethod> annotatedMethods) {
return annotatedMethods.stream().map(this::wrapInWebTauTestEntry).collect(Collectors.toList());
}

private FrameworkMethod wrapInWebTauTestEntry(FrameworkMethod annotatedMethod) {
return new WrappedFrameworkMethod(annotatedMethod);
}

private void beforeTestRun(JavaBasedTest javaBasedTest) {
javaBasedTest.getReportTestEntry().startClock();
StepReporters.add(javaBasedTest);
@@ -83,4 +111,39 @@ private void afterTestRun(JavaBasedTest javaBasedTest) {

JavaReportShutdownHook.INSTANCE.noOp();
}

private JavaBasedTest createJavaBasedTest(FrameworkMethod method) {
JavaBasedTest javaBasedTest = new JavaBasedTest(
method.getName() + idGenerator.incrementAndGet(),
method.getName());

ReportTestEntry reportTestEntry = javaBasedTest.getReportTestEntry();
reportTestEntry.setClassName(method.getDeclaringClass().getCanonicalName());

return javaBasedTest;
}

private class WrappedFrameworkMethod extends FrameworkMethod {
private final FrameworkMethod frameworkMethod;

WrappedFrameworkMethod(FrameworkMethod frameworkMethod) {
super(frameworkMethod.getMethod());
this.frameworkMethod = frameworkMethod;
}

@Override
public Object invokeExplosively(Object target, Object... params) throws Throwable {
JavaBasedTest javaBasedTest = createJavaBasedTest(frameworkMethod);

beforeTestRun(javaBasedTest);
try {
return super.invokeExplosively(target, params);
} catch (Throwable e) {
javaBasedTest.getReportTestEntry().setException(e);
throw e;
} finally {
afterTestRun(javaBasedTest);
}
}
}
}
@@ -27,7 +27,7 @@ class CustomerQueryGroovyTest {
@DisplayName("query by first name")
void queryByFirstName() {
http.get("/customers/search/first-name", [name: "CQ_FN1"]) {
_embedded.customers.should == ["*id" | "firstName" | "lastName"] { // sstar(*) marks key column so assertion is order agnostic
_embedded.customers.should == ["*id" | "firstName" | "lastName"] { // star(*) marks key column so assertion is order agnostic
__________________________________
id1 | "CQ_FN1" | "CQ_LN1"
id2 | "CQ_FN1" | "CQ_LN2" }

0 comments on commit 03e2a54

Please sign in to comment.
You can’t perform that action at this time.