| --- | |
| short-description: Meson's own unit-test system | |
| ... | |
| # Unit tests | |
| Meson comes with a fully functional unit test system. To use it simply | |
| build an executable and then use it in a test. | |
| ```meson | |
| e = executable('prog', 'testprog.c') | |
| test('name of test', e) | |
| ``` | |
| You can add as many tests as you want. They are run with the command `meson | |
| test`. | |
| Meson captures the output of all tests and writes it in the log file | |
| `meson-logs/testlog.txt`. | |
| ## Test parameters | |
| Some tests require the use of command line arguments or environment | |
| variables. These are simple to define. | |
| ```meson | |
| test('command line test', exe, args : ['first', 'second']) | |
| test('envvar test', exe2, env : ['key1=value1', 'key2=value2']) | |
| ``` | |
| Note how you need to specify multiple values as an array. | |
| ### MALLOC_PERTURB_ | |
| By default, environment variable | |
| [`MALLOC_PERTURB_`](http://man7.org/linux/man-pages/man3/mallopt.3.html) is | |
| set to a random value between 1..255. This can help find memory leaks on | |
| configurations using glibc, including with non-GCC compilers. This feature | |
| can be disabled as discussed in [[test]]. | |
| ### ASAN_OPTIONS, MSAN_OPTIONS, TSAN_OPTIONS, and UBSAN_OPTIONS | |
| By default, the environment variables `ASAN_OPTIONS`, `MSAN_OPTIONS`, `TSAN_OPTIONS`, | |
| and `UBSAN_OPTIONS` are set to enable aborting on detected violations and to give a | |
| backtrace. This feature can be disabled as discussed in [[test]]. | |
| ## Coverage | |
| If you enable coverage measurements by giving Meson the command line | |
| flag `-Db_coverage=true`, you can generate coverage reports after | |
| running the tests (running the tests is required to gather the list of | |
| functions that get called). Meson will autodetect what coverage | |
| generator tools you have installed and will generate the corresponding | |
| targets. These targets are `coverage-xml` and `coverage-text` which | |
| are both provided by [Gcovr](http://gcovr.com) (version 3.3 or higher) | |
| `coverage-sonarqube` which is provided by [Gcovr](http://gcovr.com) (version 4.2 or higher) | |
| and `coverage-html`, which requires | |
| [lcov](https://github.com/linux-test-project/lcov) and | |
| [GenHTML](https://linux.die.net/man/1/genhtml) or | |
| [Gcovr](http://gcovr.com). As a convenience, a high-level `coverage` | |
| target is also generated which will produce all 3 coverage report | |
| types, if possible. | |
| The output of these commands is written to the log directory `meson-logs` in | |
| your build directory. | |
| ## Parallelism | |
| To reduce test times, Meson will by default run multiple unit tests in | |
| parallel. It is common to have some tests which cannot be run in | |
| parallel because they require unique hold on some resource such as a | |
| file or a D-Bus name. You have to specify these tests with a keyword | |
| argument. | |
| ```meson | |
| test('unique test', t, is_parallel : false) | |
| ``` | |
| Meson will then make sure that no other unit test is running at the | |
| same time. Non-parallel tests take longer to run so it is recommended | |
| that you write your unit tests to be parallel executable whenever | |
| possible. | |
| By default Meson uses as many concurrent processes as there are cores | |
| on the test machine. You can override this with the environment | |
| variable `MESON_TESTTHREADS` or, *since 1.7.0*, `MESON_NUM_PROCESSES`: | |
| ```console | |
| $ MESON_NUM_PROCESSES=5 meson test | |
| ``` | |
| Setting `MESON_NUM_PROCESSES` to 0 enables the default behavior (core | |
| count), whereas setting an invalid value results in setting the job | |
| count to 1. | |
| If both environment variables are present, `MESON_NUM_PROCESSES` prevails. | |
| ## Priorities | |
| *(added in version 0.52.0)* | |
| Tests can be assigned a priority that determines when a test is | |
| *started*. Tests with higher priority are started first, tests with | |
| lower priority started later. The default priority is 0, Meson makes | |
| no guarantee on the ordering of tests with identical priority. | |
| ```meson | |
| test('started second', t, priority : 0) | |
| test('started third', t, priority : -50) | |
| test('started first', t, priority : 1000) | |
| ``` | |
| Note that the test priority only affects the starting order of tests | |
| and subsequent tests are affected by how long it takes previous tests | |
| to complete. It is thus possible that a higher-priority test is still | |
| running when lower-priority tests with a shorter runtime have | |
| completed. | |
| ## Skipped tests and hard errors | |
| Sometimes a test can only determine at runtime that it cannot be run. | |
| For the default `exitcode` testing protocol, the GNU standard approach | |
| in this case is to exit the program with error code 77. Meson will | |
| detect this and report these tests as skipped rather than failed. This | |
| behavior was added in version 0.37.0. | |
| For TAP-based tests, skipped tests should print a single line starting | |
| with `1..0 # SKIP`. | |
| In addition, sometimes a test fails set up so that it should fail even | |
| if it is marked as an expected failure. The GNU standard approach in | |
| this case is to exit the program with error code 99. Again, Meson will | |
| detect this and report these tests as `ERROR`, ignoring the setting of | |
| `should_fail`. This behavior was added in version 0.50.0. In version | |
| 1.11.0 `should_fail` has been deprecated and renamed to `expected_fail`. | |
| In version 1.11.0, `expected_exitcode` has been introduced. This makes | |
| it possible to positively test for non-zero return codes. An example | |
| of this would be to test if failure injection is detected in a test. | |
| ## Testing tool | |
| The goal of the Meson test tool is to provide a simple way to run | |
| tests in a variety of different ways. The tool is designed to be run | |
| in the build directory. | |
| The simplest thing to do is just to run all tests. | |
| ```console | |
| $ meson test | |
| ``` | |
| ### Run subsets of tests | |
| For clarity, consider the meson.build containing: | |
| ```meson | |
| test('A', ..., suite: 'foo') | |
| test('B', ..., suite: ['foo', 'bar']) | |
| test('C', ..., suite: 'bar') | |
| test('D', ..., suite: 'baz') | |
| ``` | |
| Specify test(s) by name like: | |
| ```console | |
| $ meson test A D | |
| ``` | |
| You can run tests from specific (sub)project: | |
| ```console | |
| $ meson test (sub)project_name: | |
| ``` | |
| or a specific test in a specific project: | |
| ```console | |
| $ meson test (sub)project_name:test_name | |
| ``` | |
| Since version *1.2.0*, you can use wildcards in project | |
| and test names. For instance, to run all tests beginning with | |
| "foo" and all tests from projects beginning with "bar": | |
| ```console | |
| $ meson test "foo*" "bar*:" | |
| ``` | |
| Tests belonging to a suite `suite` can be run as follows | |
| ```console | |
| $ meson test --suite (sub)project_name:suite | |
| ``` | |
| Since version *0.46*, `(sub)project_name` can be omitted if it is the | |
| top-level project. | |
| Multiple suites are specified like: | |
| ```console | |
| $ meson test --suite foo --suite bar | |
| ``` | |
| NOTE: If you choose to specify both suite(s) and specific test | |
| name(s), the test name(s) must be contained in the suite(s). This | |
| however is redundant-- it would be more useful to specify either | |
| specific test names or suite(s). | |
| Since version *1.8.0*, you can pass `--slice i/n` to split up the set of tests | |
| into `n` slices and execute the `ith` such slice. This allows you to distribute | |
| a set of long-running tests across multiple machines to decrease the overall | |
| runtime of tests. | |
| Since version *1.12.0*, you can pass `--exclude NAME` to skip processing | |
| of named tests: | |
| ```console | |
| $ meson test --list | |
| m:basic | |
| m:buggy | |
| $ meson test | |
| ... | |
| 1/2 m:basic OK 0.01s | |
| 2/2 m:buggy FAIL 0.00s ... | |
| Ok: 1 | |
| Fail: 1 | |
| $ meson test --exclude buggy | |
| ... | |
| 1/1 m:basic OK 0.00s | |
| Ok: 1 | |
| Fail: 0 | |
| ``` | |
| For unqualified names (no subproject specified), `--exclude NAME` matches | |
| the main project. | |
| ### Other test options | |
| Sometimes you need to run the tests multiple times, which is done like this: | |
| ```console | |
| $ meson test --repeat=10 | |
| ``` | |
| Meson will set the `MESON_TEST_ITERATION` environment variable to the | |
| current iteration of the test *(added 1.5.0)*. | |
| Invoking tests via a helper executable such as Valgrind can be done with the | |
| `--wrapper` argument | |
| ```console | |
| $ meson test --wrapper=valgrind testname | |
| ``` | |
| Arguments to the wrapper binary can be given like this: | |
| ```console | |
| $ meson test --wrapper='valgrind --tool=helgrind' testname | |
| ``` | |
| Meson also supports running the tests under GDB. Just doing this: | |
| ```console | |
| $ meson test --gdb testname | |
| ``` | |
| Meson will launch `gdb` all set up to run the test. Just type `run` in | |
| the GDB command prompt to start the program. | |
| The second use case is a test that segfaults only rarely. In this case | |
| you can invoke the following command: | |
| ```console | |
| $ meson test --gdb --repeat=10000 testname | |
| ``` | |
| This runs the test up to 10 000 times under GDB automatically. If the | |
| program crashes, GDB will halt and the user can debug the application. | |
| Note that testing timeouts are disabled in this case so `meson test` | |
| will not kill `gdb` while the developer is still debugging it. The | |
| downside is that if the test binary freezes, the test runner will wait | |
| forever. | |
| Sometimes, the GDB binary is not in the PATH variable or the user | |
| wants to use a GDB replacement. Therefore, the invoked GDB program can | |
| be specified *(added 0.52.0)*: | |
| ```console | |
| $ meson test --gdb --gdb-path /path/to/gdb testname | |
| ``` | |
| Meson can print the error logs produced by failing tests via the | |
| `--print-errorlogs` option. The logs can include stack traces and environmental | |
| variables. This is especially useful when you run the tests on GitHub, Travis, | |
| Jenkins and the like: | |
| ```console | |
| $ meson test --print-errorlogs | |
| ``` | |
| Running tests interactively can be done with the `--interactive` option. | |
| `meson test --interactive` invokes tests with stdout, stdin and stderr | |
| connected directly to the calling terminal. This can be useful if your test is | |
| an integration test running in a container or virtual machine where a debug | |
| shell is spawned if it fails *(added 1.5.0)*: | |
| ```console | |
| $ meson test --interactive testname | |
| ``` | |
| By default, the output from tests will be limited to the last 100 lines. The | |
| maximum number of lines to show can be configured with the `--max-lines` option | |
| *(added 1.5.0)*: | |
| ```console | |
| $ meson test --max-lines=1000 testname | |
| ``` | |
| **Timeout** | |
| In the test case options, the `timeout` option is specified in a number of seconds. | |
| To disable timeout in test cases, add `timeout: 0` or a negative value to allow | |
| infinite duration for the test case to complete. | |
| For running tests, you can specify a command line argument for overriding the | |
| timeout as well: | |
| ```console | |
| $ meson test --timeout-multiplier 0 | |
| ``` | |
| For further information see the command line help of Meson by running | |
| `meson test -h`. | |
| ## Legacy notes | |
| If `meson test` does not work for you, you likely have an old version | |
| of Meson. In that case you should call `mesontest` instead. If | |
| `mesontest` doesn't work either you have a very old version prior to | |
| 0.37.0 and should upgrade. | |
| ## Test outputs | |
| Meson will write several different files with detailed results of | |
| running tests. These will be written into $builddir/meson-logs/ | |
| ### testlog.json | |
| This is not a proper json file, but a file containing one valid json | |
| object per line. This is file is designed so each line is streamed out | |
| as each test is run, so it can be read as a stream while the test | |
| harness is running | |
| ### testlog.junit.xml | |
| This is a valid JUnit XML description of all tests run. It is not | |
| streamed out, and is written only once all tests complete running. | |
| When tests use the `tap` protocol each test will be recorded as a | |
| testsuite container, with each case named by the number of the result. | |
| When tests use the `gtest` protocol Meson will inject arguments to the | |
| test to generate its own JUnit XML, which Meson will include as part | |
| of this XML file. | |
| *New in 0.55.0* |