site/source/docs/getting_started/test-suite.rst
.. _emscripten-test-suite:
Emscripten has a comprehensive test suite, which covers virtually all Emscripten
functionality. These tests are an excellent resource for developers as they
provide practical examples of most features, and are known to pass on the
main branch. In addition to correctness tests, there are also benchmarks
that you can run.
This article explains how to run the test and benchmark suite, and provides an overview of what tests are available.
To run the tests, you need an emscripten setup, as it will run emcc and other
commands. See the :ref:developer's guide <developers-guide-setting-up> for
how best to do that.
Run the test suite runner (test/runner <https://github.com/emscripten-core/emscripten/blob/main/test/runner.py>_) with --help to see the help message:
.. code-block:: bash
test/runner --help
The tests are divided into modes. You can run either an entire mode or an individual test, or use wildcards to run some tests in some modes. For example:
.. code-block:: bash
test/runner test_foo
test/runner core3.test_i64
test/runner wasm2js1
The core test modes (defined at the bottom of test/test_core.py <https://github.com/emscripten-core/emscripten/blob/main/test/test_core.py>_)
let you run the tests in variety of different configurations and with different
optimization flags. For example, wasm2js or wasm64. There are also non-core
test suites, that run tests in more special manner (in particular, in those tests
it is not possible to say "run the test with a different optimization flag" -
that is what the core tests are for). The non-core test suites include
other: Non-core tests running in the shell.browser: Tests that run in a browser.sockets: Networking tests that run in a browser.interactive: Browser tests that are not fully automated, and require user interaction (these should be automated eventually).sanity: Tests for emscripten setting itself up. This modifies your .emscripten file temporarily.benchmark: Runs benchmarks, measuring speed and code size.The wildcards we mentioned above work for non-core test modes too, for example:
.. code-block:: bash
test/runner browser.test_sdl_image
test/runner browser.test_sdl2*
test/runner browser
An individual test can be skipped by passing the "skip:" prefix. E.g.
.. code-block:: bash
test/runner other skip:other.test_cmake
Wildcards can also be passed in skip, so
.. code-block:: bash
test/runner browser skip:browser.test_pthread_*
will run the whole browser suite except for all the pthread tests in it.
Sometimes it is useful to be able to iteratively fix one test at a time. In
this case the --failfast option can be used to exit the test runner after
the first failure.
.. note:: This option only works with the serial test runner. For test suites
that are normally run in parallel you can force them to run serially using
-j1.
Once a test is fixed, you continue where you left off using --start-at option:
.. code-block:: bash
test/runner browser --start-at test_foo --failfast
You can run a random subset of the test suite, using something like
.. code-block:: bash
test/runner random100
Replace 100 with another number as you prefer. This will run that number of
random tests, and tell you the statistical likelihood of almost all the test
suite passing assuming those tests do. This works just like election surveys do
Please see the bottom the file test/test_core.py <https://github.com/emscripten-core/emscripten/blob/main/test/test_core.py>_
for the current test modes, as they may change slowly over time. When you want
to run the entire test suite locally, these are currently the important
commands:
.. code-block:: bash
test/runner core*
test/runner other
test/runner browser
test/runner sockets
test/runner sanity
test/runner benchmark
.. _benchmarking:
Emscripten has a benchmark suite that measures both speed and code size, which
includes several interesting real-world codebases, from physics engines to
compression libraries to virtual machines. It also includes some existing
benchmarks such as CoreMark and LINPACK. See for example
this post's section on speed <https://kripken.github.io/blog/wasm/2020/07/27/wasmboxc.html>_
which gives an overview.
To run the benchmark suite, do:
.. code-block:: bash
test/runner benchmark
As with all the test suites, you can also run a specific benchmark:
.. code-block:: bash
test/runner benchmark.test_skinning
You can also specify which benchmarkers are run by using the environment
variable EMTEST_BENCHMARKERS. It accepts a comma separated list of named
benchmarkers (names can be found in named_benchmarkers in
test/test_benchmark.py).
.. code-block:: bash
EMTEST_BENCHMARKERS=clang,v8 test/runner benchmark.test_skinning
To further customize how the benchmarks are run, you will want to edit the file
test/test_benchmark.py. Some of the options include:
DEFAULT_ARG is how long the benchmark should run (they all try to run for
a similar amount of time for consistency).TEST_REPS is how many times to repeat each run (more will take longer, but
should have less noise).PROFILING controls whether the builds are set up for profiling (which can
increase code size, so it's not done by default).By default the test runner will hide all test output and use a single terminal line to show test results.
If you want to see more information you can run with -v/--verbose to show the
stdout / stderr / logging produced during each test.
If you add a second -v/--verbose then then test runner will output even more
information. For example it will show all the subcommands that it runs, as it
runs them.
For even more debugging info, you can set :ref:debugging-EMCC_DEBUG which will
cause the emscripten compiler itself to output a lot of debug info. This will
also tell the compiler to leave all its temporary files behind after it runs
(the files go in /tmp/emscripten_temp/):
.. code-block:: bash
set EMCC_DEBUG=1 test/runner test_hello_world set EMCC_DEBUG=0
EMCC_DEBUG=1 test/runner test_hello_world
EMCC_DEBUG=2 test/runner test_hello_world
If you run just one a single test (or one test at at time using -j1) the test
output can always be found in out/test. This is useful for inspecting test
outputs as well as temporary files generated by the test. By default, the temporary
directory will be cleaned between each test run, but you can add --no-clean to
avoid this.
The :ref:Debugging topic provides more guidance on how to debug
Emscripten-generated code.