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 or false). 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 or false). Can slow down test runner.

  • teavm.junit.wasm – whether WebAssembly target is enabled (true or false).

  • teavm.junit.wasm.runner – how to run WebAssembly tests. Same as teavm.junit.js.runner, except for htmlunit value is not supported.

  • teavm.junit.c – whether C target is enabled (true or false).

  • teavm.junit.c.compiler – command that compiles C to native code. This is usually path to a shell file that takes all.c file in working directory and produces run_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 or false).

  • 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.