Skip to content

Commit f39f567

Browse files
authored
refs #12080 - testrunner: do not create test implementation until it is used (cppcheck-opensource#6691)
Greatly improves the start-up time because it no longer needs to create all the implementations before it runs any test. The following times are using a debug build. Before: `bin/testrunner TestColor 1,16s user 0,07s system 99% cpu 1,235 total` After: `bin/testrunner TestColor 0,00s user 0,00s system 88% cpu 0,009 total`
1 parent a25bc07 commit f39f567

3 files changed

Lines changed: 27 additions & 12 deletions

File tree

test/fixture.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@
4141
**/
4242
namespace {
4343
struct CompareFixtures {
44-
bool operator()(const TestFixture* lhs, const TestFixture* rhs) const {
44+
bool operator()(const TestInstance* lhs, const TestInstance* rhs) const {
4545
return lhs->classname < rhs->classname;
4646
}
4747
};
4848
}
49-
using TestSet = std::set<TestFixture*, CompareFixtures>;
49+
using TestSet = std::set<TestInstance*, CompareFixtures>;
5050
namespace {
5151
class TestRegistry {
5252
TestSet _tests;
@@ -57,7 +57,7 @@ namespace {
5757
return testreg;
5858
}
5959

60-
void addTest(TestFixture *t) {
60+
void addTest(TestInstance *t) {
6161
_tests.insert(t);
6262
}
6363

@@ -67,7 +67,11 @@ namespace {
6767
};
6868
}
6969

70-
70+
TestInstance::TestInstance(const char * _name)
71+
: classname(_name)
72+
{
73+
TestRegistry::theInstance().addTest(this);
74+
}
7175

7276

7377
/**
@@ -83,9 +87,7 @@ std::size_t TestFixture::succeeded_todos_counter = 0;
8387

8488
TestFixture::TestFixture(const char * const _name)
8589
: classname(_name)
86-
{
87-
TestRegistry::theInstance().addTest(this);
88-
}
90+
{}
8991

9092

9193
bool TestFixture::prepareTest(const char testname[])
@@ -389,10 +391,11 @@ std::size_t TestFixture::runTests(const options& args)
389391
classname.erase(classname.find("::"));
390392
}
391393

392-
for (TestFixture * test : TestRegistry::theInstance().tests()) {
394+
for (TestInstance * test : TestRegistry::theInstance().tests()) {
393395
if (classname.empty() || test->classname == classname) {
394-
test->processOptions(args);
395-
test->run(testname);
396+
TestFixture* fixture = test->create();
397+
fixture->processOptions(args);
398+
fixture->run(testname);
396399
}
397400
}
398401
}

test/fixture.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,18 @@ class TestFixture : public ErrorLogger {
283283
static std::size_t runTests(const options& args);
284284
};
285285

286+
class TestInstance {
287+
public:
288+
explicit TestInstance(const char * _name);
289+
virtual ~TestInstance() = default;
290+
291+
virtual TestFixture* create() = 0;
292+
293+
const std::string classname;
294+
protected:
295+
std::unique_ptr<TestFixture> impl;
296+
};
297+
286298
// TODO: most asserts do not actually assert i.e. do not return
287299
#define TEST_CASE( NAME ) do { if (prepareTest(#NAME)) { setVerbose(false); try { NAME(); teardownTest(); } catch (...) { assertNoThrowFail(__FILE__, __LINE__); } } } while (false)
288300
#define ASSERT( CONDITION ) if (!assert_(__FILE__, __LINE__, (CONDITION))) return
@@ -306,7 +318,7 @@ class TestFixture : public ErrorLogger {
306318
#define TODO_ASSERT( CONDITION ) do { const bool condition=(CONDITION); todoAssertEquals(__FILE__, __LINE__, true, false, condition); } while (false)
307319
#define TODO_ASSERT_EQUALS( WANTED, CURRENT, ACTUAL ) todoAssertEquals(__FILE__, __LINE__, WANTED, CURRENT, ACTUAL)
308320
#define EXPECT_EQ( EXPECTED, ACTUAL ) assertEquals(__FILE__, __LINE__, EXPECTED, ACTUAL)
309-
#define REGISTER_TEST( CLASSNAME ) namespace { CLASSNAME instance_ ## CLASSNAME; }
321+
#define REGISTER_TEST( CLASSNAME ) namespace { class CLASSNAME ## Instance : public TestInstance { public: CLASSNAME ## Instance() : TestInstance(#CLASSNAME) {} TestFixture* create() override { impl.reset(new CLASSNAME); return impl.get(); } }; CLASSNAME ## Instance instance_ ## CLASSNAME; }
310322

311323
#define PLATFORM( P, T ) do { std::string errstr; assertEquals(__FILE__, __LINE__, true, P.set(Platform::toString(T), errstr, {exename}), errstr); } while (false)
312324

test/testmemleak.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include <cstddef>
2828
#include <list>
2929

30-
class TestMemleak : private TestFixture {
30+
class TestMemleak : public TestFixture {
3131
public:
3232
TestMemleak() : TestFixture("TestMemleak") {}
3333

0 commit comments

Comments
 (0)