我们常常为我们的营业代码写测试用例,对吧?毫无疑问,大大多数谜底会落在“不错,可是你晓得如何防止它么?”和“固然,我爱好测试”之间的某种形态。这里我将引见一些小诀窍,让你清楚写好测试用例也是如斯容易。这也将协助你写更少的碎片化的测试,以确保你的使用愈加健壮。
同时,假如你的谜底是“不,我历来不写测试”,那我也盼望这些容易有效的技巧让你看?**馐杂美?囊娲Γ?阋步?峥吹叫闯雒靼孜藜鄣牟馐约?涫挡幌衲阆氲哪茄?杩唷?/p>
怎么写测试用例和甚么是治理测试套件的最好理论,现在是一个新的主题。
我们过来曾经会商了非常多主题。从怎么在编译流程中准确地运用集成测试,到怎么在单位测试中模仿测试情况,再到代码掩盖率和怎么找出实践需求测试的代码等。
今日,我想给你一些新的思绪,教你怎么从初级到初级构建测试蓝图,组织测试的心思画像。从怎么结构一个容易的单位测试用例,到更高层级的Tools的使用等。比方: 你会清楚模仿(mock)、侦测(spy)和复制粘贴测试代码(copy-pasting 这里估量是指代码复用)等。让我们开端吧!
AAArrr, 听起来就像是海盗,对吧~~~
在大量的软件开辟中,找到适宜的设计形式来采取会是一个好的末尾。你能否想经过工场创立工具?亦或许能否需求把你的web使用分为模子,视图和把持器等模块?在这面前常常会有一种形式协助你完成你的设法。那末,一个典范的测试形式应当看起来是甚么样的呢?
在写测试代码时,一个最有效,也最容易的形式是“预备(Arrange)---举措(Act)---断言(Assert)”模子,也叫做 AAA.
这个模子的条件是:一切的测试应当遵照这个默许结构。被测零碎的一切预置前提和输出应当在测试一开端就布置好。等一切前置前提断定后,我们就能够针对被测零碎履行举措(Act)了, 比方履行一个办法或反省一些零碎形态。最初,我们还需求对被测零碎发生的后果实行反省(Assert)。
让我们看一个Java JUnit中运用该形式的测试用例:
@Test public void testAddition() { // Arrange Calculator calculator = new Calculator(); // Act int result = calculator.add(1, 2); // Assert assertEquals("Calculator.add returns invalid result", 3, result); }
怎样?如许的代码看起来不错吧?预备(Arrange),举措(Act),断言(Assert)形式可让你顿时清楚这个测试用例正在做甚么。
偏离这个形式可能会招致愈加混乱的代码构造。
请记着迪米特准绳
迪米特准绳是指各单位之间应当只运用起码的常识(或联络),以坚持松耦合的形态。在软件开辟中,迪米特准绳老是一个设计目的。
迪米特准绳可以被描绘为以下一系列规矩:
在一个办法中,一个类实例可以挪用该类中的其它办法。
在一个办法中,一个实例可以查询它本人的数据,而不克不及是数据的数据。
当一个办法需求参数的时分,第一层的办法可以经过给定的参数被挪用。
当一个办法实例化当地变量时,类实例可以挪用这些当地变量的办法。
不要挪用全局工具的办法。
那末,迪米特准绳在测试中又意味着甚么呢?这意味着你的使用更轻易实行单位测试,由于迪米特准绳的使用晋升了你顺序的松耦合度。为了阐明该准绳怎么辅佐单位测试,让我们来看看一个不契合该准绳的例子:
思索以下类,我们需求对它实行测试:
public class Foo() { public Bar doSomething(Baz aParameter) { Bar bar = null; if (aParameter.getValue().isValid()) { aParameter.getThing().increment(); bar = BarManager.getBar(new Thing()); } return bar; } }
假如我们测验考试测试该办法,由于该类的设计问题,我们将立刻碰到一些费事。
在测试该办法的过程当中,我们碰到的第一个艰苦是:我们挪用了一个静态办法 --- BarManager.getBar()。该办法在单位测试的束缚下是怎么任务的?我们没有方法很轻易地晓得。还记得我们之前讲的"预备,举措,断言“3A形式吗?这里,在挪用 doSomething()办法之前(act 举措),我们没有方法对 BarManager 实行设置装备摆设(Arrange 预备)。假如 BarManager.getBar() 长短静态的,我们可以通报一个 BarManager 实例给 doSomething() 办法,那样也更轻易在测试套件中通报一致的用例值,以对该办法的进程实行更好的和可猜测的把持。
在这个办法中,也能够看到我们实行了一个办法链的挪用:aParameter.getValue().isValid() 和 aParameter().getThing().increment(). 为了对它们实行测试,我们必需晓得工具 aParameter.getValue() 和 aParameter.getThing() 的前往类型是甚么?晓得了前往类型,我们才可以在测试中结构适宜的值对其实行测试。
假如我们要如许做(译者注:这里指的是结构适宜的值),我们必需十分熟习这些办法前往的工具,而且我们的单位测试将开端酿成一大堆不成保护的软弱代码。我们将打破单位测试的一个根本规矩,那就是测试单个单位,而不是这些单位完成的细节。
我并非说单位测试只能测试单个类,可是在大大多数状况下,将类看做单个单位多是一个好主见。但是,有时两个或更多的类可以被以为是一个单位。
我将把它留给读者作为操练,以便将这个办法完整重构为更轻易测试的办法。可是关于初学者,我们可以将 aParmater.getValue() 工具作为参数通报到办法中。这将知足我们的一些设定,并使该办法更容易于测试。
晓得甚么时分才运用断言
JUnit和TesgNG是两个十分优良的测试框架,它们供给了丰厚的断言办法,比方反省值能否相等或不等,能否为空等。
是的,我们也以为断言十分酷,那我们就随性地四处运用吧。且慢,且慢,过分运用断言会使得你的测试用例难以保护,我晓得阿谁坑有多深... ...,它会招致使用不成测,不波动。
请思索以下测试办法:
@Test public void testFoo { // Arrange Foo foo = new Foo(); double result = …; // Act double value = foo.bar( 100.0 ); // Assert assertEquals(value, result); assertNotNull( foo.getBar() ); assertTrue( foo.isValid() ); }
代码乍一看没有问题。我们遵照了AAA形式,也对将要发作的举措实行了准确的断言。这有甚么错呢?
起首,从这个测试办法名字,testFoo,我们没法失掉该测试的任何有效信息,它也不克不及适配我们正在反省的任何断言。
那末,假如此中的一个断言失败,我们怎么断定被测零碎的哪一部分招致的失败呢?是我们的履行举措中 foo.bar(100.0)失败,仍是foo.getBar()失败?亦或许是foo.isValid()失败?假如欠亨过对测试代码的深化debug剖析以反省究竟发作了甚么,那我们就没有方法晓得。
本文中的一切译文仅用于进修和交换目标,转载请务必注明文章译者、出处、和本文链接。 2KB翻译任务按照 CC 协定,假如我们的任务有进犯到您的权益,请实时联络我们。2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务