More match options for unit test selection string

This commit is contained in:
Vinnie Falco
2013-08-07 17:31:48 -07:00
parent f48ab1b286
commit b806ce2d9e
4 changed files with 217 additions and 99 deletions

View File

@@ -37,6 +37,13 @@ UnitTest::~UnitTest()
getAllTests().removeFirstMatchingValue (this);
}
String UnitTest::getTestName() const noexcept
{
String s;
s << m_packageName << "." << m_className;
return s;
}
String const& UnitTest::getClassName() const noexcept
{
return m_className;
@@ -100,7 +107,7 @@ void UnitTest::beginTestCase (String const& name)
finishCase ();
String s;
s << m_packageName << "/" << m_className << ": " << name;
s << getTestName () << " : " << name;
logMessage (s);
m_case = new Case (name, m_className);
@@ -231,91 +238,126 @@ bool UnitTests::anyTestsFailed () const noexcept
return m_results->failures > 0;
}
void UnitTests::runTests (Array <UnitTest*> const& tests)
UnitTests::TestList UnitTests::selectTests (
String const& match, TestList const& tests) const noexcept
{
TestList list;
list.ensureStorageAllocated (tests.size ());
int const indexOfDot = match.indexOfChar ('.');
String const package = (indexOfDot == -1) ? match : match.substring (0, indexOfDot);
String const testname = (indexOfDot == -1) ? ""
: match.substring (indexOfDot + 1, match.length () + 1);
if (package != String::empty)
{
if (testname != String::empty)
{
// "package.testname" : First test which matches
for (int i = 0; i < tests.size(); ++i)
{
UnitTest* const test = tests [i];
if (package.equalsIgnoreCase (test->getPackageName ()) &&
testname.equalsIgnoreCase (test->getClassName ()))
{
list.add (test);
break;
}
}
}
else
{
// Get all tests in the package
list = selectPackage (package, tests);
// If no trailing slash on package, try tests
if (list.size () == 0 && indexOfDot == -1)
{
std::cout << "Trying package as test" << std::endl;
// Try "package" as a testname
list = selectTest (package, tests);
}
}
}
else if (testname != String::empty)
{
list = selectTest (testname, tests);
}
else
{
// All non manual tests
for (int i = 0; i < tests.size(); ++i)
{
UnitTest* const test = tests [i];
if (test->getWhen () != UnitTest::runManual)
list.add (test);
}
}
return list;
}
UnitTests::TestList UnitTests::selectPackage (
String const& package, TestList const& tests) const noexcept
{
TestList list;
list.ensureStorageAllocated (tests.size ());
for (int i = 0; i < tests.size(); ++i)
{
UnitTest* const test = tests [i];
if (package.equalsIgnoreCase (test->getPackageName ()) &&
test->getWhen () != UnitTest::runManual)
list.add (test);
}
return list;
}
UnitTests::TestList UnitTests::selectTest (
String const& testname, TestList const& tests) const noexcept
{
TestList list;
for (int i = 0; i < tests.size(); ++i)
{
UnitTest* const test = tests [i];
if (testname.equalsIgnoreCase (test->getClassName ()))
{
list.add (test);
break;
}
}
return list;
}
UnitTests::TestList UnitTests::selectStartupTests (TestList const& tests) const noexcept
{
TestList list;
for (int i = 0; i < tests.size(); ++i)
{
UnitTest* const test = tests [i];
if (test->getWhen () == UnitTest::runStartup)
list.add (test);
}
return list;
}
void UnitTests::runSelectedTests (String const& match, TestList const& tests)
{
runTests (selectTests (match, tests));
}
void UnitTests::runTests (TestList const& tests)
{
m_results = new Results;
for (int i = 0; i < tests.size (); ++i)
{
if (shouldAbortTests())
break;
runTest (*tests [i]);
}
m_results->secondsElapsed = RelativeTime (
Time::getCurrentTime () - m_results->whenStarted).inSeconds ();
}
void UnitTests::runAllTests ()
{
UnitTest::TestList const& allTests (UnitTest::getAllTests ());
Array <UnitTest*> tests;
tests.ensureStorageAllocated (allTests.size ());
for (int i = 0; i < allTests.size(); ++i)
{
UnitTest* const test = allTests [i];
if (test->getWhen () == UnitTest::runNormal)
{
tests.add (test);
}
}
runTests (tests);
}
void UnitTests::runStartupTests ()
{
UnitTest::TestList const& allTests (UnitTest::getAllTests ());
Array <UnitTest*> tests;
tests.ensureStorageAllocated (allTests.size ());
for (int i = 0; i < allTests.size(); ++i)
{
UnitTest* const test = allTests [i];
if (test->getWhen () == UnitTest::runStartup)
{
tests.add (test);
}
}
runTests (tests);
}
void UnitTests::runTestsByName (String const& name)
{
UnitTest::TestList const& allTests (UnitTest::getAllTests ());
Array <UnitTest*> tests;
tests.ensureStorageAllocated (allTests.size ());
for (int i = 0; i < allTests.size(); ++i)
{
UnitTest* const test = allTests [i];
if (test->getPackageName () == name &&
(test->getWhen () == UnitTest::runNormal ||
test->getWhen () == UnitTest::runStartup))
{
tests.add (test);
}
else if (test->getClassName () == name)
{
tests.add (test);
break;
}
}
runTests (tests);
}
void UnitTests::onFailure ()
{
@@ -384,7 +426,7 @@ public:
case UnitTest::runStartup: s << "[FORCED] "; break;
};
s << test.getPackageName () << "/" << test.getClassName ();
s << test.getTestName ();
logMessage (s);
}

