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.11.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 (true
orfalse
). 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.browser
value will print link to stdout, that you should open in a browser. -
teavm.junit.js.decodeStack
– controls stack trace deobfuscation (true
orfalse
). Can slow down test runner. -
teavm.junit.wasm
– whether WebAssembly target is enabled (true
orfalse
). -
teavm.junit.wasm.runner
– how to run WebAssembly tests. Same asteavm.junit.js.runner
, except forhtmlunit
value is not supported. -
teavm.junit.c
– whether C target is enabled (true
orfalse
). -
teavm.junit.c.compiler
– command that compiles C to native code. This is usually path to a shell file that takesall.c
file in working directory and producesrun_tests
binary from it. For example:export LC_ALL=C SOURCE_DIR=$(pwd) gcc -g -O0 -lrt -lm all.c -o run_test
Another 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 (true
orfalse
). -
teavm.junit.wasi.runner
– command that executes WebAssembly module in WASI environment. This is usually a shell file that takes two arguments: path to*.wasm
file 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.