出于学习目的,我潜入了单元测试领域。我已经阅读了一些使用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];
显然很糟糕,因为如果filter[n]
)n<2
可能不存在。
如果我必须知道我的功能有哪些潜在问题,那么单元测试有什么用?
我做错了吗?有没有更好的测试方法?
答案 0 :(得分:14)
单元测试的目的是验证您编写的代码是否实际执行了它应该执行的操作。
要编写正确且完整的测试,您需要准确了解代码应该执行的操作。然后编写测试以验证:
使用未处理的数字测试isPrime
例程的行为的示例是一个很好的例子。在不知道您的实现的情况下,0,1,2和负值将是isPrime
例程的良好测试用例 - 它们是您在实现算法时可能不会考虑的事情,因此它们是有价值的测试。
请注意,验证正常情况不一定是最简单的部分。在这种情况下,确保您的算法是完美的,需要进行数学分析,然后验证您的代码是否正确实现 - 这有时很难。检查几百个已知值不一定足够(它可能会在第101个值处失败)。
如果我必须知道我的功能有哪些潜在问题,那么单元测试有什么用?
你已经逆转了。不要在考虑实施代码的情况下编写单元测试。写下它时要考虑到规范。您的代码必须符合规范,您的测试必须尽可能地确保。 (代码覆盖率工具将帮助您在完成大部分测试后找到边界条件。)
答案 1 :(得分:9)
只想添加Mat已列出的内容:
单元测试将确保您和将来处理代码的其他人不会意外更改代码的行为。
如果写得正确,单元测试将是记录代码行为的好方法。