doctest

FORK: The fastest feature-rich C++11/14/17/20 single-header testing framework
git clone https://git.neptards.moe/neptards/doctest.git
Log | Files | Refs | README

extensions.html (7637B)


      1 <!DOCTYPE html>
      2 <html>
      3 <title>extensions</title>
      4 <xmp theme="united" style="display:none;">
      5 
      6 ## Extensions
      7 
      8 The doctest header doesn't include any external or stdlib headers in it's interface part in order to provide the most optimal build times but that means it is limited in what it can provide as functionality => that's when extensions come into play. They are located as header files in [`doctest/extensions`](../../doctest/extensions) and each of them is documented in a section here.
      9 
     10 # [Utils](../../doctest/extensions/doctest_util.h)
     11 
     12 nothing here yet...
     13 
     14 # [Distributed tests with MPI](../../doctest/extensions/doctest_mpi.h)
     15 
     16 [Bruno Maugars and Bérenger Berthoul, ONERA]
     17 
     18 Testing code over distributed processes requires support from the testing framework. **Doctest** support for MPI parallel communication is provided in the ```"doctest/extensions/doctest_mpi.h"``` header.
     19 
     20 ## Example
     21 
     22 See [**the complete test**](../../examples/mpi/mpi.cpp) and [**the configuration of main()**](../../examples/mpi/main.cpp)
     23 
     24 ### MPI_TEST_CASE
     25 
     26 ```
     27 #include "doctest/extensions/doctest_mpi.h"
     28 
     29 int my_function_to_test(MPI_Comm comm) {
     30   int rank;
     31   MPI_Comm_rank(comm,&rank);
     32   if (rank == 0) {
     33     return 10;
     34   }
     35   return 11;
     36 }
     37 
     38 
     39 MPI_TEST_CASE("test over two processes",2) { // Parallel test on 2 processes
     40   int x = my_function_to_test(test_comm);
     41 
     42   MPI_CHECK( 0,  x==10 ); // CHECK for rank 0, that x==10
     43   MPI_CHECK( 1,  x==11 ); // CHECK for rank 1, that x==11
     44 }
     45 ```
     46 
     47 An ```MPI_TEST_CASE``` is like a regular ```TEST_CASE```, except it takes a second argument, which is the number of processes needed to run the test.  If the number of processes is less than 2, the test will fail. If the number of processes is greater than or equal to 2, it will create a sub-communicator over 2 processes, called ```test_comm```, and execute the test over these processes. Three objects are provided by ```MPI_TEST_CASE```:
     48  * ```test_comm```, of type ```MPI_Comm```: the mpi communicator on which the test is running,
     49  * ```test_rank``` and ```test_nb_procs```, two ```int``` giving respectively the rank of the current process and the size of the communicator for ```test_comm```. These last two are just here for convenience and could be retrieved from ```test_comm```.
     50 
     51 We always have:
     52 
     53 ```
     54 MPI_TEST_CASE("my_test",N) {
     55   CHECK( test_nb_procs == N );
     56   MPI_CHECK( i, test_rank==i ); // for any i<N
     57 }
     58 ```
     59 
     60 ### Assertions
     61 It is possible to use regular assertions in an ```MPI_TEST_CASE```. MPI-specific assertions are also provided and are all prefixed with ```MPI_``` (```MPI_CHECK```, ```MPI_ASSERT```...). The first argument is the rank for which they are checked, and the second is the usual expression to check.
     62 
     63 ## The main entry points and mpi reporters
     64 
     65 You need to launch the unit tests with an ```mpirun``` or ```mpiexec``` command:
     66 ```
     67 mpirun -np 2 unit_test_executable.exe
     68 ```
     69 
     70 ```doctest::mpi_init_thread()``` must be called before running the unit tests, and ```doctest::mpi_finalize()``` at the end of the program. Also, using the default console reporter will result in each process writing everything in the same place, which is not what we want. Two reporters are provided and can be enabled. A complete ```main()``` would be:
     71 
     72 
     73 ```
     74 #define DOCTEST_CONFIG_IMPLEMENT
     75 
     76 #include "doctest/extensions/doctest_mpi.h"
     77 
     78 int main(int argc, char** argv) {
     79   doctest::mpi_init_thread(argc,argv,MPI_THREAD_MULTIPLE); // Or any MPI thread level
     80 
     81   doctest::Context ctx;
     82   ctx.setOption("reporters", "MpiConsoleReporter");
     83   ctx.setOption("reporters", "MpiFileReporter");
     84   ctx.setOption("force-colors", true);
     85   ctx.applyCommandLine(argc, argv);
     86 
     87   int test_result = ctx.run();
     88 
     89   doctest::mpi_finalize();
     90 
     91   return test_result;
     92 }
     93 ```
     94 
     95 ### MpiConsoleReporter
     96 
     97 The ```MpiConsoleReporter``` should be substituted to the default reporter. It does the same as the default console reporter for regular assertions, but only outputs on process 0. For MPI test cases, if there is a failure it tells the process that failed
     98 
     99 ```
    100 [doctest] doctest version is "2.4.0"
    101 [doctest] run with "--help" for options
    102 ===============================================================================
    103 [doctest] test cases:    171 |    171 passed |      0 failed |      0 skipped
    104 [doctest] assertions:    864 |    864 passed |      0 failed |
    105 [doctest] Status: SUCCESS!
    106 std_e_mpi_unit_tests
    107 [doctest] doctest version is "2.4.0"
    108 [doctest] run with "--help" for options
    109 ===============================================================================
    110 path/to/test.cpp:30:
    111 TEST CASE: my test case
    112 
    113 On rank [2] : path/to/test.cpp:35: CHECK( x==-1 ) is NOT correct!
    114   values: CHECK( 0 == -1 )
    115 
    116 ===============================================================================
    117 [doctest] test cases:      2 |      2 passed |      0 failed |      0 skipped
    118 [doctest] assertions:      2 |      2 passed |      0 failed |
    119 [doctest] Status: SUCCESS!
    120 ===============================================================================
    121 [doctest] assertions on all processes:   5 |   4 passed |      1 failed |
    122 ===============================================================================
    123 [doctest] fail on rank:
    124     -> On rank [2] with 1 test failed
    125 [doctest] Status: FAILURE!
    126 ```
    127 
    128 If the test executable is launch with less processes than the number of processes required by one test, the test is skipped and marqued as such in the mpi console reporter:
    129 
    130 
    131 ```
    132 MPI_TEST_CASE("my_test",3) {
    133   // ...
    134 }
    135 ```
    136 
    137 ```
    138 mpirun -np 2 unit_test_executable.exe
    139 ```
    140 
    141 ```
    142 ===============================================================================
    143 [doctest] test cases:      1 |      1 passed |      0 failed |      1 skipped
    144 [doctest] assertions:      1 |      1 passed |      0 failed |
    145 [doctest] Status: SUCCESS!
    146 ===============================================================================
    147 [doctest] assertions on all processes:   1 |   1 passed |      0 failed |
    148 [doctest] WARNING: Skipped 1 test requiring more than 2 MPI processes to run
    149 ===============================================================================
    150 ```
    151 
    152 ### MpiFileReporter
    153 The ```MpiFileReporter``` will just print the result of each process in its own file, named ```doctest_[rank].log```. Only use this reporter as a debug facility if you want to know what is going on exactly when a parallel test case is failing.
    154 
    155 ### Other reporters
    156 Other reporters (jUnit, XML) are not supported directly, which mean that you can always print the result of each process to its own file, but there is (currently) no equivalent of the ```MpiConsoleReporter``` that will aggregate the results of all processes.
    157 
    158 
    159 ## Note
    160 
    161 This feature is provided to unit-test mpi-distributed code. It is **not** a way to parallelize many unit tests over several processes (for that, see [**the example python script**](../../examples/range_based_execution.py)).
    162 
    163 ## TODO
    164 
    165  * Pass ```s``` member variable of ```ConsoleReporter``` as an argument to member functions so we can use them with another object (would help to factorize ```MPIConsoleReporter```)
    166  * Only MPI_CHECK tested. MPI_REQUIRE, exception handling: nothing tested
    167  * More testing, automatic testing
    168  * Packaging: create a new target ```mpi_doctest```? (probably cleaner to depend explicitly on MPI for mpi/doctest.h)
    169  * Later, maybe: have a general mechanism to represent assertions so we can separate the report format (console, xml, junit...) from the reporting strategy (sequential vs. MPI)
    170 
    171 ---------------
    172 
    173 [Home](readme.html#reference)
    174 
    175 <p align="center"><img src="../../scripts/data/logo/icon_2.svg"></p>
    176 
    177 
    178 </xmp>
    179 <script src="strapdown.js/strapdown.js"></script>
    180 </html>