在 groovy (Spock) 中测试文件结构
Posted
技术标签:
【中文标题】在 groovy (Spock) 中测试文件结构【英文标题】:Test file structure in groovy(Spock) 【发布时间】:2018-08-06 14:42:55 【问题描述】:如何在 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
而实际会转换成这种树。
【问题讨论】:
【参考方案1】:不确定您是否可以使用内置的递归方法来做到这一点。当然有强大的,但这是您可以使用的标准递归代码:
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)
打印你描述的格式
【讨论】:
我认为 OP 想要解析该结构,而不是创建它。 我想以一种可读的方式比较我的实际文件树和预期的文件树。其实这个想法很好,只需要这个方法返回String,这样的话,我就可以比较我的String了。 modified 你的回答,对我来说看起来又好又简单【参考方案2】:您可以构建自己的解析器或使用 Groovy 的内置 JSON 解析器:
package de.scrum_master.***
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 :
*** : [
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.***.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/***/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.***.contains("CarTest.groovy")
中,您可以看到如何以.property
语法很好地与解析的JSON 对象图进行交互。你可能喜欢与否,需要与否。
递归方法 objectGraphToFileList
将解析的对象图转换为文件列表(如果您更喜欢一个集合,请更改它,但 File.eachFileRecurse(..)
不应产生任何重复项,因此不需要该集合。
如果您不喜欢 JSON 中的括号等,您仍然可以构建自己的解析器。
您可能想要添加另一种实用程序方法来从经过验证的目录结构中创建与给定字符串类似的 JSON 字符串,这样您在编写类似测试时的工作量就会减少。
【讨论】:
谢谢,这是个好主意,但对我来说,阅读起来有点负担。 我明白了。好处是 JSON 是一种标准格式。但您也可以轻松冲泡自己的咖啡。 ?【参考方案3】:修改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().sortit.name.each
if (it.isFile())
paths << ("\t" * (level + 1) + it.name)
if (it.isDirectory())
collectFileTree(it, level + 1, paths)
并且期望的文件以这种方式放入带有缩进(\t)的expected.txt文件中:
region:
usa:
new_york.json
california.json
europe:
spain.json
italy.json
【讨论】:
以上是关于在 groovy (Spock) 中测试文件结构的主要内容,如果未能解决你的问题,请参考以下文章
大量的 spock 测试导致 eclipse 中的编译时间很长