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

时间:2018-08-06 14:42:55

标签: testing groovy spock filetree

如何在groovy(Spock)中测试已创建和预期的文件树? 现在,我使用Set来指定要获取的路径,并以这种方式收集实际路径:

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

但是测试的可读性不是很好。 在常规情况下是否可以将期望的路径写成树,然后将其与实际值进行比较

例如,预期:

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

实际将转换为这种树。

3 个答案:

答案 0 :(得分: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)

打印出您描述的格式

答案 1 :(得分: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结构中引用每个单个String。如果文件名中包含空格或其他特殊字符,则必须使用"my file name"之类的东西。

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

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

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

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

答案 2 :(得分:0)

经过修改的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)
            }
        }
    }

预期文件以这种方式用indent(\ t)放入Expect.txt文件中:

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