A colorful BDD-style test runner for Java
Spectrum is inspired by the behavior-driven testing frameworks Jasmine, Kiwi, and RSpec, bringing their expressive syntax and functional style to Java tests. It is a custom runner for JUnit, so it works with many development and reporting tools out of the box.
see also ExampleSpec.java
@RunWith(Spectrum.class)
public class ExampleSpec {{
describe("A spec", () -> {
final int foo = 1;
it("is just a code block with a run() method", new Block() {
@Override
public void run() throws Throwable {
assertEquals(1, foo);
}
});
it("can also be a lambda function, which is a lot prettier", () -> {
assertEquals(1, foo);
});
it("can use any assertion library you like", () -> {
org.junit.Assert.assertEquals(1, foo);
org.hamcrest.MatcherAssert.assertThat(true, is(true));
});
describe("nested inside a second describe", () -> {
final int bar = 1;
it("can reference both scopes as needed", () -> {
assertThat(bar, is(equalTo(foo)));
});
});
it("can have `it`s and `describe`s in any order", () -> {
assertThat(foo, is(1));
});
});
describe("A spec using beforeEach and afterEach", () -> {
final List<String> items = new ArrayList<String>();
beforeEach(() -> {
items.add("foo");
});
beforeEach(() -> {
items.add("bar");
});
afterEach(() -> {
items.clear();
});
it("runs the beforeEach() blocks in order", () -> {
assertThat(items, contains("foo", "bar"));
items.add("bogus");
});
it("runs them before every test", () -> {
assertThat(items, contains("foo", "bar"));
items.add("bogus");
});
it("runs afterEach after every test", () -> {
assertThat(items, not(contains("bogus")));
});
describe("when nested", () -> {
beforeEach(() -> {
items.add("baz");
});
it("runs beforeEach and afterEach from inner and outer scopes", () -> {
assertThat(items, contains("foo", "bar", "baz"));
});
});
});
describe("The Value convenience wrapper", () -> {
final Value<Integer> counter = value(Integer.class);
beforeEach(() -> {
counter.value = 0;
});
beforeEach(() -> {
counter.value++;
});
it("lets you work around Java's requirement that closures only reference `final` variables", () -> {
counter.value++;
assertThat(counter.value, is(2));
});
it("can optionally have an initial value set", () -> {
final Value<String> name = value("Alice");
assertThat(name.value, is("Alice"));
});
it("has a null value if not specified", () -> {
final Value<String> name = value(String.class);
assertThat(name.value, is(nullValue()));
});
});
describe("A spec using beforeAll", () -> {
final List<Integer> numbers = new ArrayList<Integer>();
beforeAll(() -> {
numbers.add(1);
});
it("sets the initial state before any tests run", () -> {
assertThat(numbers, contains(1));
numbers.add(2);
});
describe("and afterAll", () -> {
afterAll(() -> {
numbers.clear();
});
it("does not reset anything between tests", () -> {
assertThat(numbers, contains(1, 2));
numbers.add(3);
});
it("so proceed with caution; this *will* leak shared state across tests", () -> {
assertThat(numbers, contains(1, 2, 3));
});
});
it("cleans up after running all tests in the describe block", () -> {
assertThat(numbers, is(empty()));
});
});
}}
Spectrum is available as a package on Bintray, so you'll need to add a Maven repository to your build config. Inclusion in JCenter (see #8) and Maven Central (see #12) will make this easier when those issues are resolved.
- JUnit 4
- Java 8
Add the Maven repository to build.gradle
:
repositories {
maven {
url "http://dl.bintray.com/greghaskins/maven"
}
}
Then add the Spectrum dependency for your tests:
dependencies {
...
testCompile group: 'com.greghaskins', name: 'spectrum', version: '0.4.4'
...
}
Add the bintray-greghaskins-maven
Maven repository to your pom.xml
:
<project ...>
<repositories>
<repository>
<id>bintray-greghaskins-maven</id>
<url>http://dl.bintray.com/greghaskins/maven</url>
</repository>
</repositories>
</project>
Then add Spectrum as a dependency with test
scope:
<project ...>
<dependencies>
<dependency>
<groupId>com.greghaskins</groupId>
<artifactId>spectrum</artifactId>
<version>0.4.4</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>