mirror of
https://github.com/catchorg/Catch2.git
synced 2024-12-23 11:43:29 +01:00
da0edcbe25
Previously, some errors in Catch configuration would cause exceptions to be thrown before main was even entered. This leads to call to `std::terminate`, which is not a particularly nice way of ending the binary. Now these exceptions are registered with a global collector and used once Catch enters main. They can also be optionally ignored, if user supplies his own main and opts not to check them (or ignored them intentionally). Closes #921
87 lines
2.8 KiB
Markdown
87 lines
2.8 KiB
Markdown
# Supplying main() yourself
|
|
|
|
The easiest way to use Catch is to let it supply ```main()``` for you and handle configuring itself from the command line.
|
|
|
|
This is achieved by writing ```#define CATCH_CONFIG_MAIN``` before the ```#include "catch.hpp"``` in *exactly one* source file.
|
|
|
|
Sometimes, though, you need to write your own version of main(). You can do this by writing ```#define CATCH_CONFIG_RUNNER``` instead. Now you are free to write ```main()``` as normal and call into Catch yourself manually.
|
|
|
|
You now have a lot of flexibility - but here are three recipes to get your started:
|
|
|
|
## Let Catch take full control of args and config
|
|
|
|
If you just need to have code that executes before and/ or after Catch this is the simplest option.
|
|
|
|
```c++
|
|
#define CATCH_CONFIG_RUNNER
|
|
#include "catch.hpp"
|
|
|
|
int main( int argc, char* argv[] ) {
|
|
// global setup...
|
|
|
|
int result = Catch::Session().run( argc, argv );
|
|
|
|
// global clean-up...
|
|
|
|
return ( result < 0xff ? result : 0xff );
|
|
}
|
|
```
|
|
|
|
## Amending the config
|
|
|
|
If you still want Catch to process the command line, but you want to programatically tweak the config, you can do so in one of two ways:
|
|
|
|
```c++
|
|
#define CATCH_CONFIG_RUNNER
|
|
#include "catch.hpp"
|
|
|
|
int main( int argc, char* argv[] )
|
|
{
|
|
Catch::Session session; // There must be exactly one instance
|
|
|
|
// writing to session.configData() here sets defaults
|
|
// this is the preferred way to set them
|
|
|
|
// Verify that all tests, aliases, etc registered properly
|
|
const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();
|
|
if ( !exceptions.empty() ) {
|
|
// iterate over all exceptions and notify user
|
|
for ( const auto& ex_ptr : exceptions ) {
|
|
try {
|
|
std::rethrow_exception(ex_ptr);
|
|
} catch (std::exception const& ex) {
|
|
Catch::cerr() << ex.what();
|
|
}
|
|
}
|
|
// Indicate that an error occured before main
|
|
return 1;
|
|
}
|
|
|
|
int returnCode = session.applyCommandLine( argc, argv );
|
|
if( returnCode != 0 ) // Indicates a command line error
|
|
return returnCode;
|
|
|
|
// writing to session.configData() or session.Config() here
|
|
// overrides command line args
|
|
// only do this if you know you need to
|
|
|
|
int numFailed = session.run();
|
|
// Note that on unices only the lower 8 bits are usually used, clamping
|
|
// the return value to 255 prevents false negative when some multiple
|
|
// of 256 tests has failed
|
|
return ( numFailed < 0xff ? numFailed : 0xff );
|
|
}
|
|
```
|
|
|
|
Take a look at the definitions of Config and ConfigData to see what you can do with them.
|
|
|
|
To take full control of the config simply omit the call to ```applyCommandLine()```.
|
|
|
|
## Adding your own command line options
|
|
|
|
Catch embeds a powerful command line parser which you can also use to parse your own options out. This capability is still in active development but will be documented here when it is ready.
|
|
|
|
---
|
|
|
|
[Home](Readme.md)
|