Qt 中的数据重新驱动测试

Data re-driven testing in Qt

我能否让 QTest 多次使用单个数据驱动集?


我们使用 Qt 的 QTest 框架进行项目中的低级测试,并在有意义的地方使用数据驱动的风格。

我已经到了想要对一组测试数据进行几组不同测试的地步。明显的设计是

void testcalss::teststuff_data()
{
    QTest::addColumn<int>("number");
    QTest::addColumn<double>("size");

    QTest::newRow("first") << 1 << 3.14;
    QTest::newRow("second") << 42 << 2.718;
}

void testclass::teststuff()
{
    QFETCH(int, number);
    QFETCH(double, value);

    // Test one thing about this stuff
    QCOMPARE( f(number), value );      // <=== If it fails here ...

    // test some other thing
    QCOMPARE( g(number), h(value));    // <=== ... it doesn't even try this
}

文档或多或少是对的,对吗?

但一个小烦恼是,如果早期测试失败,它会缩短后续测试的方式(注释中的注释)。有时这是一种期望的行为,有时不是,但现在我希望它尝试第二次测试,即使第一次测试失败了。

可能的替代实施方案是

void testcalss::teststuff_data()
{
    QTest::addColumn<int>("number");
    QTest::addColumn<double>("size");

    QTest::newRow("first") << 1 << 3.14;
    QTest::newRow("second") << 42 << 2.718;
}

void testclass::teststuff()
{
    QFETCH(int, number);
    QFETCH(double, value);

    QCOMPARE( f(number), value );      
}

void testclass::teststuff2()
{
    QFETCH(int, number);              // <=== No data!
    QFETCH(double, value);

    QCOMPARE( g(number), h(value));    

}

但是,当然,来自 teststuff_data() 的输入在 teststuff2 开始时已经被消耗。

这个技巧是 re-invoke Qt 识别为设置一些数据的上下文中的先前代码。一种只调用旧方法的新 _data 方法不需要任何代码重复。

void testcalss::teststuff_data()
{
    QTest::addColumn<int>("number");
    QTest::addColumn<double>("size");

    QTest::newRow("first") << 1 << 3.14;
    QTest::newRow("second") << 42 << 2.718;
}

void testclass::teststuff()
{
    QFETCH(int, number);
    QFETCH(double, value);
    QCOMPARE( f(number), value );
}

void testclass::teststuff2_data()    // <=== define a _data method that ...
{
    teststuff_data();                // <=== ... re-runs the previous set-up
}

void testclass::teststuff2()
{
    QFETCH(int, number);
    QFETCH(double, value);

    QCOMPARE( g(number), h(value));
}

像往常一样,测试框架对方法声明的顺序很敏感,所以 header 应该看起来像

class testclass: public QObject
{
   Q_OBJECT

// c'tor and what not ...

private slots:
   void teststuff_data();
   void teststuff;

   void teststuff2_data();
   void teststuff2;
}