在groovy(Spock)中测试文件结构



如何在groovy(Spock(中测试已创建和预期的文件树?现在我正在使用Set,在那里我指定了我希望获得的路径,并以这种方式收集实际路径:

Set<String> getCreatedFilePaths(String root) {
Set<String> createFilePaths = new HashSet<>()
new File(root).eachFileRecurse {
createFilePaths << it.absolutePath
}
return createFilePaths
}

但是测试的可读性不是很好。在groovy中,是否可以将预期的路径写为树,然后与实际的进行比较

例如,预期:

region:
usa:
new_york.json
california.json
europe:
spain.json
italy.json

而实际的将被转换为这种树。

不确定是否可以使用内置的递归方法。当然有一些强大的代码,但这是您可以使用的标准递归代码:

def path = new File("/Users/me/Downloads")
def printTree(File file, Integer level) {
println "   " * level + "${file.name}:"
file.eachFile {
println "   " * (level + 1) + it.name
}
file.eachDir {
printTree(it, level + 1)
}
}
printTree(path, 1)

打印您描述的格式

您可以构建自己的解析器,也可以使用Groovy内置的JSON解析器:

package de.scrum_master.stackoverflow
import groovy.json.JsonParserType
import groovy.json.JsonSlurper
import spock.lang.Specification
class FileRecursionTest extends Specification {
def jsonDirectoryTree = """{
com : {
na : {
tests : [
MyBaseIT.groovy
]
},
twg : {
sample : {
model : [
PrimeNumberCalculatorSpec.groovy
]
}
}
},
de : {
scrum_master : {
stackoverflow : [
AllowedPasswordsTest.groovy,
CarTest.groovy,
FileRecursionTest.groovy,
{
foo : [
LoginIT.groovy,
LoginModule.groovy,
LoginPage.groovy,
LoginValidationPage.groovy,
User.groovy
]
},
LuceneTest.groovy
],
testing : [
GebTestHelper.groovy,
RestartBrowserIT.groovy,
SampleGebIT.groovy
]
}
}
}"""
def "Parse directory tree JSON representation"() {
given:
def jsonSlurper = new JsonSlurper(type: JsonParserType.LAX)
def rootDirectory = jsonSlurper.parseText(jsonDirectoryTree)
expect:
rootDirectory.de.scrum_master.stackoverflow.contains("CarTest.groovy")
rootDirectory.com.twg.sample.model.contains("PrimeNumberCalculatorSpec.groovy")
when:
def fileList = objectGraphToFileList("src/test/groovy", rootDirectory)
fileList.each { println it }
then:
fileList.size() == 14
fileList.contains("src/test/groovy/de/scrum_master/stackoverflow/CarTest.groovy")
fileList.contains("src/test/groovy/com/twg/sample/model/PrimeNumberCalculatorSpec.groovy")
}
List<File> objectGraphToFileList(String directoryPath, Object directoryContent) {
List<File> files = []
directoryContent.each {
switch (it) {
case String:
files << directoryPath + "/" + it
break
case Map:
files += objectGraphToFileList(directoryPath, it)
break
case Map.Entry:
files += objectGraphToFileList(directoryPath + "/" + (it as Map.Entry).key, (it as Map.Entry).value)
break
default:
throw new IllegalArgumentException("unexpected directory content value $it")
}
}
files
}
}

请注意:

  • 我使用new JsonSlurper(type: JsonParserType.LAX)是为了避免在JSON结构中引用每个字符串。如果文件名包含空格或其他特殊字符,则必须使用类似"my file name"的字符。

  • rootDirectory.de.scrum_master.stackoverflow.contains("CarTest.groovy")中,您可以看到如何用.property语法与解析的JSON对象图进行良好的交互。你可能喜欢与否,需要与否。

  • 递归方法objectGraphToFileList将解析后的对象图转换为文件列表(如果您喜欢一个集合,请更改它,但File.eachFileRecurse(..)不应产生任何重复,因此不需要该集合。

  • 如果您不喜欢JSON中的括号等,您仍然可以构建自己的解析器。

  • 您可能需要添加另一个实用程序方法来从经过验证的目录结构中创建一个类似于给定的JSON字符串,这样在编写类似的测试时就可以减少工作量。

修改了Bavo Bruylandt的答案,以收集文件树路径,并对其进行排序,从而不关心文件的顺序。

def "check directory structure"() {
expect:
String created = getCreatedFilePaths(new File("/tmp/region"))
String expected = new File("expected.txt").text
created == expected
}
private String getCreatedFilePaths(File root) {
List paths = new ArrayList()
printTree(root, 0, paths)
return paths.join("n")
}
private void printTree(File file, Integer level, List paths) {
paths << ("t" * level + "${file.name}:")
file.listFiles().sort{it.name}.each {
if (it.isFile()) {
paths << ("t" * (level + 1) + it.name)
}
if (it.isDirectory()) {
collectFileTree(it, level + 1, paths)
}
}
}

预期的文件以这种方式放入带有缩进(\t(的预期.txt文件中:

region:
usa:
new_york.json
california.json
europe:
spain.json
italy.json

最新更新