mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-22 21:36:11 +01:00
Improvements to self test to give finer grained feedback
This commit is contained in:
parent
2e444861c9
commit
13bfe477c7
@ -11,22 +11,51 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../catch_with_main.hpp"
|
#include "../catch_with_main.hpp"
|
||||||
|
|
||||||
#include "../internal/catch_self_test.hpp"
|
#include "../internal/catch_self_test.hpp"
|
||||||
|
|
||||||
TEST_CASE( "selftest/main", "Runs all Catch self tests and checks their results" )
|
TEST_CASE( "selftest/main", "Runs all Catch self tests and checks their results" )
|
||||||
{
|
{
|
||||||
Catch::EmbeddedRunner runner;
|
using namespace Catch;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
SECTION( "selftest/expected result",
|
||||||
|
"Tests do what they claim" )
|
||||||
|
{
|
||||||
|
SECTION( "selftest/expected result/failing tests",
|
||||||
|
"Tests in the 'failing' branch fail" )
|
||||||
|
{
|
||||||
|
MetaTestRunner::runMatching( "./failing/*", MetaTestRunner::Expected::ToFail );
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION( "selftest/expected result/succeeding tests",
|
||||||
|
"Tests in the 'succeeding' branch succeed" )
|
||||||
|
{
|
||||||
|
MetaTestRunner::runMatching( "./succeeding/*", MetaTestRunner::Expected::ToSucceed );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
SECTION( "selftest/test counts",
|
||||||
|
"Number of test cases that run is fixed" )
|
||||||
|
{
|
||||||
|
EmbeddedRunner runner;
|
||||||
|
|
||||||
|
SECTION( "selftest/test counts/succeeding tests",
|
||||||
|
"Number of 'succeeding' tests is fixed" )
|
||||||
|
{
|
||||||
|
runner.runMatching( "./succeeding/*" );
|
||||||
|
CHECK( runner.getSuccessCount() == 213 );
|
||||||
|
CHECK( runner.getFailureCount() == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
runner.runMatching( "./succeeding/*" );
|
SECTION( "selftest/test counts/failing tests",
|
||||||
INFO( runner.getOutput() );
|
"Number of 'failing' tests is fixed" )
|
||||||
CHECK( runner.getSuccessCount() == 213 );
|
{
|
||||||
CHECK( runner.getFailureCount() == 0 );
|
runner.runMatching( "./failing/*" );
|
||||||
|
CHECK( runner.getSuccessCount() == 0 );
|
||||||
runner.runMatching( "./failing/*" );
|
CHECK( runner.getFailureCount() == 54 );
|
||||||
INFO( runner.getOutput() );
|
}
|
||||||
CHECK( runner.getSuccessCount() == 0 );
|
}
|
||||||
CHECK( runner.getFailureCount() == 54 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE( "meta/Misc/Sections", "looped tests" )
|
TEST_CASE( "meta/Misc/Sections", "looped tests" )
|
||||||
|
@ -63,6 +63,18 @@ namespace Catch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ContainerT, typename Function>
|
||||||
|
inline void forEach( ContainerT& container, Function function )
|
||||||
|
{
|
||||||
|
std::for_each( container.begin(), container.end(), function );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ContainerT, typename Function>
|
||||||
|
inline void forEach( const ContainerT& container, Function function )
|
||||||
|
{
|
||||||
|
std::for_each( container.begin(), container.end(), function );
|
||||||
|
}
|
||||||
|
|
||||||
ATTRIBUTE_NORETURN
|
ATTRIBUTE_NORETURN
|
||||||
inline void throwLogicError( const std::string& message, const std::string& file, long line )
|
inline void throwLogicError( const std::string& message, const std::string& file, long line )
|
||||||
{
|
{
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
namespace Catch
|
namespace Catch
|
||||||
{
|
{
|
||||||
|
class TestCaseInfo;
|
||||||
|
|
||||||
struct IRunner
|
struct IRunner
|
||||||
{
|
{
|
||||||
virtual ~IRunner
|
virtual ~IRunner
|
||||||
|
@ -52,6 +52,10 @@ namespace Catch
|
|||||||
|
|
||||||
virtual const std::vector<TestCaseInfo>& getAllTests
|
virtual const std::vector<TestCaseInfo>& getAllTests
|
||||||
() const = 0;
|
() const = 0;
|
||||||
|
|
||||||
|
virtual std::vector<TestCaseInfo> getMatchingTestCases
|
||||||
|
( const std::string& rawTestSpec
|
||||||
|
) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,44 +56,6 @@ namespace Catch
|
|||||||
std::string& m_targetString;
|
std::string& m_targetString;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class TestSpec
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
TestSpec
|
|
||||||
(
|
|
||||||
const std::string& rawSpec
|
|
||||||
)
|
|
||||||
: m_rawSpec( rawSpec ),
|
|
||||||
m_isWildcarded( false )
|
|
||||||
{
|
|
||||||
if( m_rawSpec[m_rawSpec.size()-1] == '*' )
|
|
||||||
{
|
|
||||||
m_rawSpec = m_rawSpec.substr( 0, m_rawSpec.size()-1 );
|
|
||||||
m_isWildcarded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
bool matches
|
|
||||||
(
|
|
||||||
const std::string& testName
|
|
||||||
)
|
|
||||||
const
|
|
||||||
{
|
|
||||||
if( !m_isWildcarded )
|
|
||||||
return m_rawSpec == testName;
|
|
||||||
else
|
|
||||||
return testName.size() >= m_rawSpec.size() && testName.substr( 0, m_rawSpec.size() ) == m_rawSpec;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_rawSpec;
|
|
||||||
bool m_isWildcarded;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -50,7 +50,7 @@ namespace Catch
|
|||||||
m_output = oss.str();
|
m_output = oss.str();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
std::string getOutput
|
std::string getOutput
|
||||||
()
|
()
|
||||||
@ -79,6 +79,76 @@ namespace Catch
|
|||||||
std::size_t m_failures;
|
std::size_t m_failures;
|
||||||
std::string m_output;
|
std::string m_output;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MetaTestRunner
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Expected
|
||||||
|
{
|
||||||
|
enum Result
|
||||||
|
{
|
||||||
|
ToSucceed,
|
||||||
|
ToFail
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
static void runMatching
|
||||||
|
(
|
||||||
|
const std::string& testSpec,
|
||||||
|
Expected::Result expectedResult
|
||||||
|
)
|
||||||
|
{
|
||||||
|
forEach( Hub::getTestCaseRegistry().getMatchingTestCases( testSpec ),
|
||||||
|
MetaTestRunner( expectedResult ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
MetaTestRunner
|
||||||
|
(
|
||||||
|
Expected::Result expectedResult
|
||||||
|
)
|
||||||
|
: m_expectedResult( expectedResult )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
void operator()
|
||||||
|
(
|
||||||
|
const TestCaseInfo& testCase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EmbeddedRunner runner;
|
||||||
|
runner.runMatching( testCase.getName() );
|
||||||
|
switch( m_expectedResult )
|
||||||
|
{
|
||||||
|
case Expected::ToSucceed:
|
||||||
|
if( runner.getFailureCount() > 0 )
|
||||||
|
{
|
||||||
|
INFO( runner.getOutput() );
|
||||||
|
FAIL( "Expected test case '"
|
||||||
|
<< testCase.getName()
|
||||||
|
<< "' to succeed but there was/ were "
|
||||||
|
<< runner.getFailureCount() << " failure(s)" );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Expected::ToFail:
|
||||||
|
if( runner.getSuccessCount() > 0 )
|
||||||
|
{
|
||||||
|
INFO( runner.getOutput() );
|
||||||
|
FAIL( "Expected test case '"
|
||||||
|
<< testCase.getName()
|
||||||
|
<< "' to fail but there was/ were "
|
||||||
|
<< runner.getSuccessCount() << " success(es)" );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
Expected::Result m_expectedResult;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_SELF_TEST_HPP_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_SELF_TEST_HPP_INCLUDED
|
||||||
|
@ -157,6 +157,44 @@ namespace Catch
|
|||||||
std::string m_description;
|
std::string m_description;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class TestSpec
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
TestSpec
|
||||||
|
(
|
||||||
|
const std::string& rawSpec
|
||||||
|
)
|
||||||
|
: m_rawSpec( rawSpec ),
|
||||||
|
m_isWildcarded( false )
|
||||||
|
{
|
||||||
|
if( m_rawSpec[m_rawSpec.size()-1] == '*' )
|
||||||
|
{
|
||||||
|
m_rawSpec = m_rawSpec.substr( 0, m_rawSpec.size()-1 );
|
||||||
|
m_isWildcarded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
bool matches
|
||||||
|
(
|
||||||
|
const std::string& testName
|
||||||
|
)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
if( !m_isWildcarded )
|
||||||
|
return m_rawSpec == testName;
|
||||||
|
else
|
||||||
|
return testName.size() >= m_rawSpec.size() && testName.substr( 0, m_rawSpec.size() ) == m_rawSpec;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_rawSpec;
|
||||||
|
bool m_isWildcarded;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_TESTCASEINFO_HPP_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_TESTCASEINFO_HPP_INCLUDED
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <iostream> // !TBD DBG
|
||||||
namespace Catch
|
namespace Catch
|
||||||
{
|
{
|
||||||
class TestRegistry : public ITestCaseRegistry
|
class TestRegistry : public ITestCaseRegistry
|
||||||
@ -56,6 +57,28 @@ namespace Catch
|
|||||||
{
|
{
|
||||||
return m_functionsInOrder;
|
return m_functionsInOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
virtual std::vector<TestCaseInfo> getMatchingTestCases
|
||||||
|
(
|
||||||
|
const std::string& rawTestSpec
|
||||||
|
)
|
||||||
|
{
|
||||||
|
TestSpec testSpec( rawTestSpec );
|
||||||
|
|
||||||
|
std::vector<TestCaseInfo> testList;
|
||||||
|
std::vector<TestCaseInfo>::const_iterator it = m_functionsInOrder.begin();
|
||||||
|
std::vector<TestCaseInfo>::const_iterator itEnd = m_functionsInOrder.end();
|
||||||
|
for(; it != itEnd; ++it )
|
||||||
|
{
|
||||||
|
if( testSpec.matches( it->getName() ) )
|
||||||
|
{
|
||||||
|
testList.push_back( *it );
|
||||||
|
std::cout << it->getName() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return testList;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user