您如何使单元测试更加有趣?[关闭]


18

如果您一直喜欢单元测试,那对您有好处!但是对于那些不是天生喜欢它的人来说,您如何使这项任务变得更加愉快呢?

这不是“什么是正确的单元测试方法”的问题。我只是想知道一些个人技巧,这些技巧可以减少编写单元测试的乏味(我敢说)。


1
我喜欢编写单元测试和其他测试,部分原因是因为几乎所有其他人都对此感到厌倦(有时他们也对我正在测试的工具感到厌倦)。不,我不喜欢开发人员。我只喜欢可用性,便利性和自动化性。该MbUnit库已经改变了我的生活。自动测试很重要。自动测试可以节省时间。自动测试可以省钱。自动测试可以挽救生命。自动测试是唯一的方法。自动测试是另一个安全网。当我是在一个巨大的建筑中工作的50个人中的一个时,我感到犹如隔壁的砖墙。通过单元测试,我可以控制一切。
工作

单元测试中的懒惰和沮丧是对我们的大脑认为无用的工作的正常反应。我讨厌编写和维护投资回报率很少或为负的单元测试。但是,编写有用的测试是一项令人愉快的任务,但是它本身就是一种技能,它可以识别有用的东西和什么是垃圾。还有谁在编写基于在他的博客一书中对这个话题的人,你可以阅读明星在这里:enterprisecraftsmanship.com/2016/06/01/...
科拉

Answers:


22

首先,我同意您的看法-如果您是在已经完成的代码上编写单元测试,或者正在手动对代码进行单元测试,那么我也觉得这很无聊。

我发现有两种让我真正感到愉快的单元测试方法:

  1. 通过使用测试驱动开发(TDD)-首先编写测试,使我可以考虑代码中需要的下一个功能或行为。我发现迈向最终目标的步伐很小,每隔几分钟看到实现目标的切实进展是非常有益和愉快的。
  2. 如果存在错误,而不是直接去调试器,找到一种方法来编写重现该错误的失败的单元测试是一个有趣的挑战。最终找出导致代码失败的情况,然后对其进行修复,并看着新测试失败的条变为绿色(对于所有现有测试保持绿色),这是非常令人满足的。

12

自鸣得意的优势。

我只是在开玩笑。“看着我,要养成良好的编程习惯!这些“单元测试”的东西是十年前我从来没有做过的-真是个傻瓜!再想一想我将要捕获的所有错误。我现在正在做的这份枯燥乏味的工作-我的代码将很棒!我肯定会加薪的!*”

*-不,我不会。

我发现这就像锻炼身体或饮食健康;直到切实的收益开始发挥作用(“天哪,我真的在赶上将要潜入生产中的大量回归错误!”),知道自己在做正确的事可以帮助您实现自己的道义上的骄傲通过。


7

首先,我几乎从来不只是坐在那里写单元测试。单元测试是达到目的的一种手段,而不是目的本身。它们是一种回答“此代码是否完成了应该执行的基本任务”的一种方式。

例如,有些人将编写一个函数,然后打开一个交互式会话,以对几个值进行测试以确保其正常工作:

def fact x
  if x == 0
    1
  else 
    x * fact(x-1)
  end
end

>> fact 10
=> 3628800
>> fact 7
=> 5040

但是现在您发现了一个错误:

>> fact -1
SystemStackError: stack level too deep
    from (irb):2:in `fact'
    from (irb):5:in `fact'
    from (irb):10

因此,您可以解决此问题:

def fact x
  if x < 0
    raise "Can't take the factorial of a negative number"
  elsif x == 0
    1
  else 
    x * fact(x-1)
  end
end

