我对在单元测试中使用冗长的设置字符串的意见,实践和推荐的最佳实践感兴趣。
您是希望在线测试,接近测试,还是在某个文件中外部化?
注意,我说的是特定于单个单元测试的测试资产,因此不一定适合生活在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);
}
鉴于这个例子,我可以将实际/期望外部化到外部文件中,但这也使得测试对于它实际测试的内容有点不清楚。
思想?
答案 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)
我会这样做 - 因为它对于那个测试很重要,如果你依赖于对“外部”的测试而严格看待,那么它不是一个严格的单元测试。