有时我最终会为其他开发人员编写的代码编写单元测试用例。有时候我真的不知道开发人员要做什么(业务部分),而我只是操纵测试用例来获得绿线。这些事情在业界正常吗?
正常趋势是什么?开发人员是否应该为自己编写的代码编写单元测试用例?
有时我最终会为其他开发人员编写的代码编写单元测试用例。有时候我真的不知道开发人员要做什么(业务部分),而我只是操纵测试用例来获得绿线。这些事情在业界正常吗?
正常趋势是什么?开发人员是否应该为自己编写的代码编写单元测试用例?
Answers:
尝试阅读此博客文章:编写出色的单元测试:最佳实践和最佳实践。
但是网络上还有无数其他人。
直接回答您的问题...
而且您描述的编写测试方式(在您的问题中)是完全错误的!
这种方法使单元测试毫无价值。
当某些实际操作无法按预期进行时,您需要使单元测试失败。如果您不这样做,甚至在测试代码前编写测试,就好像烟雾报警器无法正常工作一样。
在现实世界中,为其他人的代码编写单元测试是完全正常的。当然,原始开发人员应该已经做到了,但是通常您会收到遗留代码,而这只是没有完成。顺便说一句,遗留代码是否源于数十年前的遥远星系,或者您的同事是否在上周检查过它,还是您今天编写的,遗留代码是未经测试的代码
问自己:为什么我们要编写单元测试?走向绿色显然只是达到目的的一种手段,最终目的是证明或反驳有关被测代码的主张。
假设您有一种方法可以计算浮点数的平方根。在Java中,接口会将其定义为:
public double squareRoot(double number);
无论是编写实现还是其他人编写,都想声明squareRoot的一些属性:
因此,您开始将这些作为单独的测试编写:
@Test
public void canFindSimpleRoot() {
assertEquals(2, squareRoot(4), epsilon);
}
糟糕,此测试已失败:
java.lang.AssertionError: Use assertEquals(expected, actual, delta) to compare floating-point numbers
您忘记了浮点运算。好,介绍double epsilon=0.01
并开始:
@Test
public void canFindSimpleRootToEpsilonPrecision() {
assertEquals(2, squareRoot(4), epsilon);
}
并添加其他测试:最后
@Test
@ExpectedException(IllegalArgumentException.class)
public void throwsExceptionOnNegativeInput() {
assertEquals(-1, squareRoot(-1), epsilon);
}
哎呀,再次:
java.lang.AssertionError: expected:<-1.0> but was:<NaN>
您应该已经测试:
@Test
public void returnsNaNOnNegativeInput() {
assertEquals(Double.NaN, squareRoot(-1), epsilon);
}
我们在这里做了什么?我们从关于该方法应如何工作的一些假设开始,发现并非全部都是正确的。然后,我们将测试套件设为绿色,以记下该方法根据我们正确的假设进行工作的证明。现在,此代码的客户可以依靠此行为。如果有人要用其他东西交换squareRoot的实际实现,例如确实引发了异常而不返回NaN的东西,我们的测试将立即捕获到这一点。
这个例子很简单,但是经常会在不清楚实际作用的地方继承大量代码。在这种情况下,通常在代码周围放置测试工具。从有关代码应如何表现的一些基本假设开始,为它们编写单元测试,然后进行测试。如果为绿色,则编写更多测试。如果是Red,那么现在您有一个失败的断言,您可以坚持某个规范。遗留代码中可能存在错误。也许规格对此不清楚。也许您没有规格。在这种情况下,重写测试,使其记录意外的行为:
@Test
public void throwsNoExceptionOnNegativeInput() {
assertNotNull(squareRoot(-1)); // Shouldn't this fail?
}
随着时间的流逝,您最终获得了一个测试工具,该工具记录了代码的实际行为,并成为某种编码规范。如果您想更改旧代码或将其替换为其他代码,则可以使用测试工具来验证新代码的行为是否相同,或者新代码在预期和受控方式下的行为是否不同(例如,实际上修复了您期望它修复的错误)。实际上,这种挽具不必在第一天就完成,事实上,拥有不完备的挽具几乎总比根本没有挽具要好。拥有安全带意味着您可以更轻松地编写客户代码,知道更改后期望中断的地方,以及最终更改时可以中断的地方。
您应该尝试摆脱必须编写单元测试的想法,就像您必须在表单上填写必填字段一样。而且,您不应该只是为了使红线变为绿色而编写单元测试。单元测试不是您的敌人,单元测试是您的朋友。
在为打印机编写测试用例时,我尝试考虑每个小组件……以及如何做才能打破它。举例来说,让扫描器说一下,它使用什么命令(在pjl printer-job-language中),我可以写些什么来测试每一个功能……现在,我可以做些什么来尝试破坏它。
我尝试对每个主要组件执行此操作,但是涉及软件而不是太多硬件时,您要查看每种方法/功能并检查边界等。