>> fact -1
RuntimeError: Can't take the factorial of a negative number
    from (irb):3:in `fact'
    from (irb):10

但是现在您真的应该进行测试以确保它仍然有效:

>> fact 10
=> 3628800
>> fact 7
=> 5040

如您所见,您继续重复相同的测试...,并且必须目视比较结果。在这种情况下,单元测试是避免重复的一种方法。它减少了您需要做的工作。尽管这是一个愚蠢的小例子,但在现实世界中,它变得越来越重要,并且手动测试也越来越困难。当然,这意味着人们根本不测试各个组件。他们只是测试整个程序。但是随后出现了错误,很难找到它们。或发生了错误,并且已将其修复,但是有人再次引入了相同的错误,因为没有人添加测试用例来确保未发生这种情况。或者有人看着一大段代码,然后说:“我不知道这应该做什么,因为它没有文档记录,也没有测试... 如果我修复此错误,我不知道是否会根据此错误打破其他问题;也许我会从头开始重写它。”

在这些情况下,单元测试减少了所有额外的工作。使它们变得有趣的最好方法是,确保人们了解他们要替换的所有工作,并通过了解每段代码应该做什么来获得额外的灵活性。在某种程度上,人们需要在编写和维护大型代码库方面有更多的经验,以了解单元测试的重要性。如果他们所有的代码都是一次编写然后扔掉的东西,他们将永远无法得到它。

而且事实不应该编写单元测试,因为一旦您“知道”了代码就可以了,这是一个额外的琐事。在编写有问题的代码之后,应该首先编写单元测试,或者至少(由于有时您有时忘记先编写它们)才编写单元测试。这就是所谓的测试驱动开发,它可以帮助您改善API。如果您首先编写用于测试API的测试,则在编写代码之前,您将了解在API难以使用的地方,并且比之后再添加测试要容易得多。


@Biran,我同意。但是所有这些使它成为“正确”的事情。但是如何使它变得愉快呢?甚至一点点?
Preets 2010年

@Preets这很有趣,因为您避免进行重复的手动测试。当您第一次进行此操作而不是事后进行操作时,它会更加有趣,因为它成为设计过程的一部分,而不是事后处理已经“起作用”的代码。
Brian Campbell 2010年

因此,花点时间做不好的事情,这样比较起来就很有趣了吗?……实际上可能会起作用。–
BlairHippo 2010年

@Biran,我同意,必须“首先”做到这一点-不仅是为了消除无聊,而且我认为这样做是正确的方法,以便获得单元测试的真正好处。
Preets 10/09/14

@Biran,谢谢!我最近在一个我的业余项目中使用了TDD,它改变了我对单元测试的看法。
Preets

5

我不知道。使单元测试更令我感到愉悦的是,我想到了所有令人沮丧,冗长,无聊和无用的调试程序,而每次我对软件进行更改时,我都不会经历:)


2
这太有趣了。因为就个人而言,当有人在我的代码中发现错误时,我会羞愧地埋头,但是与此同时,对我来说调试过程实际上很有趣,并且比单元测试更有趣。这就像解决一个难题一样,您必须抓住该漏洞。
Preets 2010年

@Preets:我同意,有时候它可能很有趣,但是对我来说,设计比实现更有趣。因此,我不想在实施上花费很多时间。我希望它简单明了且可预测,尤其是因为它允许制定更可靠的时间表。尽管我喜欢创建软件的过程,但我认为结果是决定性的。
back2dos

哦,我完全同意!一个带有随机bug的系统可能会导致不眠之夜..我的选择仅仅是在一个虚幻世界中的一种偏爱,在这个虚幻世界中,除了获得乐趣外别无其他!
Preets

3

当您签入坚如磐石,强大而稳定的代码时,您会感到自鸣得意的优越性。而且,如果您使用代码覆盖率工具编写单元测试,则可以在签入注释中夸耀代码覆盖率达到90%或更高。


3

显然,对测试优先开发的满足以及设计和测试结合在一起时的感觉是令人满意的。但是,为预先存在的/遗留的代码编写测试可能会让人感到麻木和沮丧。当我们的项目处于维护模式时,我使用覆盖率报告作为游戏来编写未经测试的代码的测试。您可以与自己和/或其他人进行一些比赛来提高覆盖率。当然,您可能做得太过分了,并创建了一些不好的测试,但是它可能是一个很好的激励因素。


由于遗留代码通常不容易测试,因此我发现自己很难编写好的单元测试-这样不仅使过程很痛苦,而且结果(单元测试)也不是特别有用:-//我发现最令人沮丧的是。 。覆盖面游戏虽然不错:)
Preets 2010年

1

尝试进入流程。为自己设定艰难但可实现的目标。单元测试的目标是什么?例如,尝试在保持质量的同时加快书写速度。单元测试不需要太多思考,因此不太可能出错。专注于您的目标,并经常检查一下是否接近目标。


ás,为什么您说单元测试不会引起太多思考?如果您使用TDD,则确实需要很多思考。那不是真的吗?
Preets 2010年

没错,我没有考虑TDD。
陶Szelei

0

有时候,为了激发自己的动力,我会在一天开始时写下当前的“代码覆盖率”。然后,每次编写测试并通过测试时,我都会运行套件并更新覆盖率编号。这很有趣,并且有助于提醒我为什么要这样做。(还有其他原因,但是我喜欢这些数字。也许就是我!)


0

通过不自欺欺人,我可以欺骗我,使我认为在任何可持续的时间段内单元测试都可以令人愉快。

接受不享受单元测试的现实,这对我有很大帮助,这使我意识到,我在一个从未有过的地方寻找东西。

在这些短暂的心理旅行中,当我到达要真正了解单元测试的程度时,即残酷,不堪忍受且令人心碎的无聊任务,我问自己是否可以承受得起他们的放任,即没有对功能正确性的高度保证。

答案总是响亮的“否”。

接受命运后,我不断将带有字母,数字和符号的方形物体推到我的面前,我们称它们为键盘,从第一手经验得知每次单击键盘后,单元测试的结束都比它接近曾经有


并非每个测试都是好的或有用的。这是TDD'ers和其他考试布道者通常没有提到的。我敢打赌,当您知道单元测试可以测试复杂的逻辑,优雅且不与实现耦合时,您会喜欢单元测试,而当您被迫测试琐碎的杂物以达到某些疯子代码覆盖率目标时,他们会讨厌项目指南。
KolA

@KolA没错,有挑战性的单元测试需要创造力,但是编写无穷无尽的单元测试甚至可以从本来有趣的单元测试中吸取乐趣。
bugfoot
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.