Allow multiple test case arguments to testrunner (#1755)
Take some care to not run the same test case twice, even if running: ./testrunner TestClass TestClass::TestCase
This commit is contained in:
parent
c262aeffdd
commit
6b478c362e
|
@ -19,16 +19,19 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
options::options(int argc, const char* const argv[])
|
options::options(int argc, const char* const argv[])
|
||||||
:mOptions(argv + 1, argv + argc)
|
:mWhichTests(argv + 1, argv + argc)
|
||||||
,mWhichTest("")
|
,mQuiet(mWhichTests.count("-q") != 0)
|
||||||
,mQuiet(mOptions.count("-q") != 0)
|
,mHelp(mWhichTests.count("-h") != 0 || mWhichTests.count("--help"))
|
||||||
,mHelp(mOptions.count("-h") != 0 || mOptions.count("--help"))
|
|
||||||
{
|
{
|
||||||
mOptions.erase("-q");
|
for (std::set<std::string>::const_iterator it = mWhichTests.begin(); it != mWhichTests.end();) {
|
||||||
mOptions.erase("-h");
|
if (!(*it).empty() && (((*it)[0] == '-') || ((*it).find("::") != std::string::npos && mWhichTests.count((*it).substr(0, (*it).find("::"))))))
|
||||||
mOptions.erase("--help");
|
it = mWhichTests.erase(it);
|
||||||
if (! mOptions.empty()) {
|
else
|
||||||
mWhichTest = *mOptions.rbegin();
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mWhichTests.empty()) {
|
||||||
|
mWhichTests.insert("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +45,7 @@ bool options::help() const
|
||||||
return mHelp;
|
return mHelp;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& options::which_test() const
|
const std::set<std::string>& options::which_test() const
|
||||||
{
|
{
|
||||||
return mWhichTest;
|
return mWhichTests;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ public:
|
||||||
/** Print help. */
|
/** Print help. */
|
||||||
bool help() const;
|
bool help() const;
|
||||||
/** Which test should be run. Empty string means 'all tests' */
|
/** Which test should be run. Empty string means 'all tests' */
|
||||||
const std::string& which_test() const;
|
const std::set<std::string>& which_test() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
options();
|
options();
|
||||||
|
@ -42,8 +42,7 @@ private:
|
||||||
const options& operator =(const options& non_assign);
|
const options& operator =(const options& non_assign);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::set<std::string> mOptions;
|
std::set<std::string> mWhichTests;
|
||||||
std::string mWhichTest;
|
|
||||||
const bool mQuiet;
|
const bool mQuiet;
|
||||||
const bool mHelp;
|
const bool mHelp;
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,6 +36,7 @@ private:
|
||||||
TEST_CASE(help);
|
TEST_CASE(help);
|
||||||
TEST_CASE(help_long);
|
TEST_CASE(help_long);
|
||||||
TEST_CASE(multiple_testcases);
|
TEST_CASE(multiple_testcases);
|
||||||
|
TEST_CASE(multiple_testcases_ignore_duplicates);
|
||||||
TEST_CASE(invalid_switches);
|
TEST_CASE(invalid_switches);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,21 +44,21 @@ private:
|
||||||
void which_test() const {
|
void which_test() const {
|
||||||
const char* argv[] = {"./test_runner", "TestClass"};
|
const char* argv[] = {"./test_runner", "TestClass"};
|
||||||
options args(sizeof argv / sizeof argv[0], argv);
|
options args(sizeof argv / sizeof argv[0], argv);
|
||||||
ASSERT_EQUALS("TestClass", args.which_test());
|
ASSERT(std::set<std::string> {"TestClass"} == args.which_test());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void which_test_method() const {
|
void which_test_method() const {
|
||||||
const char* argv[] = {"./test_runner", "TestClass::TestMethod"};
|
const char* argv[] = {"./test_runner", "TestClass::TestMethod"};
|
||||||
options args(sizeof argv / sizeof argv[0], argv);
|
options args(sizeof argv / sizeof argv[0], argv);
|
||||||
ASSERT_EQUALS("TestClass::TestMethod", args.which_test());
|
ASSERT(std::set<std::string> {"TestClass::TestMethod"} == args.which_test());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void no_test_method() const {
|
void no_test_method() const {
|
||||||
const char* argv[] = {"./test_runner"};
|
const char* argv[] = {"./test_runner"};
|
||||||
options args(sizeof argv / sizeof argv[0], argv);
|
options args(sizeof argv / sizeof argv[0], argv);
|
||||||
ASSERT_EQUALS("", args.which_test());
|
ASSERT(std::set<std::string> {""} == args.which_test());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,16 +96,24 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void multiple_testcases() const {
|
void multiple_testcases() const {
|
||||||
const char* argv[] = {"./test_runner", "TestClass::TestMethod", "Ignore::ThisOne"};
|
const char* argv[] = {"./test_runner", "TestClass::TestMethod", "TestClass::AnotherTestMethod"};
|
||||||
options args(sizeof argv / sizeof argv[0], argv);
|
options args(sizeof argv / sizeof argv[0], argv);
|
||||||
ASSERT_EQUALS("TestClass::TestMethod", args.which_test());
|
std::set<std::string> expected {"TestClass::TestMethod", "TestClass::AnotherTestMethod"};
|
||||||
|
ASSERT(expected == args.which_test());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void multiple_testcases_ignore_duplicates() const {
|
||||||
|
const char* argv[] = {"./test_runner", "TestClass::TestMethod", "TestClass"};
|
||||||
|
options args(sizeof argv / sizeof argv[0], argv);
|
||||||
|
std::set<std::string> expected {"TestClass"};
|
||||||
|
ASSERT(expected == args.which_test());
|
||||||
|
}
|
||||||
|
|
||||||
void invalid_switches() const {
|
void invalid_switches() const {
|
||||||
const char* argv[] = {"./test_runner", "TestClass::TestMethod", "-a", "-v", "-q"};
|
const char* argv[] = {"./test_runner", "TestClass::TestMethod", "-a", "-v", "-q"};
|
||||||
options args(sizeof argv / sizeof argv[0], argv);
|
options args(sizeof argv / sizeof argv[0], argv);
|
||||||
ASSERT_EQUALS("TestClass::TestMethod", args.which_test());
|
std::set<std::string> expected {"TestClass::TestMethod"};
|
||||||
|
ASSERT(expected == args.which_test());
|
||||||
ASSERT_EQUALS(true, args.quiet());
|
ASSERT_EQUALS(true, args.quiet());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -280,13 +280,15 @@ void TestFixture::printHelp()
|
||||||
std::cout << "Testrunner - run Cppcheck tests\n"
|
std::cout << "Testrunner - run Cppcheck tests\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Syntax:\n"
|
"Syntax:\n"
|
||||||
" testrunner [OPTIONS] [TestClass::TestCase]\n"
|
" testrunner [OPTIONS] [TestClass::TestCase...]\n"
|
||||||
" run all test cases:\n"
|
" run all test cases:\n"
|
||||||
" testrunner\n"
|
" testrunner\n"
|
||||||
" run all test cases in TestClass:\n"
|
" run all test cases in TestClass:\n"
|
||||||
" testrunner TestClass\n"
|
" testrunner TestClass\n"
|
||||||
" run TestClass::TestCase:\n"
|
" run TestClass::TestCase:\n"
|
||||||
" testrunner TestClass::TestCase\n"
|
" testrunner TestClass::TestCase\n"
|
||||||
|
" run all test cases in TestClass1 and TestClass2::TestCase:\n"
|
||||||
|
" testrunner TestClass1 TestClass2::TestCase\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
" -q Do not print the test cases that have run.\n"
|
" -q Do not print the test cases that have run.\n"
|
||||||
|
@ -311,22 +313,24 @@ void TestFixture::processOptions(const options& args)
|
||||||
|
|
||||||
std::size_t TestFixture::runTests(const options& args)
|
std::size_t TestFixture::runTests(const options& args)
|
||||||
{
|
{
|
||||||
std::string classname(args.which_test());
|
|
||||||
std::string testname;
|
|
||||||
if (classname.find("::") != std::string::npos) {
|
|
||||||
testname = classname.substr(classname.find("::") + 2);
|
|
||||||
classname.erase(classname.find("::"));
|
|
||||||
}
|
|
||||||
|
|
||||||
countTests = 0;
|
countTests = 0;
|
||||||
errmsg.str("");
|
errmsg.str("");
|
||||||
|
|
||||||
const TestSet &tests = TestRegistry::theInstance().tests();
|
const std::set<std::string>& tests = args.which_test();
|
||||||
|
for (std::string classname : tests) {
|
||||||
|
std::string testname;
|
||||||
|
if (classname.find("::") != std::string::npos) {
|
||||||
|
testname = classname.substr(classname.find("::") + 2);
|
||||||
|
classname.erase(classname.find("::"));
|
||||||
|
}
|
||||||
|
|
||||||
for (TestFixture * test : tests) {
|
const TestSet &tests = TestRegistry::theInstance().tests();
|
||||||
if (classname.empty() || test->classname == classname) {
|
|
||||||
test->processOptions(args);
|
for (TestFixture * test : tests) {
|
||||||
test->run(testname);
|
if (classname.empty() || test->classname == classname) {
|
||||||
|
test->processOptions(args);
|
||||||
|
test->run(testname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue