首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单元测试: DRY与可预测性

单元测试: DRY与可预测性
EN

Stack Overflow用户
提问于 2009-10-28 14:03:54
回答 3查看 690关注 0票数 4

在编写单元测试时,我们是否应该以DRY为目标,因为功能的变化对代码的影响尽可能小,我们的可预测性,代码的操作是微不足道的?基本上,我问的是创建非常通用且可供多个单元测试使用的辅助方法与仅将测试代码限制为单个单元测试之间的权衡。以工厂为例,它具有以下方法签名:

代码语言:javascript
复制
public Node buildNode(String path, String name, Map<String, Object> attributes);

根据提供的参数,结果Node对象将不同,因此我们需要测试不同的可能性。如果我们的目标是可预测性,我们可能会像第一个示例中给出的那样编写两个自包含的单元测试,但如果我们的目标是DRY,我们更愿意添加一个通用的助手方法,如第二个示例中所示:

代码语言:javascript
复制
EXAMPLE1:
@Test
public void testBuildBasicNode() {
  Node node = testee.buildNode("/home/user", "Node", null);
  assertEquals("/home/user/Node", node.getAbsolutePath());
  assertEquals(false, node.isFolder());
}

@Test
public void testBuildAdvancedNode() {
  Map<String, Object> attributes = new HashMap<String, Object>();
  attributes.put("type", NodeType.FOLDER);
  Node node = testee.buildNode("/home/user", "Node", attributes);
  assertEquals("/home/user/Node", node.getAbsolutePath());
  assertEquals(true, node.isFolder());
}

EXAMPLE2:
@Test
public void testBuildBasicNode() {
  Node node = testee.buildNode("/home/user", "Node", null);
  Node comparisonNode = buildComparisonNode("/home/user", "Node", null);
  assertEquals(comparisonNode, node);
}

@Test
public void testBuildAdvancedNode() {
  Map<String, Object> attributes = new HashMap<String, Object>();
  attributes.put("type", NodeType.FOLDER);
  Node node = testee.buildNode("/home/user", "Node", attributes);
  Node comparisonNode = buildComparisonNode("/home/user", "Node", attributes);
  assertEquals(comparisonNode, node);
}

private Node buildComparisonNode(String path, String name, Map<String, Object> attributes) {
  // Not just a duplicate of the buildNode method,
  // can be more trivial if we only limit it to unit tests that share some common attributes
  ...
}

我对第一个示例(可预测性)的问题是,如果有任何功能发生变化(比如AbsolutePath应该如何格式化),就需要在我的所有单元测试中进行更改。我对第二个例子的问题是,buildComparisonNode感觉像是应该测试的东西,我当然不想开始为测试编写测试。

另外,作为结束语,您是否会为示例单元测试中使用的文本字符串声明final变量,或者它们是可以的吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-10-28 14:19:09

  1. 问得好。我以前听说过“单元测试可以是湿的,但不是湿透的……”对于测试的可维护性,焦点(或可预测性)是关键。你的团队越大,我认为这对你就越重要。另一件要考虑的事情是,如果有特定的测试助手代码,那么它本身就可以成为一个API,所以如果每个人都知道如何利用它,这可能不是一个坏主意。我的经验法则是,如果我可以在自动重构中使用集成开发环境来做这件事,并且我可以给它一个好的名字,我就会删除重复。
  2. 一个建议……查看Nat Pryce编写的Test Data Builder模式,了解一种更易维护/可扩展的方法。
票数 7
EN

Stack Overflow用户

发布于 2009-10-28 14:16:35

虽然DRY适用于生产代码,但它并不总是适用于单元测试。你真的希望每个测试彼此独立,这通常意味着重复你自己。另一方面,我确实发现将某些东西分组到所有测试使用的辅助方法中是很有用的,只要它不将测试耦合在一起,那么它应该是好的。我通常减少重复的一个地方是通过使用测试数据构建器来构造存在于测试中特定状态的对象。

我的经验法则是让我的测试尽可能小和可读性强。如果使用DRY可以帮助实现这一点,那么我会使用它。如果不是,那么我就不会。:-)

希望这能有所帮助。我不是单元测试方面的世界专家,所以我可能会大错特错。:-)

票数 4
EN

Stack Overflow用户

发布于 2009-10-28 14:27:54

另一件需要考虑的事情-当你在测试中去除重复时,它通常会告诉你,某些东西是产品代码或设计,正在等待一个合法的原因(在产品代码库中的使用)来将其转移到产品代码中。我记不清我是从哪里得到那一刻的.但我认为这和TDD as if you mean it有关。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1635434

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档