Unit testing 单元测试及;冗长的设置字符串:样式/最佳实践
我对在单元测试中使用冗长的设置字符串的观点、实践和推荐的最佳实践感兴趣 您更喜欢在线声明测试、在测试附近声明测试,还是将测试外部化到某个文件中 注意,我所说的测试资产是特定于单个单元测试的,因此不一定适合使用setup()方法 我看到了这两种方法的优点/缺点——我非常喜欢让对测试重要的东西尽可能靠近测试,但是在测试方法中,几行字符串设置可能会很快变得很刺耳 例如,我正在编写一个快速解析器来从文件中去除未使用的css声明。我想测试给定一个特定的输入字符串,正确的文本被删除。我的测试已经变得非常嘈杂与所有的字符串连接Unit testing 单元测试及;冗长的设置字符串:样式/最佳实践,unit-testing,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);
}
在这个例子中,我可以将实际的/预期的内容外部化到外部文件中,但这也使得测试对于它实际测试的目的有点不清楚
想法?我会将字符串外部化,并就您测试的内容编写一些注释。注释还具有比这些字符串结构可读性强得多的优点。当然是代码,它更容易立即告诉您正在测试什么,并且在您想要重用它时更容易重构。我喜欢让它保持干燥,所以我通常倾向于将它移动到构建器或具体类(取决于我正在做什么),这会为我提供一个默认配置,我可以为特定的测试查看它。我个人更喜欢在这样的情况下保持字符串内联。字符串对于理解测试应该做什么很重要,因此必须从外部查找它似乎适得其反
如果您有很多相同的测试,它们只在输入的字符串和输出的字符串上有所不同,那么故事就有点不同了,您可能需要看看基于表的测试解决方案。在.Net中,您有mbunit。它允许您使用不同的预期输入/输出运行相同的测试,或者您可以查看Fitnesse之类的工具,这些工具允许您定义要测试的数据表。我同意这种方式,因为这对于该测试非常重要,如果您在测试中依赖于“外部”的东西,则可以严格查看这不是一个严格的单元测试。如果您使用支持正确字符串文本的编程语言,您的问题将消失。例如,Python支持多行字符串:
source = """
.presentInFileOne {
}
.presentInFileTwo {
bottom-corners-rounded : false;
}
.notUsed {
}
"""
expected = """
.presentInFileOne {
}
.presentInFileTwo {
bottom-corners-rounded : false;
}
"""
assert removeDeclaration(source, "notUsed") == expected
这样的语言结构将使您的测试比其他任何东西都更具可读性。有一种方法需要改进。性能可能不是您希望在生产中看到的东西,但对于测试来说已经足够好了
我的规则是:如果字符串很小(<10行),我将它们保持在内联状态,但我可以始终将“”之间的所有内容剪切掉,然后粘贴新版本(这意味着如果需要,我将在assertEquals()中转换字符串)
如果字符串文字更长、更复杂,或者当我有一个好的编辑器(带有语法高亮显示等)时,我喜欢将它们保存在一个测试数据文件夹中,以测试名称作为文件名。然后,您可以在JUnit测试中使用一个实用函数,该函数使用getName()加载字符串,您将不需要任何魔法就能知道哪个文件属于哪个测试
如果有很多这样的文件,我会使用测试类名(class.getSimpleName())作为文件夹名来保持对它们的控制