测试代码时你会犯的 11 个错误

我遇到的大多数开发人员都不怎么热衷于测试。有些会去做测试,但大多数都不测试,不愿意测试,或者勉而为之。我喜欢测试,并且比起编写新的代码,愉快地花更多的时间在测试中。我认为,正是因为专注于测试,我才可以花更少的时间来编写新的代码或修复bug,并且非常有成效。

如果你不确定要不要编写测试或者并不常写测试,那么,下面这些内容将指导你往一个更好的方向发展。

1.没有测试

我们很容易毫无原因地掉入这个陷阱。从现在开始,制定计划添加测试到你现在正在处理的代码中,并添加测试到将来的项目中。

2.没有从项目一开始就启动测试

我们很难再回过头去添加测试,并且可能需要改变架构才能添加测试,这样做最终将需要你花更长的时间才能产出可信任的代码。从一开始就在项目的生命周期添加测试可以节省时间和精力。

3.编写失败的测试

TDD方法的普及将红—绿—重构的理念带到软件测试世界。这个理念常常被误认为应该“通过编写一个失败的测试开始”。其实并非如此。在写代码之前创建测试的目的是定义系统的正确行为应该是什么。在许多情况下,它是一个失败的测试(红色表示),但它可能会通过一个非决定性的或未实现的测试来表示。

4.担心未实现测试

软件开发中的一个大问题就是,代码和任何关于系统实际上应该做什么的文档之间的沟壑。通过拥有一个名称中明确定义你最终想要实现的预期行为的测试,你将从测试中得到一定的价值,即使将怎么写测试目前还不得知。

5.没有很好地命名测试

命名软件这件事出了名的很难做好,这同样适用于测试。关于如何命名测试有几种流行的约定。无论你使用哪一种都没有关系,只要你能够一贯使用,并准确描述正在测试什么。

6.让测试做太多事情

又长又复杂的名字通常说明了你想同时测试多件事情。单个测试应该只测试一件事情。如果失败了也应该在代码中注明是什么地方出了错。你没有必要为了知道代码中出了什么问题而查看是哪部分测试失败。这并不意味着你不应该在测试中有多个断言,但这些断言应该紧密相关。例如,一个查看订单处理系统输出,并确认输出中是否有一个单一项目以及它是否包含具体项目的测试,是ok的。但一个验证相同系统的输出的测试,既创建一个特定项目,又记录到数据库中,还发送确认电子邮件,就不行了。

7.没有实际测试代码

经常可以看到测试新手创建过于复杂的模型以及不能实际测试代码的设置程序。他们可能会验证模拟代码是否正确,或者模拟代码是否和真正代码做相同的事情,或没有任何断言而只是执行代码。这样的“测试”都是白费力气,特别是如果它们的存在只是为了提高代码覆盖率水平的话。

8.担心代码覆盖率

代码覆盖率的理念很崇高,但往往实际价值有限。知道运行测试的时候有多少代码被执行应该是有用的,但因为它不考虑正在执行代码的测试的质量,因此就变得没有意义。代码覆盖率在它数值非常高或非常低的时候,是挺博人眼球的。如果非常高,就表明,比起带来的价值,过多的代码可能正在被测试。非常低的代码覆盖率表明有可能代码的测试不够。因为这样模棱两可的意思,有的人就不知道单一片段的代码是否应该进行测试。我用一个简单的问题来明确这一点:代码是否包含重大的复杂性?如果包含,那么你需要一些测试。如果没有的话,你就不需要。测试属性访问器不过是浪费时间。如果它们失败的话,那么比起你正在写的代码,你的代码体系出现了一些更根本的问题。如果你不用看一段代码,就立即知道一切,那么它就不重大。这不仅适用于代码,也适用于你写代码。如果我们在任意点重访代码,那么它就需要测试。如果在现有代码中发现过bug,那就说明这一块的代码对其复杂性没有进行充分的测试。

9.着眼于一种类型的测试

一旦你开始测试,很容易只纠结于一种风格的测试。这是一个错误。只用一种类型的测试,你就不能充分测试系统的所有部分。你需要单元测试来确认代码的各个组件是否能够正确工作。你需要集成测试来确认不同组件是否能够协同工作。你需要自动化UI测试来验证软件是否可以如预期使用。最后,你需要为任何不容易自动化的部分和探索性尝试进行手动测试。

10.着眼于短期测试

来自于测试的价值大多数会随着时间的推移而获得。测试不应该只存在用于确认事情是否正确写入,而应该随着时间的推移继续起作用,并且对于代码库做其他的改变。有回归错误或新的异常,那么测试应该重复运行以尽早发现问题,这将意味着错误和异常可以更快,更便宜和更容易被修复。没有变化(人为错误)可自动和快速执行的测试,是为什么编码测试如此有价值的原因。

11.作为一个开发者,依靠于别人来运行(或编写)测试

如果不运行,那么测试几乎没有价值。如果测试不能被运行,那么就可能遗漏bug。自动运行的测试(作为一个持续集成系统的一部分)是一个开始,但项目的任何一个人都应该能够随时运行测试。如果需要特殊设置,机器,权限,或配置来运行测试,那么这些将成为执行测试的壁垒。开发者需要能够在检查代码之前就运行测试,因此他们需要能够访问并有运行所有相关测试的权力。代码和测试应保持在同一个地方,并且所需的任何设置都应该写好脚本。关于这个方面我见过的最坏的例子是一个做的很糟糕的项目,在这个项目中测试人员的子团队定期取走开发人员正在处理的代码副本,他们修改代码以便他们能执行一系列测试,但这些测试是开发人员在特殊配置(无证)的机器上所无法访问的,然后测试人员再发送一个很大的邮件给所有的开发人员以说明他们找到的问题。这不仅是一个坏的测试方式,而且也是团队工作的糟糕方式。不要这样做。代码能够正确执行是专业开发人员的部分属性。要保证代码的准确性,方法是使用伴随它的适当测试。依靠其他人为你写的代码编写测试和运行测试,不会帮助你成为一个专业的开发人员。

