gpt4 book ai didi

java - 我应该测试(复制)数据,还是只测试行为?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:35:25 27 4
gpt4 key购买 nike

从设计的角度来看,我想知道我是否应该测试数据,特别是如果它是一个众所周知的数据(不是很容易配置的东西)——这可以应用于流行的文件扩展名、特殊 IP地址等

假设我们有一个紧急电话号码分类器:

public class ContactClassifier {

public final static String EMERGENCY_PHONE_NUMBER = "911";

public boolean isEmergencyNumber(String number) {
return number.equals(EMERGENCY_PHONE_NUMBER);
}
}

我应该这样测试吗(“911”重复):

@Test
public testClassifier() {
assertTrue(contactClassifier.isEmergencyNumber("911"));
assertFalse(contactClassifier.isEmergencyNumber("111-other-222"));
}

或(测试是否正确识别“配置”号码):

@Test
public testClassifier() {
assertTrue(contactClassifier.isEmergencyNumber(ContactClassifier.EMERGENCY_PHONE_NUMBER));
assertFalse(contactClassifier.isEmergencyNumber("111-other-222"));
}

或者在构造函数中注入(inject)“911”,这对我来说看起来最合理,但即使我这样做了——如果组件被实例化,我是否应该为“应用程序胶水”编写一个测试具有适当的值(value)?如果有人可以在数据(代码)中输入错误,那么我看不出有人可以在测试用例中输入错误(我打赌这样的数据会被复制粘贴)

最佳答案

您可以测试的测试数据有什么意义?那个常数值实际上是常数值?它已经在代码中定义了。 Java 确保该值实际上就是该值,所以不用担心。

在单元测试中你应该做的是测试实现,不管它是否正确。要测试不正确的行为,您可以使用在测试中定义的数据,将其标记为错误,然后发送到方法。要测试数据是否正确,您可以在测试期间输入它,如果它的边界值不是众所周知的,或者如果它们已经在某处定义,则使用应用程序范围内已知的值(接口(interface)内的常量)。

困扰大家的是数据,大家应该都知道)放在test里面,一点都不对。您可以做的是将其移至界面级别。这样,通过设计,您的应用程序已知数据被设计为契约(Contract)的一部分,并且它的正确性由 java 编译器检查。

不应检查众所周知的值,而应由某种接口(interface)处理以维护它们。是的,更改它很容易,并且您的测试在该更改期间不会失败,但是为了避免发生意外,您应该有合并请求、审查和与之相关的任务。如果有人不小心更改了它,您可以在代码审查中找到它。如果你将一切都交给 master,你会遇到比双重定义的常量更大的问题。

现在,在其他方法中困扰您的部分:

1) 如果有人可以在数据(代码)中输入错误,那么我看不出有人可以在测试用例中输入错误(我敢打赌这样的数据会被复制粘贴)

实际上,如果有人更改数据中的值然后继续开发,在某个时候他将运行全新安装并查看那些失败的测试。到那时他可能会更改/忽略测试以使其通过。如果你有人随机更改数据,你就会遇到更大的问题,如果不是,并且更改是由任务定义的——你让某人做了两次更改(至少?)。没有优点,有很多缺点。

2) 担心别人犯错通常是不好的做法。您无法使用代码捕获它。代码审查就是为此而设计的。您可以担心有人没有正确使用您定义的接口(interface)。

3) 我应该这样测试吗:

@Test
public testClassifier() {
assertTrue(contactClassifier.isEmergencyNumber(ContactClassifier.EMERGENCY_PHONE_NUMBER));
assertFalse(contactClassifier.isEmergencyNumber("111-other-222"));
}

也不是这样。这不是测试而是测试批处理,即在同一方法中进行多次测试。应该是这样的(convention-s):

@Test
public testClassifier_emergencyNumberSupplied_correctnessConfirmed() {
assertTrue(contactClassifier.isEmergencyNumber(ContactClassifier.EMERGENCY_PHONE_NUMBER));
}


@Test
public testClassifier_incorrectValueSupplied_correctnessNotConfirmed() {
assertFalse(contactClassifier.isEmergencyNumber("111-other-222"));
}

4) 正确命名方法时没有必要,但如果它足够长,您可以考虑在测试中命名值。例如

@Test
public testClassifier_incorrectValueSupplied_correctnessNotConfirmed() {
String nonEmergencyNumber = "111-other-222";
assertFalse(contactClassifier.isEmergencyNumber(nonEmergencyNumber));
}

关于java - 我应该测试(复制)数据,还是只测试行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47260491/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com