Skip to content

Commit

Permalink
Make unit tests fail faster (#71)
Browse files Browse the repository at this point in the history
Specifically, our custom recursive fuzzy XML compare routines were not
aborting on the first failure, as QVERIFY / QCOMPARE and friends do.

This change should also mean that small, repeated errors, like the
recent locale and rounding errors, finish much sooner on CI platforms
like Travis CI and Appveyor, and now longer bring down their Web UIs!
  • Loading branch information
pcolby committed Aug 23, 2016
1 parent 22e0bc4 commit c0072ca
Showing 1 changed file with 58 additions and 13 deletions.
71 changes: 58 additions & 13 deletions test/polar/v2/testtrainingsession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,35 +38,48 @@ Q_DECLARE_METATYPE(polar::v2::TrainingSession::OutputFormats)
// and toByteArray functions are both non-deterministic. Hence we have to roll
// our own QDomDocument comparison functions :(

// Much the same as QCOMPARE, execept that we check QTest::currentTestFailed
// (qFail would have already been called), and report a::nodeName() on failure.
#define XCOMPARE(actual, expected) \
do {\
compare(actual, expected);\
if (QTest::currentTestFailed()) {\
qInfo() << "Failed node path" << a.nodeName();\
return;\
}\
} while(0)

void compare(const QDomNode &a, const QDomNode &b);

// Find 'a' within 'b' by node name, and compare the two nodes.
void compare(const QDomNode &a, const QDomNamedNodeMap &b)
{
if (a.namespaceURI().isEmpty()) {
compare(a, b.namedItem(a.nodeName()));
XCOMPARE(a, b.namedItem(a.nodeName()));
} else {
compare(a, b.namedItemNS(a.namespaceURI(), a.localName()));
XCOMPARE(a, b.namedItemNS(a.namespaceURI(), a.localName()));
}
}

void compare(const QDomNamedNodeMap &a, const QDomNamedNodeMap &b)
{
QCOMPARE(a.length(), b.length());
for (int i = 0; i < a.length(); ++i) {
for (int i = 0; (i < a.length()) && (!QTest::currentTestFailed()); ++i) {
compare(a.item(i), b);
if (QTest::currentTestFailed()) continue;
compare(b.item(i), a);
}
}

void compare(const QDomNodeList &a, const QDomNodeList &b)
{
QCOMPARE(a.length(), b.length());
for (int i = 0; i < a.length(); ++i) {
for (int i = 0; (i < a.length()) && (!QTest::currentTestFailed()); ++i) {
compare(a.at(i), b.at(i));
}
}

void fuzzyCompare(const QString &a, const QString &b)
void compare(const QString &a, const QString &b)
{
// Only consider fuzzy comparisons for floating point numbers.
if ((a.contains(QLatin1Char('.'))) || (a.contains(QLatin1Char('.')))) {
Expand Down Expand Up @@ -95,35 +108,37 @@ void fuzzyCompare(const QString &a, const QString &b)

void compare(const QDomNode &a, const QDomNode &b)
{
compare(a.attributes(), b.attributes());
compare(a.childNodes(), b.childNodes());
XCOMPARE(a.attributes(), b.attributes());
XCOMPARE(a.childNodes(), b.childNodes());
QCOMPARE(a.localName(), b.localName());
QCOMPARE(a.namespaceURI(), b.namespaceURI());
QCOMPARE(a.nodeName(), b.nodeName());
QCOMPARE(a.nodeType(), b.nodeType());
fuzzyCompare(a.nodeValue(), b.nodeValue());
XCOMPARE(a.nodeValue(), b.nodeValue());
QCOMPARE(a.prefix(), b.prefix());
}

void compare(const QDomDocumentType &a, const QDomDocumentType &b)
{
compare(static_cast<const QDomNode &>(a), static_cast<const QDomNode &>(b));
compare(a.entities(), b.entities());
XCOMPARE(static_cast<const QDomNode &>(a), static_cast<const QDomNode &>(b));
XCOMPARE(a.entities(), b.entities());
QCOMPARE(a.internalSubset(), b.internalSubset());
QCOMPARE(a.name(), b.name());
QCOMPARE(a.nodeType(), b.nodeType());
compare(a.notations(), b.notations());
XCOMPARE(a.notations(), b.notations());
QCOMPARE(a.publicId(), b.publicId());
QCOMPARE(a.systemId(), b.systemId());
}

void compare(const QDomDocument &a, const QDomDocument &b)
{
compare(a.doctype(), b.doctype());
compare(a.documentElement(), b.documentElement());
XCOMPARE(a.doctype(), b.doctype());
XCOMPARE(a.documentElement(), b.documentElement());
QCOMPARE(a.nodeType(), b.nodeType());
}

#undef XCOMPARE

void TestTrainingSession::initTestCase()
{
outputDirPath = QString::fromLatin1("%1/%2").arg(QDir::tempPath())
Expand Down Expand Up @@ -841,6 +856,9 @@ void TestTrainingSession::toGPX()
QDomDocument expectedDoc;
expectedDoc.setContent(expected);
compare(gpx, expectedDoc);
if (QTest::currentTestFailed()) {
return;
}

// Validate the generated document against the relevant XML schema.
gpx.documentElement().removeAttribute(QLatin1String("xsi:schemaLocation"));
Expand Down Expand Up @@ -903,6 +921,9 @@ void TestTrainingSession::toGPX_AllExtensions()
QDomDocument expectedDoc;
expectedDoc.setContent(expected);
compare(gpx, expectedDoc);
if (QTest::currentTestFailed()) {
return;
}

// Validate the generated document against the relevant XML schema.
gpx.documentElement().removeAttribute(QLatin1String("xsi:schemaLocation"));
Expand Down Expand Up @@ -966,6 +987,9 @@ void TestTrainingSession::toGPX_Cluetrust()
QDomDocument expectedDoc;
expectedDoc.setContent(expected);
compare(gpx, expectedDoc);
if (QTest::currentTestFailed()) {
return;
}

// Validate the generated document against the relevant XML schema.
gpx.documentElement().removeAttribute(QLatin1String("xsi:schemaLocation"));
Expand Down Expand Up @@ -1054,6 +1078,9 @@ void TestTrainingSession::toGPX_GarminAcceleration()
QDomDocument expectedDoc;
expectedDoc.setContent(expected);
compare(gpx, expectedDoc);
if (QTest::currentTestFailed()) {
return;
}

// Validate the generated document against the relevant XML schema.
gpx.documentElement().removeAttribute(QLatin1String("xsi:schemaLocation"));
Expand Down Expand Up @@ -1136,6 +1163,9 @@ void TestTrainingSession::toGPX_GarminTrackPoint()
QDomDocument expectedDoc;
expectedDoc.setContent(expected);
compare(gpx, expectedDoc);
if (QTest::currentTestFailed()) {
return;
}

// Validate the generated document against the relevant XML schema.
gpx.documentElement().removeAttribute(QLatin1String("xsi:schemaLocation"));
Expand Down Expand Up @@ -1472,6 +1502,9 @@ void TestTrainingSession::toTCX()
QDomDocument expectedDoc;
expectedDoc.setContent(expected);
compare(tcx, expectedDoc);
if (QTest::currentTestFailed()) {
return;
}

// Validate the generated document against the relevant XML schema.
tcx.documentElement().removeAttribute(QLatin1String("xsi:schemaLocation"));
Expand Down Expand Up @@ -1532,6 +1565,9 @@ void TestTrainingSession::toTCX_AllExtensions()
QDomDocument expectedDoc;
expectedDoc.setContent(expected);
compare(tcx, expectedDoc);
if (QTest::currentTestFailed()) {
return;
}

// Validate the generated document against the relevant XML schema.
tcx.documentElement().removeAttribute(QLatin1String("xsi:schemaLocation"));
Expand Down Expand Up @@ -1594,6 +1630,9 @@ void TestTrainingSession::toTCX_GarminActivity()
QDomDocument expectedDoc;
expectedDoc.setContent(expected);
compare(tcx, expectedDoc);
if (QTest::currentTestFailed()) {
return;
}

// Validate the generated document against the relevant XML schema.
tcx.documentElement().removeAttribute(QLatin1String("xsi:schemaLocation"));
Expand Down Expand Up @@ -1685,6 +1724,9 @@ void TestTrainingSession::toTCX_GarminCourse()
QDomDocument expectedDoc;
expectedDoc.setContent(expected);
compare(tcx, expectedDoc);
if (QTest::currentTestFailed()) {
return;
}

// Validate the generated document against the relevant XML schema.
tcx.documentElement().removeAttribute(QLatin1String("xsi:schemaLocation"));
Expand Down Expand Up @@ -1761,6 +1803,9 @@ void TestTrainingSession::toTCX_UTC()
QDomDocument expectedDoc;
expectedDoc.setContent(expected);
compare(tcx, expectedDoc);
if (QTest::currentTestFailed()) {
return;
}

// Validate the generated document against the relevant XML schema.
tcx.documentElement().removeAttribute(QLatin1String("xsi:schemaLocation"));
Expand Down

0 comments on commit c0072ca

Please sign in to comment.