如果以上这些都不属于你的情况,那么恭喜你!继续保持开发稳健又有价值的软件。

如果上面有一些确实发生在你身上,那么是时候做一些改变了。

转自:http://www.kuqin.com/shuoit/20160808/352732.html

时间: 2024-10-10 00:27:13

测试代码时你会犯的 11 个错误的相关文章

《职业经理人常犯的11个错误》——余世维

相比<赢在执行力>,余博士<职业经理人常犯的11个错误>所谈到的问题更为尖锐,每个问题都一针见血地挑出作为一个处于工作中的人(不仅仅是职业经理)习惯性所容易犯的错误. 第一个错误:拒绝承担责任.“圣人千虑,必有一失”,每个人在日常工作中难免会有犯错误的时候,有效的管理者.有效的员工应该果断为事情的结果承担责任.余博士指出:与其不停地辩解,还不如努力地表现.一句“对不起,这是我的错”.“对不起,我失察了”.“对不起,我刚才犯了个错误”能让事情马上有了结果,直接进入解决错误的局面.因此

必看 :大数据挖掘中易犯的11大错误

0.缺乏数据(LackData) 对于分类问题或预估问题来说,常常缺乏准确标注的案例. 例如: 欺诈侦测(FraudDetection):在上百万的交易中,可能只有屈指可数的欺诈交易,还有很多的欺诈交易没有被正确标注出来,这就需要在建模前花费大量人力来修正. 信用评分(CreditScoring):需要对潜在的高风险客户进行长期跟踪(比如两年),从而积累足够的评分样本. 1.太关注训练(FocusonTraining) IDMer:就象体育训练中越来越注重实战训练,因为单纯的封闭式训练常常会训练

职业经理人常犯的11种错误-余世维

★课程提纲 ——通过本课程,您能学到什么? 第一讲 拒绝承担个人责任 1. 引言 2.          有效的管理者,为事情的结果负责 3.          “努力的表现”与“不停的辩解” 4.          观察你自己,别光是观察市场/管区/办公室/人手 第二讲 未能启发工作人员 1.          引言 2.          离开办公室一天,不会引发混乱 3.          主管需要“少不了他们”的感觉 4.          未能自己训练员工,提升其绩效 5.     

Junit测试代码时出现initializationError 错误

首先代码没有错误,执行Junit测试时出现以上错误.上网查资料发现少了包 从网上下载了一个jar包解决了hamcrest-core-1.3.jar 现在下载包搜索的好多坑,有的网站必须注册才能下载,而且下载的有的还是 很垃圾.所以给大家推荐一个下载网站:http://www.java2s.com  平时找包就so easy了

pytorch代码中同时包含训练和测试代码时显存爆炸

原因在于没有使用torch.no_grad()函数.在查看验证集和测试集表现时,应使用类似这样的代码 def evaluate(data_loader): with torch.no_grad(): mean_acc, mean_iou = 0, 0 for i, (img, gnd) in enumerate(data_loader): if torch.cuda.is_available(): img = img.cuda(device=device) gnd = gnd.cuda(devi

今天写测试代码时遇到的小坑

#!/usr/bin/env python class Animal(object): nane = 'rrrr' def __init__(self): self.name = 66666 print(self.name) def greet(self): print ('Hello, I am %s.' % self.name) @classmethod def jk(self): print(33333333) self.hk() @staticmethod def hk(): print

小白学PYTHON时最容易犯的6个错误,看看你遇到过几个

最近又在跟之前的同学一起学习python,一起进步,发现很多测试同学在初学python的时候很容易犯一些错误,特意总结了一下.其实这些错误不仅是在学python时会碰到,在学习其他语言的时候也同样会碰到. 错误1: 缩进 python是强制缩进的语言,很多同学在初次接触python时可能会不习惯,缩进老是犯错.比如 Python 2.7.12 (default, Sep 17 2016, 13:47:40) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clan

小白学PYTHON时最容易犯的6个错误

最近又在跟之前的同学一起学习python,一起进步,发现很多测试同学在初学python的时候很容易犯一些错误,特意总结了一下.其实这些错误不仅是在学python时会碰到,在学习其他语言的时候也同样会碰到. 错误1:缩进 python是强制缩进的语言,很多同学在初次接触python时可能会不习惯,缩进老是犯错.比如 Python 2.7.12 (default, Sep 17 2016, 13:47:40) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang

测试代码执行时间的模块-timeit

有时候我们想看看一个函数的执行时间是多久,这时候我们可以使用装饰器,在函数的执行开始前,记录一个时间,在函数的执行结束后记录一个时间,然后求两个数的差,就可以得到这个函数本次的执行时间了.但是这样做的做法,太Low,接下来我们就说说Python 内置的timeit 模块 timeit 模块可以用来测试一小段Python 代码的执行速度timeit 模块里面有一个Timer 类,首先需要实例化这个类,先看一下初始化这个类所可以接收的参数,下面是timeit 模块关于Timer 的源码 1 clas