/ externals / catch / docs / limitations.md
limitations.md
  1  <a id="top"></a>
  2  # Known limitations
  3  
  4  Over time, some limitations of Catch2 emerged. Some of these are due
  5  to implementation details that cannot be easily changed, some of these
  6  are due to lack of development resources on our part, and some of these
  7  are due to plain old 3rd party bugs.
  8  
  9  
 10  ## Implementation limits
 11  ### Sections nested in loops
 12  
 13  If you are using `SECTION`s inside loops, you have to create them with
 14  different name per loop's iteration. The recommended way to do so is to
 15  incorporate the loop's counter into section's name, like so:
 16  
 17  ```cpp
 18  TEST_CASE( "Looped section" ) {
 19      for (char i = '0'; i < '5'; ++i) {
 20          SECTION(std::string("Looped section ") + i) {
 21              SUCCEED( "Everything is OK" );
 22          }
 23      }
 24  }
 25  ```
 26  
 27  or with a `DYNAMIC_SECTION` macro (that was made for exactly this purpose):
 28  
 29  ```cpp
 30  TEST_CASE( "Looped section" ) {
 31      for (char i = '0'; i < '5'; ++i) {
 32          DYNAMIC_SECTION( "Looped section " << i) {
 33              SUCCEED( "Everything is OK" );
 34          }
 35      }
 36  }
 37  ```
 38  
 39  ### Tests might be run again if last section fails
 40  
 41  If the last section in a test fails, it might be run again. This is because
 42  Catch2 discovers `SECTION`s dynamically, as they are about to run, and
 43  if the last section in test case is aborted during execution (e.g. via
 44  the `REQUIRE` family of macros), Catch2 does not know that there are no
 45  more sections in that test case and must run the test case again.
 46  
 47  
 48  ### MinGW/CygWin compilation (linking) is extremely slow
 49  
 50  Compiling Catch2 with MinGW can be exceedingly slow, especially during
 51  the linking step. As far as we can tell, this is caused by deficiencies
 52  in its default linker. If you can tell MinGW to instead use lld, via
 53  `-fuse-ld=lld`, the link time should drop down to reasonable length
 54  again.
 55  
 56  
 57  ## Features
 58  This section outlines some missing features, what is their status and their possible workarounds.
 59  
 60  ### Thread safe assertions
 61  Catch2's assertion macros are not thread safe. This does not mean that
 62  you cannot use threads inside Catch's test, but that only single thread
 63  can interact with Catch's assertions and other macros.
 64  
 65  This means that this is ok
 66  ```cpp
 67      std::vector<std::thread> threads;
 68      std::atomic<int> cnt{ 0 };
 69      for (int i = 0; i < 4; ++i) {
 70          threads.emplace_back([&]() {
 71              ++cnt; ++cnt; ++cnt; ++cnt;
 72          });
 73      }
 74      for (auto& t : threads) { t.join(); }
 75      REQUIRE(cnt == 16);
 76  ```
 77  because only one thread passes the `REQUIRE` macro and this is not
 78  ```cpp
 79      std::vector<std::thread> threads;
 80      std::atomic<int> cnt{ 0 };
 81      for (int i = 0; i < 4; ++i) {
 82          threads.emplace_back([&]() {
 83              ++cnt; ++cnt; ++cnt; ++cnt;
 84              CHECK(cnt == 16);
 85          });
 86      }
 87      for (auto& t : threads) { t.join(); }
 88      REQUIRE(cnt == 16);
 89  ```
 90  
 91  We currently do not plan to support thread-safe assertions.
 92  
 93  
 94  ### Process isolation in a test
 95  Catch does not support running tests in isolated (forked) processes. While this might in the future, the fact that Windows does not support forking and only allows full-on process creation and the desire to keep code as similar as possible across platforms, mean that this is likely to take significant development time, that is not currently available.
 96  
 97  
 98  ### Running multiple tests in parallel
 99  
100  Catch2 keeps test execution in one process strictly serial, and there
101  are no plans to change this. If you find yourself with a test suite
102  that takes too long to run and you want to make it parallel, you have
103  to run multiple processes side by side.
104  
105  There are 2 basic ways to do that,
106  * you can split your tests into multiple binaries, and run those binaries
107    in parallel
108  * you can run the same test binary multiple times, but run a different
109    subset of the tests in each process
110  
111  There are multiple ways to achieve the latter, the easiest way is to use
112  [test sharding](command-line.md#test-sharding).
113  
114  
115  ## 3rd party bugs
116  
117  This section outlines known bugs in 3rd party components (this means compilers, standard libraries, standard runtimes).
118  
119  
120  ### Visual Studio 2017 -- raw string literal in assert fails to compile
121  
122  There is a known bug in Visual Studio 2017 (VC 15), that causes compilation
123  error when preprocessor attempts to stringize a raw string literal
124  (`#` preprocessor directive is applied to it). This snippet is sufficient
125  to trigger the compilation error:
126  
127  ```cpp
128  #include <catch2/catch_test_macros.hpp>
129  
130  TEST_CASE("test") {
131      CHECK(std::string(R"("\)") == "\"\\");
132  }
133  ```
134  
135  Catch2 provides a workaround, by letting the user disable stringification
136  of the original expression by defining `CATCH_CONFIG_DISABLE_STRINGIFICATION`,
137  like so:
138  ```cpp
139  #define CATCH_CONFIG_DISABLE_STRINGIFICATION
140  #include <catch2/catch_test_macros.hpp>
141  
142  TEST_CASE("test") {
143      CHECK(std::string(R"("\)") == "\"\\");
144  }
145  ```
146  
147  _Do note that this changes the output:_
148  ```
149  catchwork\test1.cpp(6):
150  PASSED:
151    CHECK( Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION )
152  with expansion:
153    ""\" == ""\"
154  ```
155  
156  
157  ### Clang/G++ -- skipping leaf sections after an exception
158  Some versions of `libc++` and `libstdc++` (or their runtimes) have a bug with `std::uncaught_exception()` getting stuck returning `true` after rethrow, even if there are no active exceptions. One such case is this snippet, which skipped the sections "a" and "b", when compiled against `libcxxrt` from the master branch
159  ```cpp
160  #include <catch2/catch_test_macros.hpp>
161  
162  TEST_CASE("a") {
163      CHECK_THROWS(throw 3);
164  }
165  
166  TEST_CASE("b") {
167      int i = 0;
168      SECTION("a") { i = 1; }
169      SECTION("b") { i = 2; }
170      CHECK(i > 0);
171  }
172  ```
173  
174  If you are seeing a problem like this, i.e. weird test paths that trigger only under Clang with `libc++`, or only under very specific version of `libstdc++`, it is very likely you are seeing this. The only known workaround is to use a fixed version of your standard library.
175