假设我们有一个如下所示的 Spock 规范类。
class SomeFeature extends Specification {
def "some scenario"() {
given: "some resource"
def resource = someResource()
when: "some action is taken"
someAction()
then: "some condition must be met"
true == someCondition()
}
}
如何提取 BDD 元语句,例如 some scenario
、given
、when
、then
?处理源文件很简单,但我想知道是否可以使用反射来实现。
顺便说一句,获取这些信息的动机是为了促进产品所有者和开发人员之间的沟通,这样产品所有者就可以在不查看源代码的情况下知道已经实现和验证了哪些行为。
非常感谢。
最佳答案
在寒冷的阳光下,这有一些问题。
- 它可能非常脆弱,需要整理以处理不同的情况和格式(展开的描述?辅助方法?参数化描述?)
- 即使从未执行过测试,它也会盲目地转储所有内容。
我认为更好更稳定的解决方案是@PeterNiederwieser 上面的评论中的解决方案。
不过,为了繁荣起见,我会把它留在这里,因为它是一个很好的例子,说明如何从一些 Groovy 代码生成 AST 作为字符串...
我认为反射不会有帮助,因为它不会让您获得方法的内容。
您可以通过从源代码生成 AST,然后遍历它寻找感兴趣的节点来实现。
所以给定字符串中的代码,如下所示:
def code = '''import spock.*
class SomeFeature extends Specification {
def "some scenario"() {
given: "some resource"
def resource = someResource()
when: "some action is taken"
someAction()
then: "some condition must be met"
true == someCondition()
}
def "another"() {
given: 'a value 1'
def value = 1
then: '1 == 1'
value == 1
}
}'''
您可以生成一个 AST:
import org.codehaus.groovy.antlr.*
import org.codehaus.groovy.antlr.parser.*
def ast = new GroovyRecognizer(
new GroovyLexer(
new StringReader( code ) ).plumb() ).with { p ->
p.compilationUnit()
p.AST
}
然后你可以做这样的事情(这可能不是最干净的方法,我是在时间限制下);-)
while( ast ) {
if( ast.type == GroovyTokenTypes.CLASS_DEF ) {
def child = ast.firstChild.nextSibling
println "Specification '${child.text}'"
while( child && child.type != GroovyTokenTypes.OBJBLOCK ) {
child = child.nextSibling
}
if( child ) {
child = child.firstChild
while( child ) {
if( child.type == GroovyTokenTypes.METHOD_DEF ) {
def method = child.firstChild
println " Scenario '${method.nextSibling?.nextSibling?.text}'"
while( method ) {
if( method.type == GroovyTokenTypes.SLIST ) {
def statements = method.firstChild
while( statements ) {
if( statements.type == GroovyTokenTypes.LABELED_STAT ) {
def label = statements.firstChild
println " ${label.text.toUpperCase()} '${label.nextSibling?.firstChild?.text}'"
}
statements = statements.nextSibling
}
}
method = method.nextSibling
}
}
child = child.nextSibling
}
}
}
ast = ast.nextSibling
}
这给了我输出:
Specification 'SomeFeature'
Scenario 'some scenario'
GIVEN 'some resource'
WHEN 'some action is taken'
THEN 'some condition must be met'
Scenario 'another'
GIVEN 'a value 1'
THEN '1 == 1'
希望对你有帮助...
关于java - 如何从 Spock 规范类中提取 BDD 元语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21887399/