mirror of
https://github.com/catchorg/Catch2.git
synced 2025-08-01 12:55:40 +02:00
Added cutoff option to command line
Aborts testing after a certain number of assertion failures
This commit is contained in:
@@ -52,7 +52,8 @@ inline bool isTrue( bool value ){ return value; }
|
||||
#define INTERNAL_CATCH_ACCEPT_EXPR( expr, stopOnFailure, originalExpr ) \
|
||||
if( Catch::ResultAction::Value internal_catch_action = Catch::getCurrentContext().getResultCapture().acceptExpression( expr ) ) \
|
||||
{ \
|
||||
if( internal_catch_action == Catch::ResultAction::DebugFailed ) BreakIntoDebugger(); \
|
||||
if( internal_catch_action & Catch::ResultAction::Debug ) BreakIntoDebugger(); \
|
||||
if( internal_catch_action & Catch::ResultAction::Abort ) throw Catch::TestFailureException(); \
|
||||
if( Catch::isTrue( stopOnFailure ) ) throw Catch::TestFailureException(); \
|
||||
if( Catch::isTrue( false ) ){ bool this_is_here_to_invoke_warnings = ( originalExpr ); Catch::isTrue( this_is_here_to_invoke_warnings ); } \
|
||||
}
|
||||
|
@@ -161,6 +161,19 @@ namespace Catch {
|
||||
throw std::domain_error( cmd.name() + " does not accept arguments" );
|
||||
config.setShowHelp( true );
|
||||
}
|
||||
|
||||
if( Command cmd = parser.find( "-c", "--cutoff" ) ) {
|
||||
if( cmd.argsCount() > 1 )
|
||||
throw std::domain_error( cmd.name() + " only accepts 0-1 arguments" );
|
||||
int threshold = 1;
|
||||
if( cmd.argsCount() == 1 )
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << cmd[0];
|
||||
ss >> threshold;
|
||||
}
|
||||
config.setCutoff( threshold );
|
||||
}
|
||||
}
|
||||
catch( std::exception& ex ) {
|
||||
config.setError( ex.what() );
|
||||
|
@@ -50,7 +50,8 @@ namespace Catch {
|
||||
m_showHelp( false ),
|
||||
m_streambuf( NULL ),
|
||||
m_os( std::cout.rdbuf() ),
|
||||
m_includeWhichResults( Include::FailedOnly )
|
||||
m_includeWhichResults( Include::FailedOnly ),
|
||||
m_cutoff( -1 )
|
||||
{}
|
||||
|
||||
~Config() {
|
||||
@@ -165,6 +166,14 @@ namespace Catch {
|
||||
return m_includeWhichResults == Include::SuccessfulResults;
|
||||
}
|
||||
|
||||
int getCutoff() const {
|
||||
return m_cutoff;
|
||||
}
|
||||
|
||||
void setCutoff( int cutoff ) {
|
||||
m_cutoff = cutoff;
|
||||
}
|
||||
|
||||
private:
|
||||
Ptr<IReporter> m_reporter;
|
||||
std::string m_filename;
|
||||
@@ -177,6 +186,7 @@ namespace Catch {
|
||||
mutable std::ostream m_os;
|
||||
Include::WhichResults m_includeWhichResults;
|
||||
std::string m_name;
|
||||
int m_cutoff;
|
||||
};
|
||||
|
||||
struct NewConfig {
|
||||
|
@@ -38,7 +38,8 @@ namespace Catch
|
||||
virtual void StartSection( const std::string& sectionName, const std::string& description ) = 0;
|
||||
virtual void EndSection( const std::string& sectionName, const Counts& assertions ) = 0;
|
||||
virtual void StartTestCase( const TestCaseInfo& testInfo ) = 0;
|
||||
virtual void EndTestCase( const TestCaseInfo& testInfo, const Totals& totals, const std::string& stdOut, const std::string& stdErr ) = 0;
|
||||
virtual void Aborted() = 0;
|
||||
virtual void EndTestCase( const TestCaseInfo& testInfo, const Totals& totals, const std::string& stdOut, const std::string& stdErr ) = 0;
|
||||
virtual void Result( const ResultInfo& result ) = 0;
|
||||
};
|
||||
|
||||
|
@@ -30,9 +30,9 @@ struct ResultWas { enum OfType {
|
||||
|
||||
struct ResultAction { enum Value {
|
||||
None,
|
||||
Failed = 1, // Failure - but no debug break if Debug bit not set
|
||||
DebugFailed = 3 // Indicates that the debugger should break, if possible
|
||||
|
||||
Failed = 1, // Failure - but no debug break if Debug bit not set
|
||||
Debug = 2, // If this bit is set, invoke the debugger
|
||||
Abort = 4 // Test run should abort
|
||||
}; };
|
||||
|
||||
}
|
||||
|
@@ -78,7 +78,13 @@ namespace Catch {
|
||||
const std::vector<TestCaseInfo>& allTests = getCurrentContext().getTestCaseRegistry().getAllTests();
|
||||
for( std::size_t i=0; i < allTests.size(); ++i ) {
|
||||
if( runHiddenTests || !allTests[i].isHidden() )
|
||||
runTest( allTests[i] );
|
||||
{
|
||||
if( aborting() ) {
|
||||
m_reporter->Aborted();
|
||||
break;
|
||||
}
|
||||
runTest( allTests[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +95,10 @@ namespace Catch {
|
||||
std::size_t testsRun = 0;
|
||||
for( std::size_t i=0; i < allTests.size(); ++i ) {
|
||||
if( testSpec.matches( allTests[i].getName() ) ) {
|
||||
if( aborting() ) {
|
||||
m_reporter->Aborted();
|
||||
break;
|
||||
}
|
||||
runTest( allTests[i] );
|
||||
testsRun++;
|
||||
}
|
||||
@@ -108,14 +118,14 @@ namespace Catch {
|
||||
|
||||
do {
|
||||
do {
|
||||
m_reporter->StartGroup( "test case run" );
|
||||
// m_reporter->StartGroup( "test case run" );
|
||||
m_currentResult.setLineInfo( m_runningTest->getTestCaseInfo().getLineInfo() );
|
||||
runCurrentTest( redirectedCout, redirectedCerr );
|
||||
m_reporter->EndGroup( "test case run", m_totals.delta( prevTotals ) );
|
||||
// m_reporter->EndGroup( "test case run", m_totals.delta( prevTotals ) );
|
||||
}
|
||||
while( m_runningTest->hasUntestedSections() );
|
||||
while( m_runningTest->hasUntestedSections() && !aborting() );
|
||||
}
|
||||
while( getCurrentContext().advanceGeneratorsForCurrentTest() );
|
||||
while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() );
|
||||
|
||||
delete m_runningTest;
|
||||
m_runningTest = NULL;
|
||||
@@ -168,7 +178,7 @@ namespace Catch {
|
||||
else
|
||||
m_reporter->Result( result );
|
||||
}
|
||||
|
||||
|
||||
virtual bool sectionStarted (
|
||||
const std::string& name,
|
||||
const std::string& description,
|
||||
@@ -218,18 +228,27 @@ namespace Catch {
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool aborting() const {
|
||||
return m_totals.assertions.failed == m_config.getCutoff();
|
||||
}
|
||||
|
||||
ResultAction::Value actOnCurrentResult() {
|
||||
testEnded( m_currentResult );
|
||||
m_lastResult = m_currentResult;
|
||||
|
||||
m_currentResult = ResultInfoBuilder();
|
||||
if( m_lastResult.ok() )
|
||||
return ResultAction::None;
|
||||
else if( shouldDebugBreak() )
|
||||
return ResultAction::DebugFailed;
|
||||
else
|
||||
return ResultAction::Failed;
|
||||
|
||||
ResultAction::Value action = ResultAction::None;
|
||||
|
||||
if( !m_lastResult.ok() ) {
|
||||
action = ResultAction::Failed;
|
||||
if( shouldDebugBreak() )
|
||||
action = (ResultAction::Value)( action | ResultAction::Debug );
|
||||
if( aborting() )
|
||||
action = (ResultAction::Value)( action | ResultAction::Abort );
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
|
||||
|
Reference in New Issue
Block a user