View File

@@ -199,6 +199,9 @@ public:
/** Destructor. */
virtual ~UnitTest();
/** Returns the fully qualified test name in the form <package>.<class> */
String getTestName() const noexcept;
/** Returns the class name of the test. */
const String& getClassName() const noexcept;
@@ -334,6 +337,8 @@ private:
class BEAST_API UnitTests : public Uncopyable
{
public:
typedef UnitTest::TestList TestList;
struct Results
{
Results ()
@@ -374,21 +379,99 @@ public:
//--------------------------------------------------------------------------
/** Selects zero or more tests from specified packages or test names.
The name can be in these formats:
""
<package | testname>
<package> "."
<package> "." <testname>
"." <testname>
""
An empty string will match all tests objects which are not
marked to be run manually.
<package | testname>
Selects all tests which belong to that package, excluding those
which must be run manually. If no package with that name exists,
then this will select the first test from any package which matches
the name. If the test is a manual test, it will be selected.
<package> "."
Selects all tests which belong to that package, excluding those
which must be run manually. If no package with that name exists,
then no tests will be selected.
<package> "." <testname>
Selects only the first test that matches the given testname and
package, regardless of the manual run setting. If no test with a
matching package and test name is found, then no test is selected.
"/" <testname>
Selects the first test which matches the testname, even if it
is a manual test.
Some examples of names:
"beast" All unit tests in beast
"beast.File" Just the File beast unit test
".Random" The first test with the name Random
@note Matching is not case-sensitive.
@param match The string used to match tests
@param tests An optional parameter containing a list of tests to match.
*/
TestList selectTests (String const& match = "",
TestList const& tests = UnitTest::getAllTests ()) const noexcept;
/** Selects all tests which match the specified package.
Tests marked to be run manually are not included.
@note Matching is not case-sensitive.
@param match The string used to match tests
@param tests An optional parameter containing a list of tests to match.
*/
TestList selectPackage (String const& package,
TestList const& tests = UnitTest::getAllTests ()) const noexcept;
/** Selects the first test whose name matches, from any package.
This can include tests marked to be run manually.
@note Matching is not case-sensitive.
@param match The name of the test to match.
@param tests An optional parameter containing a list of tests to match.
*/
TestList selectTest (String const& testname,
TestList const& tests = UnitTest::getAllTests ()) const noexcept;
/** Selects the startup tests.
A test marked as runStartup will be forced to run on launch.
Typically these are lightweight tests that ensure the system
environment will not cause the program to exhibit undefined behavior.
@param tests An optional parameter containing a list of tests to match.
*/
TestList selectStartupTests (TestList const& tests = UnitTest::getAllTests ()) const noexcept;
/** Run a list of matching tests.
This first calls selectTests and then runTeests on the resulting list.
@param match The string used for matching.
@param tests An optional parameter containing a list of tests to match.
*/
void runSelectedTests (String const& match = "",
TestList const& tests = UnitTest::getAllTests ());
/** Runs the specified list of tests.
This is used internally and won't normally need to be called.
@note The tests are run regardless of the run settings.
@param tests The list of tests to run.
*/
void runTests (Array <UnitTest*> const& tests);
/** Runs all the UnitTest objects that currently exist.
This calls @ref runTests for all the objects listed in @ref UnitTest::getAllTests.
*/
void runAllTests ();
/** Runs the startup tests. */
void runStartupTests ();
/** Run a particular test or group. */
void runTestsByName (String const& name);
void runTests (TestList const& tests);
protected:
friend class UnitTest;

View File

@@ -99,7 +99,7 @@ void Main::runStartupUnitTests ()
StartupUnitTests tests;
tests.runStartupTests ();
tests.runTests (tests.selectStartupTests ());
if (tests.anyTestsFailed ())
{

View File

@@ -174,7 +174,7 @@ private:
bool const m_shouldLog;
};
static int runUnitTests (String const& whichTests, String const& format)
static int runUnitTests (String const& match, String const& format)
{
bool const shouldLog = format != "junit";
@@ -187,14 +187,7 @@ static int runUnitTests (String const& whichTests, String const& format)
RippleUnitTests tr (shouldLog);
if (whichTests == "")
{
tr.runAllTests ();
}
else
{
tr.runTestsByName (whichTests);
}
tr.runSelectedTests (match);
if (format == "junit")
{