Added ability to load names of tests to run from a file

- use -f to specify filename. Blank lines and lines starting with # are ignored
- also added --list-test-names-only to list test names out to file in a form that can be immediate read in by -f
This commit is contained in:
Phil Nash 2013-11-26 20:57:34 +00:00
parent 993430a3c4
commit 782c2b5891
3 changed files with 52 additions and 8 deletions

View File

@ -12,6 +12,8 @@
#include "catch_common.h" #include "catch_common.h"
#include "clara.h" #include "clara.h"
#include <fstream>
namespace Catch { namespace Catch {
inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; } inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
@ -38,7 +40,18 @@ namespace Catch {
? ShowDurations::Always ? ShowDurations::Always
: ShowDurations::Never; : ShowDurations::Never;
} }
inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
std::ifstream f( _filename.c_str() );
if( !f.is_open() )
throw std::domain_error( "Unable to load input file: " + _filename );
std::string line;
while( std::getline( f, line ) ) {
line = trim(line);
if( !line.empty() && !startsWith( line, "#" ) )
addTestOrTags( config, line );
}
}
inline Clara::CommandLine<ConfigData> makeCommandLineParser() { inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
@ -53,19 +66,15 @@ namespace Catch {
.longOpt( "help" ); .longOpt( "help" );
cli.bind( &ConfigData::listTests ) cli.bind( &ConfigData::listTests )
.describe( "list all (or matching) test cases" ) .describe( "list all/matching test cases" )
.shortOpt( "l") .shortOpt( "l")
.longOpt( "list-tests" ); .longOpt( "list-tests" );
cli.bind( &ConfigData::listTags ) cli.bind( &ConfigData::listTags )
.describe( "list all (or matching) tags" ) .describe( "list all/matching tags" )
.shortOpt( "t") .shortOpt( "t")
.longOpt( "list-tags" ); .longOpt( "list-tags" );
cli.bind( &ConfigData::listReporters )
.describe( "list all reporters" )
.longOpt( "list-reporters" );
cli.bind( &ConfigData::showSuccessfulTests ) cli.bind( &ConfigData::showSuccessfulTests )
.describe( "include successful tests in output" ) .describe( "include successful tests in output" )
.shortOpt( "s") .shortOpt( "s")
@ -88,7 +97,7 @@ namespace Catch {
.hint( "filename" ); .hint( "filename" );
cli.bind( &ConfigData::reporterName ) cli.bind( &ConfigData::reporterName )
.describe( "reporter to use - defaults to console" ) .describe( "reporter to use (defaults to console)" )
.shortOpt( "r") .shortOpt( "r")
.longOpt( "reporter" ) .longOpt( "reporter" )
// .hint( "name[:filename]" ); // .hint( "name[:filename]" );
@ -133,6 +142,22 @@ namespace Catch {
.longOpt( "durations" ) .longOpt( "durations" )
.hint( "yes/no" ); .hint( "yes/no" );
cli.bind( &loadTestNamesFromFile )
.describe( "load test names to run from a file" )
.shortOpt( "f")
.longOpt( "input-file" )
.hint( "filename" );
// Less common commands which don't have a short form
cli.bind( &ConfigData::listTestNamesOnly )
.describe( "list all/matching test cases names only" )
.longOpt( "list-test-names-only" );
cli.bind( &ConfigData::listReporters )
.describe( "list all reporters" )
.longOpt( "list-reporters" );
return cli; return cli;
} }

View File

@ -30,6 +30,7 @@ namespace Catch {
: listTests( false ), : listTests( false ),
listTags( false ), listTags( false ),
listReporters( false ), listReporters( false ),
listTestNamesOnly( false ),
showSuccessfulTests( false ), showSuccessfulTests( false ),
shouldDebugBreak( false ), shouldDebugBreak( false ),
noThrow( false ), noThrow( false ),
@ -43,6 +44,7 @@ namespace Catch {
bool listTests; bool listTests;
bool listTags; bool listTags;
bool listReporters; bool listReporters;
bool listTestNamesOnly;
bool showSuccessfulTests; bool showSuccessfulTests;
bool shouldDebugBreak; bool shouldDebugBreak;
@ -112,6 +114,7 @@ namespace Catch {
} }
bool listTests() const { return m_data.listTests; } bool listTests() const { return m_data.listTests; }
bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
bool listTags() const { return m_data.listTags; } bool listTags() const { return m_data.listTags; }
bool listReporters() const { return m_data.listReporters; } bool listReporters() const { return m_data.listReporters; }

View File

@ -60,6 +60,20 @@ namespace Catch {
return matchedTests; return matchedTests;
} }
inline std::size_t listTestsNamesOnly( Config const& config ) {
std::size_t matchedTests = 0;
std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests();
for( std::vector<TestCase>::const_iterator it = allTests.begin(), itEnd = allTests.end();
it != itEnd;
++it )
if( matchesFilters( config.filters(), *it ) ) {
matchedTests++;
TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
std::cout << testCaseInfo.name << std::endl;
}
return matchedTests;
}
inline std::size_t listTags( Config const& config ) { inline std::size_t listTags( Config const& config ) {
if( config.filters().empty() ) if( config.filters().empty() )
std::cout << "All available tags:\n"; std::cout << "All available tags:\n";
@ -131,6 +145,8 @@ namespace Catch {
Option<std::size_t> listedCount; Option<std::size_t> listedCount;
if( config.listTests() ) if( config.listTests() )
listedCount = listedCount.valueOr(0) + listTests( config ); listedCount = listedCount.valueOr(0) + listTests( config );
if( config.listTestNamesOnly() )
listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
if( config.listTags() ) if( config.listTags() )
listedCount = listedCount.valueOr(0) + listTags( config ); listedCount = listedCount.valueOr(0) + listTags( config );
if( config.listReporters() ) if( config.listReporters() )