/alchemy-test

Java Unit Test Drugs

Primary LanguageJavaApache License 2.0Apache-2.0

Alchemy Test

"Testing your code should be as fun and simple as writing it."

Build Status Maven Central Version

Purpose

We write so many tests in our day; it should be easier. Part of the Alchemy Collection, Alchemy Test is a Unit Test Library that makes it easier to test your code by providing syntactic sugar for unit-testing and mocking.

Download

To use, simply add the following maven dependency.

Release

<dependency>
	<groupId>tech.sirwellington.alchemy</groupId>
	<artifactId>alchemy-test</artifactId>
	<version>2.2.1</version>
</dependency>

Snapshot

First add the Snapshot Repository

<repository>
	<id>ossrh</id>
    <url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
<dependency>
	<groupId>tech.sirwellington.alchemy</groupId>
	<artifactId>alchemy-test</artifactId>
	<version>2.3-SNAPSHOT</version>
</dependency>

Javadocs

API

Throwable Assertions

In conjunction with JUnit, Throwable assertions make it really easy to write Exception Statements.

Instead of writing all this crap:

try
{
	instance.call("badArg");
	fail("Expected exception");
}
catch(IllegalArgumentException ex)
{
	//This means the test passed
}

You can now just do:

assertThrows(() -> instance.call("badArg"))
  .isInstanceOf(IllegalArgumentException.class); //Optional further assertion

Alchemy Test Runner

"Let's take some of the drudgery out of Unit Testing"

Free Print Statements

So often in tests we do this:

@Test
public void testSomeMethod()
{
	//Print out the test name at the beginning
	System.out.println("testSomeMethod");

	//Rest of the Test Case...
}

Who wants to write the same thing twice? It's especially troublesome when you decide to rename your test name, since you have to remember to update the print statement as well.

AlchemyTestRunner makes this automatic.

@RunWith(AlchemyTestRunner.class)
public class HttpTests
{
	@Test
	public void testReponse()
	{
		//Automatic
		//System.out.println("testResponse()");
		//FOR FREE
	}
}

Test Synopsis

We even tell you information about the test run:

testRequestReadyEdgeCases()
  Duration: 59ms
  Runs: 100

testValidContentType()
  Duration: 7ms
  Runs: 100

Automatic Data Generation

Used in conjunction with Alchemy Generator, Alchemy Unit Tests can now easily generate any Data they use

@RunWith(AlchemyTestRunnner.class)
public class ExampleTest
{
	@GenerateString
	private String name;

	@GenerateString(HEXADECIMAL)
	private String username;

	@GenerateInteger(POSITIVE)
	private int points;

    @GeneratePojo
    private User user;

    @GenerateList(String.class)
    private List<String> names;
	...
}

Supported Generators

  • @GenerateString
  • @GenerateInteger
  • @GenerateLong
  • @GenerateDouble
  • @GenerateDate
  • @GenerateInstant
  • @GenerateURL
  • @GeneratePojo
  • @GenerateEnum
  • @GenerateList

More on the way...

Repeat Tests

Used in conjunction with Automatic Data Generation, Repeat Tests can dramatically improve test quality.

@Repeat(1000)
@RunWith(AlchemyTestRunner.class)
public class StringEncryptorTests
{
	private String text;
	private StringEncryptor instance;

	@Before
	public void setup()
	{
		text = one(hexadecimalStrings(10));
		instance = new StringEncryptor();
	}

	@Test
	public void testDecrypt()
	{
		String result = instance.decrypt(text);
		//Blah checks
	}
}

You can also set the number of repeats on a case by case basis

@Repeat(100)
@RunWith(AlchemyTestRunner.class)
public class StringEncryptorTests
{
	private String text;
	private StringEncryptor instance;

	@Before
	public void setup()
	{
		text = one(alphabeticStrings(10));
		instance = new StringEncryptor();
	}

	//Repeat less often
	@Repeat(10)
	@Test
	public void testEncrypt()
	{
		String result = instance.encrypt(text);
		//Blah checks
	}
}

You can also use the @DontRepeat annotation to prevent a testCase from being repeated entirely.

@DontRepeat
@Test
public void testExecute()
{
	//Will run only once
}

Mockito Initialization

By default, we also init your Mockito Mocks for free

@RunWith(AlchemyTestRunner.class)
public class MyTest
{
	@Mock
	private AlchemyHttp http;

	@Mock
	private HttpResponse response;

	@Before
	private void setup()
	{
		//Mocks are already instantiated

		when(http.get())
		.thenReturn(response);
	}
}

If you want to disable this behavior, simply add:

@InitMocks(false)

to your test class.

Mockito Answers

Returning arguments back

// Return the first argument back when the mock is called
when(someMock)
	.call(anyString(), anyString())
	then(returnFirst());

//verify it works
String result = mock.call("arg1", "arg2");
assertThat(result, is("arg1"));

More coming soon...

Requirements

  • Java 8
  • Maven 3+

Building

This project builds with maven. Just run a mvn clean install to compile and install to your local maven repository.

Feature Requests

Feature Requests are definitely welcomed! Please drop a note in Issues.

License

This Software is licensed under the Apache 2.0 License

http://www.apache.org/licenses/LICENSE-2.0