Tagged: junit

Power Assert in Vim

Power Assert for Java and others

Peter Niederwieser, creator of Spock, the best testing framework ever, also contributed to Groovy programming language a very handy feature: Power Asserts.

int x = 1;
assert x == 2;

// Output:
//
// Assertion failed:
// assert x == 2
//        | |
//        1 false

As you can see, we can see each value of each statement, and this is very cool, especially for unit tests.
It makes all this JUnit bullshit like assertEquals(), assertTrue, assertNull, and all matchers like Hamcrest absolutely unneeded.
I really hate all matchers like FEST or Hamcest, because they aren’t natural and repeat code itself.

So now you can breathe freely without any repeating yourself.

You can see a talk where Peter Niederwieser present Spock specifications
https://vimeo.com/33947244

Also Peter created Power Asserts lib for Scala
https://github.com/pniederw/expecty

But,
Unfortunately, you can’t make a Power Asserts in Java, because it doesn’t have an AST preprocessor.
UPD Now we have the library https://github.com/jkschneider/java-power-assert but with limitations

If you, like me, have a big project with tests written in Java+JUnit, the only one way that I found, is convert them to Groovy (in 99% just change file extension from Java to Groovy) or you can compile your tests with groovyc — it’s Groovy Compiler but compiles Java too as well.
After compiling with groovyc asserts in Java behaves like in Groovy. Maybe this is the only one case when something written in Java works differently when compiled with Groovy.

For example here is simple test in Java

import org.junit.Test

class UserTest {
@Test
public void testName() {
String username = "olololo";
assert username.equals("trololo");
}

}

After compiling with groovyc it’s decompiled bytecode will looks like:

// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
import org.codehaus.groovy.runtime.callsite.CallSite;
import org.codehaus.groovy.runtime.powerassert.AssertionRenderer;
import org.codehaus.groovy.runtime.powerassert.ValueRecorder;
import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
import org.junit.Test;

public class UserTest implements GroovyObject {
public UserTestGroovy() {
CallSite[] var1 = $getCallSiteArray();
MetaClass var2 = this.$getStaticMetaClass();
this.metaClass = var2;
}

@Test
public void testName() {
CallSite[] var1 = $getCallSiteArray();
String username = "olololo";
ValueRecorder var3 = new ValueRecorder();

try {
CallSite var10000 = var1[0];
var3.record(username, 8);
Object var6 = var10000.call(username, "trololo");
var3.record(var6, 17);
if(DefaultTypeTransformation.booleanUnbox(var6)) {
var3.clear();
} else {
ScriptBytecodeAdapter.assertFailed(AssertionRenderer.render("assert username.equals(\"trololo\")", var3), (Object)null);
}

} catch (Throwable var5) {
var3.clear();
throw var5;
}
}
}

As you can see, it uses ValueRecorder to store all evaluated expressions and it will render a source code line. And it may be executed as class file (may require groovy-all dependency in classpath):

Assertion failed:

assert username.equals("trololo")
|        |
olololo  false

at org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:402)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.assertFailed(ScriptBytecodeAdapter.java:650)
at com.github.stokito.UserTest.testName(UserTest.java:9)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)

Unfortunately currently IntelliJ can’t compile Java files with Groovyc. It always compiles *.java files with javac.
I created an issue Allow groovyc as compiler for Java classes, please vote for it.

Power Asserts in other languages

Kotlin

does not exist but authors know about Power Assertions and had intentions to do them.

.NET languages

https://github.com/PowerAssert/PowerAssert.Net

JavaScript

https://github.com/power-assert-js/power-assert
https://github.com/power-assert-js/espower-typescript for TypeScript
https://github.com/power-assert-js/espower-babel
https://github.com/power-assert-js/babel-plugin-espower
https://github.com/twada/battlefield-sourcemaps
https://github.com/deepblue-will/coffee-power-assert for Cofee Script
https://github.com/twada/fly-espower

Ruby

There is a gem https://github.com/k-tsj/power_assert and here is presentation from author:
https://speakerdeck.com/k_tsj/power-assert-in-ruby

https://github.com/joker1007/rspec-power_assert
https://rubygems.org/gems/power_assert/versions/0.2.4
https://github.com/hsbt/minitest-power_assert
https://github.com/yui-knk/pry-power_assert for Pry REPL

Others

https://github.com/keygx/PAssert XCTest for Swift
https://github.com/rosylilly/power_assert.cr for Crystal (static Ruby)
https://github.com/ma2gedev/power_assert_ex for Elixir
https://github.com/gifnksm/power-assert-rs for Rust
https://github.com/haya14busa/vital-power-assert for Vim script
https://github.com/ToQoz/gopwt for Go

TODO: write about power assets in https://en.wikipedia.org/wiki/Assertion_(software_development)

Реклама