Testing
JavaScript code, generated with TeaVM, can be tested in the browser by using JUnit. Currently only JUnit 4 supported (unfortunately, JUnit 5 does not provide necessary extension points for purposes of TeaVM). This requires some extra efforts.
First, you need to include library that extends JUnit. Gradle plugins do it automatically, for Maven you should add following dependency:
<dependency>
<groupId>org.teavm</groupId>
<artifactId>teavm-junit</artifactId>
<version>0.13.0</version>
<scope>test</scope>
</dependency>
Second, you should put @RunWith(TeaVMTestRunner.class)
If for some reason you want each test method to be compiled in a separate VM, you may also annotate class with
@EachTestCompiledSeparately. This can be necessary if you are testing custom TeaVM plugins or using
metaprogramming API.
Example:
@RunWith(TeaVMTestRunner.class)
public class SimpleTest {
@Test
public void simpleFields() {
var x = 2;
var y = 3;
assertEquals(5, x + y);
}
}
You can additionally put @JvmSkip annotation on class or on individual methods if you want
tests run only in JS (or other TeaVM target).
In multi-platform project you can additionally ignore tests (either single methods of whole classes)
with @SkipPlatform. There's also opposite @OnlyPlatform which enumerates only platforms
that are supported by test.
Finally, you need to specify additional system properties to JUnit runner. For maven include following configuration:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<systemProperties>
<teavm.junit.target>${project.build.directory}/js-tests</teavm.junit.target>
<teavm.junit.js.runner>browser-chrome</teavm.junit.js.runner>
</systemProperties>
</configuration>
</plugin>
</plugins>
For Gradle, use TeaVM DSL:
teavm.tests.js {
enabled = true
runner = TeaVMWebTestRunner.CHROME
}
Configuring runner using system properties
Here is the list of available system properties:
-
teavm.junit.target– target directory where test files will be generated. -
teavm.junit.js– whether JS target is enabled (trueorfalse). JS target is enabled by default. -
teavm.junit.js.runner– how to run JS tests. Available values:browser,browser-chrome,browser-firefox,none. None means that only JavaScript files will be generated without attempt to run them.browservalue will print link to stdout, that you should open in a browser. -
teavm.junit.js.decodeStack– controls stack trace deobfuscation (trueorfalse). Can slow down test runner. -
teavm.junit.wasm– whether WebAssembly target is enabled (trueorfalse). -
teavm.junit.wasm.runner– how to run WebAssembly tests. Same asteavm.junit.js.runner, except forhtmlunitvalue is not supported. -
teavm.junit.c– whether C target is enabled (trueorfalse). -
teavm.junit.c.compiler– command that compiles C to native code. This is usually path to a shell file that takesall.cfile in working directory and producesrun_testsbinary from it. For example:export LC_ALL=C SOURCE_DIR=$(pwd) gcc -g -O0 -lrt -lm all.c -o run_testAnother way to write such runner is to run cmake in working directory:
SOURCE_DIR=$(pwd) BUILD_DIR=$SOURCE_DIR/build mkdir -p $BUILD_DIR pushd $BUILD_DIR >/dev/null && \ cmake -S $SOURCE_DIR -B . >/dev/null && \ make --quiet >/dev/null && \ popd >/dev/null && \ rm -rf $BUILD_DIR -
teavm.junit.wasi– whether WebAssembly (WASI) target is enabled (trueorfalse). -
teavm.junit.wasi.runner– command that executes WebAssembly module in WASI environment. This is usually a shell file that takes two arguments: path to*.wasmfile and one string command line argument to this file. For example:~/.wasmtime/bin/wasmtime run --mapdir /::target/wasi-testdir $1 $2
Configuring runner using Gradle DSL
teavm.tests.js and test.tests.wasm objects have the following properties:
enabled: Boolean– enable corresponding target.runner: TeaVMWebTestRunner– use corresponding runner.
Also, teavm.tests.js provides decodeStack boolean property to enable stack trace deobfuscation.