【问题标题】:What is the purpose of unit testing?单元测试的目的是什么?
【发布时间】:2011-12-23 15:04:59
【问题描述】:

出于学习目的,我潜入了单元测试领域。我使用 QT 阅读了一些关于这个问题的教程,并提出了以下内容:

class QMyUnitTest : public QObject
{
    Q_OBJECT
private:
    bool isPrime(unsigned int ui);
private Q_SLOTS:
    void myTest();
};

bool QMyUnitTest::isPrime(unsigned int n) {
    typedef std::map<unsigned int, bool> Filter;
    Filter filter;

    for(unsigned int ui = 2; ui <= n; ui++) {
        filter[ui] = true;
    }
    unsigned int ui = filter.begin()->first;
    for(Filter::iterator it = filter.begin();
        it != filter.end(); it++) {
        if(it->second) {
            for(unsigned int uj = ui * ui; uj <= n; uj += ui) {
                filter[uj] = false;
            }
        }
        ui++;
    }
    return filter[n];
}

void QMyUnitTest::myTest() {
}

QTEST_MAIN(QMyUnitTest)
#include "tst_myunittest.moc"

我知道我的素数查找算法效率低下,尤其是有缺陷;就是这个意思。现在我想彻底测试一下,但出现了以下问题:

要正确测试,我是否不必非常准确地了解可能出现的问题?

当然,我可以遍历前 1000 个素数并检查它们是否出现 true 或 1000 个不是素数并检查它们是否出现 false,但这可能无法发现算法中的缺陷(对于例如:return filter[n]; 显然很可怕,因为如果n&lt;2 可能不存在filter[n])。

如果我已经必须知道我的功能的潜在问题是什么,那么单元测试有什么用?

我做错了吗?有没有更好的测试方法?

【问题讨论】:

  • 请修改您的标题以包含用于描述您的问题的标签以外的其他内容。例如,“单元测试的目的是什么?”
  • 谢谢你的建议,我改了。

标签: c++ unit-testing qt testing


【解决方案1】:

单元测试的目的是验证您编写的代码是否确实完成了它应该做的事情。

要编写正确和完整的测试,您需要准确地知道您的代码应该做什么。然后编写测试来验证:

  • 正常条件(即“正常”、“常规”输入产生预期输出)
  • 边界条件(即勉强符合规范的输入)
  • 失败条件(即当输入无效时,您验证代码是否正确失败)。

您使用无法处理的数字测试isPrime 例程的行为的示例是一个很好的示例。在不了解您的实现的情况下,0、1、2 和负值将是 isPrime 例程的良好测试用例 - 它们是您在实现算法时可能不会考虑的事情,因此它们是有价值的测试。

请注意,验证正常情况不一定是最简单的部分。在这种情况下,确保您的算法完美需要进行数学分析,然后验证您的代码是否正确实现 - 这有时很难。检查几百个已知值不一定足够(它可能从第 101 个值开始失败)。

如果我已经必须知道我的功能的潜在问题是什么,那么单元测试有什么用?

你把它弄反了。不要在考虑实现代码的情况下编写单元测试。写下它时要牢记规范。您的代码必须符合规范,并且您的测试必须尽可能确保符合规范。 (代码覆盖工具将帮助您在完成大部分测试后找到边界条件。)

【讨论】:

  • 负数不是unsigned ints 的好例子
  • +1 用于写出我正在使用的完全相同的句子:“你把它颠倒了。”
  • 是和不是。过去,有符号到无符号转换(或相反,或有符号/无符号比较)已经困扰了不止一个 C(或 C++)开发人员,而且我认为这种情况不会很快改变。 (在这种特定情况下,-1 只需在其中输入将需要一点时间才能完成,假设编译器警告已被忽略)
  • 谢谢你的详细描述,我想我开始明白了。你提到了代码覆盖工具,在搜索之后我发现了很多。您是否碰巧知道某个特定的用于入门目的的产品?
  • @nijansen:我只是使用gcov,但确实有很多。很大程度上取决于您的工具链和环境。
【解决方案2】:

只想添加到 Mat 已经列出的内容:

  • 单元测试将确保您和其他在未来处理您的代码的人不会意外更改您的代码的行为。

  • 如果编写正确,单元测试将是记录代码行为的好方法。

【讨论】:

  • 对这一重要点的一点扩展:代码从来没有像第一次编写时那样被理解。单元测试是一种以自动可测试的方式写下有关预期代码行为的知识的方法。因此,这些单元测试是您向未来的维护者传达的信息,您预计会出错或正确。
  • 是的。尽可能早地编写测试——最好是使测试通过的实现代码之前。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
  • 2010-11-07
相关资源
最近更新 更多