Testing Utilities and Test Management Module.
The imttest module provides testing infrastructure, test data management, and utilities for unit testing, integration testing, and test automation in ImtCore applications.
Overview
This module provides testing support:
- Test information and metadata
- Test instance management
- Test database delegates
- Test data providers
- Test collection management
- Test metadata creation
Architecture
Design Patterns
Data Transfer Object (DTO) Pattern:
- ITestInfo as pure test data container
- Separate interface from implementation
- Serializable test information
- Facilitates test data persistence
Provider Pattern:
- ITestInfoProvider supplies test data
- Abstraction over test data sources
- Enables mock test providers
- Facilitates test isolation
Delegate Pattern:
- CTestDatabaseDelegateComp for database persistence
- SQL query generation for test data
- Database-agnostic test storage
Meta-Info Pattern:
Core Interfaces
The module provides test management interfaces:
Test Information:
├─ GetTestId() / SetTestId() - Test identifier
├─ GetTestName() / SetTestName() - Test name
├─ GetTestDescription() / SetTestDescription() - Test description
└─ Extends iser::IObject for serialization
│
└─ CTestInfo (concrete implementation)
├─ Data object for test information
└─ Serializable test data
Test Data Provider:
├─ GetTestInfo() - Retrieve test information
├─ GetTestsByFilter() - Query tests
└─ Test data access abstraction
Test Metadata:
CTestMetaInfo (idoc::IDocumentMetaInfo)
├─ Test metadata structure
├─ MIT_TEST_ID - Test identifier metadata
├─ MIT_TEST_NAME - Test name metadata
└─ MIT_TEST_DESCRIPTION - Test description metadata
│
Test Database Persistence:
CTestDatabaseDelegateComp (imtdb::CSqlDatabaseDocumentDelegateComp)
├─ CreateNewObjectQuery() - SQL INSERT for tests
├─ CreateUpdateObjectQuery() - SQL UPDATE for tests
├─ CreateDeleteObjectsQuery() - SQL DELETE for tests
└─ Database persistence for test data
Usage Examples
Creating Test Information
Create Test Data:**
auto testInfo = CTestInfo::CreateInstance();
testInfo->SetTestId("TEST-001");
testInfo->SetTestName("User Authentication Test");
testInfo->SetTestDescription(
"Validates user authentication with valid and invalid credentials");
QByteArray testId = testInfo->GetTestId();
QString testName = testInfo->GetTestName();
QString description = testInfo->GetTestDescription();
qDebug() << "Test:" << testName << "ID:" << testId;
Database Storage
Store Tests in Database:**
auto testCollection = CSqlDatabaseObjectCollectionComp::CreateInstance();
auto testDelegate = CTestDatabaseDelegateComp::CreateInstance();
testCollection->SetAttribute("Delegate", testDelegate.get());
auto databaseEngine = GetDatabaseEngine();
testCollection->SetAttribute("DatabaseEngine", databaseEngine.get());
testCollection->SetAttribute("TableName", "tests");
testCollection->AddObject(testInfo.get());
auto filter = CreateFilterParams("test_name", "Authentication%");
auto authTests = testCollection->GetObjectsByFilter(filter.get());
qDebug() << "Found" << authTests.size() << "authentication tests";
Test Metadata
Create Test Metadata:**
auto metaInfoCreator = CTestMetaInfoCreatorComp::CreateInstance();
auto testMetaInfo = metaInfoCreator->CreateMetaInfo(testInfo.get());
QVariant testIdMeta = testMetaInfo->GetValue(
QVariant testNameMeta = testMetaInfo->GetValue(
QVariant testDescMeta = testMetaInfo->GetValue(
qDebug() << "Test Metadata:"
<< "ID:" << testIdMeta.toByteArray()
<< "Name:" << testNameMeta.toString()
<< "Description:" << testDescMeta.toString();
Test Provider
Implement Test Provider:**
class CTestSuiteProviderComp : public ACF_COMPONENT(ITestInfoProvider)
{
I_REFERENCE(IObjectCollection, m_testCollection)
public:
ITestInfo* GetTestInfo(
const QByteArray& testId)
const override
{
m_testCollection->GetObject(testId));
}
QList<ITestInfo*> GetTestsByCategory(const QString& category) const
{
auto filter = CreateFilterParams("category", category);
auto tests = m_testCollection->GetObjectsByFilter(filter.get());
QList<ITestInfo*> result;
for (auto test : tests) {
result.append(dynamic_cast<ITestInfo*>(test));
}
return result;
}
int GetTestCount() const
{
return m_testCollection->GetIds().size();
}
};
Integration Patterns
Unit Testing Integration
Pattern: Test Runner with Test Collection:**
class CTestRunnerComp : public ACF_COMPONENT(ITestRunner)
{
public:
void RunAllTests()
{
QList<ITestInfo*> tests = LoadAllTests();
int passed = 0;
int failed = 0;
qDebug() << "Running test:" << test->GetTestName();
bool result = ExecuteTest(test);
if (result) {
passed++;
qDebug() << " PASSED";
} else {
failed++;
qCritical() << " FAILED";
}
}
qDebug() << "Test Results:"
<< "Passed:" << passed
<< "Failed:" << failed
<< "Total:" << (passed + failed);
}
private:
QList<ITestInfo*> LoadAllTests()
{
return m_testProvider->GetAllTests();
}
bool ExecuteTest(ITestInfo* test)
{
QString testId = test->GetTestId();
return InvokeTestMethod(testId);
}
};
Test Reporting
Pattern: Test Results Collection:**
class CTestReportGeneratorComp : public ACF_COMPONENT(ITestReportGenerator)
{
public:
void GenerateTestReport(const QString& outputPath)
{
QList<ITestInfo*> tests = m_testProvider->GetAllTests();
QString html = "<html><head><title>Test Report</title></head><body>";
html += "<h1>ImtCore Test Report</h1>";
html += "<table border='1'>";
html += "<tr><th>Test ID</th><th>Test Name</th>"
"<th>Description</th></tr>";
html += QString("<tr>"
"<td>%1</td>"
"<td>%2</td>"
"<td>%3</td>"
"</tr>")
.arg(QString::fromUtf8(test->GetTestId()))
.arg(test->GetTestName())
.arg(test->GetTestDescription());
}
html += "</table></body></html>";
QFile file(outputPath);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
file.write(html.toUtf8());
file.close();
qDebug() << "Test report saved to:" << outputPath;
}
}
};
Best Practices
Test Organization
- Use consistent test ID naming conventions (e.g., TEST-MODULE-001)
- Group related tests by category or module
- Maintain test descriptions with clear objectives
- Store test data in version control
- Use database persistence for large test suites
Test Maintenance
- Update test descriptions when functionality changes
- Archive obsolete tests instead of deleting
- Version test data alongside application code
- Document test dependencies and prerequisites
- Regular review and cleanup of test database
Integration with Other Modules
With imtdb (Database Layer):
- Test data persistence in SQL databases
- Test collection management
- Query and filter test data
With imtbase (Core Infrastructure):
- Test collections and filters
- Serialization of test data
- ACF component integration
Testing Frameworks:
- Qt Test framework integration
- Google Test compatibility
- Custom test runners
References
Related Modules:
- imtdb - Database persistence
- imtbase - Core collections and serialization
Testing Frameworks:
External Documentation:
- Test-Driven Development (TDD)
- Unit Testing Best Practices