# MFEM Unit Tests This directory contains MFEM's suite of unit tests, using the [Catch2](https://github.com/catchorg/Catch2) unit testing framework. ## Test executables MFEM's unit test suite includes a number of executables: * `unit_tests` * `cunit_tests` if MFEM is compiled with CUDA support * `sedov_tests_cpu`, `sedov_tests_debug` (and `sedov_tests_cuda` and `sedov_tests_cuda_uvm` if CUDA is enabled), testing a Sedov hydrodynamics case * `tmop_pa_tests_cpu`, `tmop_pa_tests_debug` (and `tmop_pa_tests_cuda` if CUDA is enabled), testing TMOP with partial assembly There are also parallel versions of these executables (prefixed with `p`), which are built if MFEM is compiled with MPI enabled. ## Basics of using Catch To run the unit tests, any of the executables listed above can be run from the command line, for example ``` ./unit_tests ``` which will run _all_ serial unit tests. If you want to run only a specific test case, it is possible to specify the name of the test case as an argument to the test executable (the names of the test cases are given as the first argument to the `TEST_CASE` macro in the source code). For example ``` ./unit_tests "NCMesh PA diagonal" ``` will run only test case testing partial assembly of the diagonal on non-conforming meshes. Test cases are optionally given one or more _tags_, which can be used to group test cases together. Tags can also be specified on the command line, for example ``` ./unit_tests "[NCMesh]" ``` will run all the tests that relate to non-conforming meshes. ## Listing tests and tags It is possible to list all test cases with the `-l` flag, for example ``` ./unit_tests -l ``` will list all serial unit tests, and ``` ./unit_tests -l "[NCMesh]" ``` will list all test cases with the given tag. ``` ./unit_tests -t ``` will list all available tags, along with the number of test cases that are assigned to each tag. ## Special tags For the most part, tags are just used to group similar tests together according to their subject matter. However, several specific tags have special meanings, and those are: * `[Parallel]`, which indicates that a test will **not** be tested with the serial test executables, and will only be tested with the parallel executable (e.g. `punit_tests`). `punit_tests` will only run tests marked with `[Parallel]`. * `[CUDA]`, which indicates that a test will be tested with the CUDA executables (e.g. `cunit_tests`). These tests will still be run by the standard (CPU) executables. `cunit_tests` will only run tests marked with `[CUDA]`, and its parallel version `pcunit_tests` will only run tests marked with _both_ `[CUDA]` and `[Parallel]`. * `[MFEMData]`, which indicates that a test requires access to a clone of the MFEM data repository (see the `--data` flag below), in order to run tests on some larger mesh files. By default, tests tagged with this tag are skipped, unless the `--data` flag is provided. ## Special command line arguments In addition to the standard Catch command line arguments (which can be viewed with the `-h` or `--help` flag), MFEM's unit tests support two additional command line arguments: * `--all`, which enables some more thorough tests, at the expense of longer runtimes. This sets the global variable `launch_all_non_regression_tests` to true. * `--data`, which specifies a path to a clone of the MFEM [data repository](https://github.com/mfem/data), which contains some larger mesh files. If this argument is provided, tests tagged with `[MFEMData]` will be run, and they will have access to the files in the data repo through the `mfem_data_dir` global variable. ## Test output and debug messages By default, MFEM's unit tests display relatively little output (a couple of info lines at the beginning, and a summary at the end with the number of test cases and assertions that were run). If a test fails, some additional information about the failing test will be printed. Output to `mfem::out` and `mfem::err` is suppressed by default. To enable more verbose test output, run the unit tests with the `-s` or `--success` flag, which will print a message for every successful test assertion, including some additional informational messages. With this option, output to `mfem::out` and `mfem::err` is enabled. ## Writing unit tests The following are some guidelines for developers writing unit tests: * Give your test case a concise yet descriptive name. Whitespace is allowed. * Tag your test with the relevant tags. Look at similar tags to see what relevant tags are in use. Class names are often used as tags. Another common tag is `[PartialAssembly]`. See also the section on [special tags](#special-tags). * Do not use `std::cout` or `std::cerr` in your test. Prefer the Catch macros [`INFO`](https://github.com/catchorg/Catch2/blob/v2.x/docs/logging.md#top), [`CAPTURE`](https://github.com/catchorg/Catch2/blob/v2.x/docs/logging.md#quickly-capture-value-of-variables-or-expressions), and similar. If you need more control over the output, prefer `mfem::out` and `mfem::err`. * Use the [`GENERATE`](https://github.com/catchorg/Catch2/blob/v2.x/docs/generators.md#top) macro instead of nested for-loops when testing many combinations of parameters.