Added cutoff option to command line

Aborts testing after a certain number of assertion failures
This commit is contained in:
Phil Nash
2012-06-01 19:40:27 +01:00
parent 163088a11f
commit 19b2aa6187
14 changed files with 233 additions and 73 deletions

View File

@@ -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 ); } \
}

View File

@@ -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() );

View File

@@ -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 {

View File

@@ -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;
};

View File

@@ -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
}; };
}

View File

@@ -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 ) {