单元测试&冗长的设置字符串:风格/最佳实践

时间:2009-03-18 09:09:48

标签: unit-testing

我对在单元测试中使用冗长的设置字符串的意见,实践和推荐的最佳实践感兴趣。

您是希望在线测试,接近测试,还是在某个文件中外部化?

注意,我说的是特定于单个单元测试的测试资产,因此不一定适合生活在setup()方法中。

我看到两者的优点/缺点 - 我很喜欢尽可能接近测试保持测试的重要性,但是几行字符串设置很快就会变成测试方法。

例如,我正在编写一个快速解析器来从文件中删除未使用的css声明。我想测试给定一个特定的输入字符串,正确的文本被删除。所有字符串连接都使我的测试变得非常嘈杂。

public void removesStyleFromText() 
{
    StyleCleaner styleCleaner = new StyleCleaner();
    String source = ".presentInFileOne {\r\n" + 
            "}\r\n" + 
            "\r\n" + 
            ".presentInFileTwo {\r\n" + 
            "   bottom-corners-rounded : false;\r\n" + 
            "}\r\n" + 
            ".notUsed {\r\n" + 
            "}\r\n" + 
            "";

    String actual = styleCleaner.removeDeclaration(source , "notUsed");

    String expected = ".presentInFileOne {\r\n" + 
    "}\r\n" + 
    "\r\n" + 
    ".presentInFileTwo {\r\n" + 
    "   bottom-corners-rounded : false;\r\n" + 
    "}\r\n";

    assertEquals(expected , actual);
}

鉴于这个例子,我可以将实际/期望外部化到外部文件中,但这也使得测试对于它实际测试的内容有点不清楚。

思想?

6 个答案:

答案 0 :(得分:3)

我个人更喜欢在这种情况下保持字符串内联。字符串对于理解测试应该做什么很重要,因此不得不在外部查找它似乎适得其反。

如果你有很多相同的测试,只有不同的字符串进入和什么字符串来,故事有点不同,你可能想看看基于表格的测试解决方案。在.Net你有mbunit。它允许您使用不同的预期输入/输出运行相同的测试,或者您可以查看Fitnesse之类的工具,它们允许您定义要测试的数据表。

答案 1 :(得分:1)

绝对是代码,当您想要重用它时,更容易立即告诉您正在测试的内容并且更容易重构。我喜欢把它保持干燥,所以我通常倾向于将它移动到构建器或具体类(取决于我正在做什么),这使我得到一个默认配置,我可以调整特定测试。

答案 2 :(得分:0)

我会将字符串外部化,并对您正在测试的内容写一些评论。注释还具有比这些字符串结构更具可读性的优点。

答案 3 :(得分:0)

如果您使用支持正确的字符串文字的编程语言,您的问题将会消失。例如,Python支持多行字符串:

source = """
.presentInFileOne {
}

.presentInFileTwo {
       bottom-corners-rounded : false;
}
.notUsed {
}
"""

expected = """
.presentInFileOne {
}

.presentInFileTwo {
       bottom-corners-rounded : false;
}
"""

assert removeDeclaration(source, "notUsed") == expected

这样的语言结构将使您的测试比其他任何内容都更具可读性。

答案 4 :(得分:0)

有一个黑客可以multi-line Strings literals work in Java。性能可能不是你想要在生产中看到的,但足以用于测试。

我的规则是:如果字符串很小(< 10行),我会将它们保持内联,但我总是可以在“”之间剪切所有内容并粘贴新版本(这意味着我是如果需要,转换我的assertEquals()中的字符串。

如果字符串文字更长,更复杂或者我有一个好的编辑器(带有语法高亮等),我喜欢将它们保存在测试名称中作为文件名的测试数据文件夹中。然后,您可以在JUnit测试中使用实用程序函数,该函数使用getName()来加载字符串,您将知道哪个文件属于哪个测试。

如果你有很多这些,我使用测试类名(class.getSimpleName())作为文件夹名称来保持对它们的控制。

答案 5 :(得分:-1)

我会这样做 - 因为它对于那个测试很重要,如果你依赖于对“外部”的测试而严格看待,那么它不是一个严格的单元测试。

相关问题