我最近花了大约70%的时间编写功能编写集成测试。有一次,我在想“该死,所有这些努力测试它,我知道我这里没有虫子,为什么我这么努力?我们只是略过测试并完成它......“
五分钟后,测试失败。详细检查表明,这是我们正在使用的第三方库中一个重要的,未知的错误。
那么......你在哪里可以测试什么来考验信仰?您是否测试了所有内容,或者您预期大多数错误的代码?
答案 0 :(得分:16)
在我看来,在测试方面务实是务实的。优先考虑最有可能失败的事情的测试工作,和/或最重要但不会失败的事情(即考虑概率和后果)。
请考虑,而不是盲目地遵循代码覆盖等一个指标。
当您对测试套件和代码感到满意时停止。当(如果?)事情开始失败时,返回并添加更多测试。
答案 1 :(得分:4)
如果您不再害怕在代码中进行中等到重大的更改,那么您可能已经获得了足够的测试。
答案 2 :(得分:3)
好问题!
首先 - 听起来你的广泛集成测试得到了回报:)
根据我的个人经验:
多少钱够了?艰难的问题 - 我不认为有足够的东西!
答案 3 :(得分:3)
“太多的东西都足够了。”
我没有遵循严格的TDD做法。我尝试编写足够的单元测试来覆盖所有代码路径,并运用我认为重要的任何边缘情况。基本上我试着预测会出现什么问题。我还尝试将我编写的测试代码量与我认为测试代码的脆弱程度相匹配。
我在一个方面很严格:如果发现错误,我首先编写一个测试来修复错误并失败,更改代码,并验证测试是否通过。
答案 4 :(得分:2)
Gerald Weinberg的经典着作“The Psychology of Computer Programming"有许多关于测试的好故事。我特别喜欢的是第4章”Programming as a Social Activity“”Bill“要求同事审查他的代码和他们在13个语句中找到了17个错误。代码审查提供额外的眼睛来帮助发现错误,你使用的眼睛越多,你就越有可能找到如此微妙的错误。就像Linus说的那样,“如果有足够的眼球,所有的错误都很浅“你的测试基本上都是机器人眼睛,他们会在白天或晚上的任何时间多次查看你的代码,让你知道一切是否仍然是犹太人。
多少测试足够取决于您是从头开发还是维护现有系统。
从头开始,您不希望花费所有时间编写测试并最终无法交付,因为您能够编码的10%的功能都经过了详尽的测试。将有一些优先级要做。一个例子是私人方法。由于私有方法必须由以某种形式(公共/包/受保护)可见的代码使用,因此可以认为私有方法在更可见方法的测试中被涵盖。如果私有代码中存在一些重要或模糊的行为或边缘情况,则需要在此处包含一些白盒测试。
测试应该帮助您确保1)了解要求,2)通过编写可测试性来遵循良好的设计实践,以及3)了解以前现有代码何时停止工作。如果您无法描述某些功能的测试,我愿意打赌您不能很好地理解该功能以便干净地编写代码。使用单元测试代码会强迫你做一些事情,比如传入像数据库连接或实例工厂那样重要的事情,而不是屈服于让班级自己做太多而变成“上帝”对象的诱惑。让您的代码成为您的金丝雀意味着您可以自由编写更多代码。当先前通过的测试失败时,它意味着两件事之一,即代码不再符合预期,或者特征的要求已经改变,测试只需要更新以适应新的要求。
使用现有代码时,您应该能够显示已涵盖所有已知方案,以便在下一个更改请求或错误修复发生时,您可以自由地挖掘您认为合适的任何模块而无需唠叨担心,“如果我破坏了什么”会导致花费更多时间测试甚至小修复,那么实际更改代码就会花费。
所以,我们不能给你一个快速和快速的测试数量,但是你应该进行一定程度的覆盖,这会增加你对继续进行更改或添加功能的能力的信心,否则你可能已达到了这一点收益减少。
答案 5 :(得分:1)
如果您或您的团队一直在跟踪指标,您可以看到随着软件生命周期的进展,每次测试都会发现多少错误。如果您已经定义了一个可接受的阈值,其中测试所花费的时间不能证明找到的错误数量,那么那就是您应该停止的点。
您可能永远不会找到100%的错误。
答案 6 :(得分:0)
我测试一切。我讨厌它,但这是我工作的重要部分。
答案 7 :(得分:0)
我花了很多时间进行单元测试,但很少进行集成测试。单元测试允许我以结构方式构建特征。现在你有一些很好的文档和回归测试可以在每次构建时运行
集成测试是另一回事。它们难以维护,并且根据定义集成了许多不同的功能,通常是难以使用的基础结构。
答案 8 :(得分:0)
与生活中的一切一样,它受时间和资源以及相对于其重要性的限制。理想情况下,您将测试您认为可能会破坏的所有内容。当然,您的估计可能是错误的,但是确保您的假设是正确的,取决于错误的重要程度与转移到下一个功能/发布/项目的需要有关。
注意:我的回答主要涉及集成测试。 TDD非常不同。它之前被SO覆盖,当你没有更多功能可以添加时,你会停止测试。 TDD是关于设计,而不是错误发现。
答案 9 :(得分:0)
在成为开发人员之前,我在QA工作了1。5年。
你永远不能测试一切(我被告知在训练时,单个文本框的所有排列都需要比已知宇宙更长的时间)。
作为开发人员,无法了解或说明测试重要性和不测试内容的优先级。最终产品的测试和质量是一项责任,但只有客户才能有意义地说明功能的优先级,除非他们明确地对您负责。如果没有QA团队并且您不知道,请要求项目经理找出并确定优先顺序。
测试是一项风险降低练习,客户/用户将知道什么是重要的,什么不是。使用极限编程中的第一个驱动开发测试将会很有帮助,因此您有一个良好的测试基础,并且可以在更改后进行回归测试。
重要的是要注意,由于自然选择代码可以对测试“免疫”。代码完成说,在修复缺陷以为其编写测试用例并查找类似缺陷时,为类似的缺陷编写测试用例也是一个好主意。
答案 10 :(得分:0)
我更喜欢尽可能地进行单元测试。其中一个最大的副作用(除了提高代码质量和帮助防止一些错误)在我看来,高单元测试期望需要一个来改变他们编写代码的方式为了更好。至少,这就是它对我的影响。
我的课程更具凝聚力,更易于阅读,更灵活,因为它们的设计功能强大且可测试。
也就是说,我使用junit和cobertura(对于Java)默认单位测试覆盖率要求为90%(线和分支)。当我觉得由于特定类的性质(或者cobertura中的错误)而无法满足这些要求时,我就会例外。
单元测试从覆盖范围开始,当您使用它们来逼真地测试边界条件时,它真的适合您。有关如何实现该目标的建议,其他答案都是正确的。
答案 11 :(得分:0)
This article为使用不同数量的用户进行用户测试的有效性提供了一些非常有趣的见解。它表明,只有三个用户可以测试应用程序,您可以找到大约三分之二的错误,而只有五个用户可以找到85%的错误。
单位测试更难以设置离散值。需要记住的一个建议是,单元测试可以帮助您组织有关如何开发正在测试的代码的想法。一旦你编写了一段代码的要求并且有办法可靠地检查它,你就可以更快更可靠地编写它。