Last active
November 2, 2018 02:20
-
-
Save SeijiEmery/2a2812309c932a7c62f3d661a4185d39 to your computer and use it in GitHub Desktop.
Crappy, easy unittesting in java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class YourTestClass { | |
public static void main (String[] args) { | |
expect("my tests", () -> { | |
expect("test arithmetic", () -> { | |
assertEquals(2 + 2, 4); | |
assertNotEquals(2 + 2, 5); | |
}); | |
expect("test exceptions", () -> { | |
assertNoThrow(() -> { if (2 + 2 != 4) { throw new IllegalStateException("blarg!"); }); | |
assertThrows(() -> { if (2 + 2 != 5) { throw new IllegalStateException("blarg!"); }); | |
}); | |
}); | |
} | |
// "unittest" (any void function) interface - used as signature for lambdas | |
private interface Unittest { | |
void test (); | |
} | |
// Internal testing state. Kept in global linked list (shitty, but sufficient for simple testing) | |
private static class TestInfo { | |
private String description; | |
private TestInfo prev = null; | |
private static TestInfo instance = new TestInfo("main"); | |
private int passed = 0, failed = 0; | |
private int indent = 0; | |
// Constructor (called from expect()) | |
TestInfo (String description) { this.description = description; } | |
// Internal "println-with-indent" method | |
private void println (String msg) { | |
System.out.print("\033[33m"); | |
for (int i = 0; i < indent; ++i) { | |
System.out.print("| "); | |
} | |
System.out.print("\033[0m"); | |
System.out.println(msg); | |
} | |
// Enter this test state | |
void enter () { | |
indent = instance.indent; | |
println("\033[33mStarting test: "+description+"\033[0m"); | |
++indent; | |
prev = instance; instance = this; | |
} | |
// Exit this test state | |
void exit () { | |
instance = prev; prev = null; | |
if (failed == 0) { | |
logSuccess("Finished test: "+passed+" / "+(passed+failed)+" test(s) passed"); | |
} else { | |
logFailure("Finished test: "+passed+" / "+(passed+failed)+" test(s) passed"); | |
} | |
} | |
// Log test / assert success (on the current test instance) | |
public static void logSuccess (String msg) { instance.println("\033[32mPASSED: "+msg+"\033[0m"); ++instance.passed; } | |
// Log test / assert failure (on the current test instance) | |
public static void logFailure (String msg) { instance.println("\033[31mFAILED: "+msg+"\033[0m"); ++instance.failed; } | |
public static void logMessage (String msg) { instance.println("\033[33m"+msg+"\033[0m"); } | |
} | |
// Basic building block for nested tests. | |
// @param what: description of the test | |
// @param unittest: a lambda / block of code to execute | |
private static void expect (String what, Unittest unittest) { | |
TestInfo testInfo = new TestInfo(what); | |
testInfo.enter(); | |
unittest.test(); | |
testInfo.exit(); | |
} | |
// Test that two things (ints) are equal. | |
// TODO: add versions for additional types and comparisons (as needed) | |
private static void assertEquals (int a, int b) { | |
if (a == b) TestInfo.logSuccess(""+a+" == "+b); | |
else TestInfo.logFailure(""+a+" == "+b); | |
} | |
private static void assertEquals (boolean a, boolean b) { | |
if (a == b) TestInfo.logSuccess(""+a+" == "+b); | |
else TestInfo.logFailure(""+a+" == "+b); | |
} | |
private static <T> void assertEquals (T a, T b) { | |
if (a.equals(b)) TestInfo.logSuccess(""+a+" == "+b); | |
else TestInfo.logFailure(""+a+" == "+b); | |
} | |
private static <T> void assertNotEquals (T a, T b) { | |
if (!a.equals(b)) TestInfo.logSuccess(""+a+" == "+b); | |
else TestInfo.logFailure(""+a+" == "+b); | |
} | |
// Testcase that requires the code in the inner lambda to throw an exception (any exception) | |
private static void assertThrows (Unittest unittest) { | |
try { | |
unittest.test(); | |
} catch (Throwable e) { | |
TestInfo.logSuccess("expected exception, got "+e); return; | |
} TestInfo.logFailure("expected exception"); | |
} | |
// Testcase that requires the code in the inner lambda to NOT throw any exception | |
private static void assertNoThrow (Unittest unittest) { | |
try { | |
unittest.test(); | |
} catch (Throwable e) { | |
TestInfo.logFailure("unexpected exception: "+e); return; | |
} TestInfo.logSuccess("no exception thrown"); | |
} | |
// Basic, non-informative testcase | |
private static void assertThat (boolean expected) { | |
if (expected) { TestInfo.logSuccess("succeeded"); } | |
else { TestInfo.logFailure("failed"); } | |
} | |
private static void ignoreAsserts (Unittest unittest) { | |
try { | |
unittest.test(); | |
} catch (AssertionError e) { | |
TestInfo.logMessage("got assert: "+e); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment