2

我创建了一个 Grails 插件,它添加了一个自定义测试类型类(扩展GrailsTestTypeSupport)和自定义测试结果类(扩展GrailsTestTypeResult),以支持我在脚本other阶段运行的自定义测试类型。test-app在我的本地机器上测试这个已经很顺利了,但是......

当我打包插件以在我的应用程序中使用时,测试在我们的 CI 服务器 (Jenkins) 上爆炸了。这是詹金斯吐出的错误:

unable to resolve class CustomTestResult  @ line 58, column 9.
       new CustomTestResult(tests.size() - failed, failed)

看来我不能简单地import将这些类放入_Events.groovy中,并且这些类不在类路径中。但如果我能弄清楚如何让它们进入类路径,我会被诅咒的。这是我到目前为止所拥有的(在_Events.groovy):

import java.lang.reflect.Constructor

eventAllTestsStart = {
  if (!otherTests) otherTests = []

  loadCustomTestResult()
  otherTests << createCustomTestType()
}

private def createCustomTestType(String name = 'js', String relativeSourcePath = 'js') {
  ClassLoader parent = getClass().getClassLoader()
  GroovyClassLoader loader = new GroovyClassLoader(parent)
  Class customTestTypeClass = loader.parseClass(new File("${customTestPluginDir}/src/groovy/custom/test/CustomTestType.groovy"))
  Constructor customTestTypeConstructor = customTestTypeClass.getConstructor(String, String)
  def customTestType = customTestTypeConstructor.newInstance(name, relativeSourcePath)

  customTestType
}

private def loadCustomTestResult() {
  ClassLoader parent = getClass().getClassLoader()
  GroovyClassLoader loader = new GroovyClassLoader(parent)
  Class customTestResultClass = loader.parseClass(new File("${customTestPluginDir}/src/groovy/custom/test/CustomTestResult.groovy"))
}

当前:CustomTestResult仅从内部引用CustomTestType。据我所知,_Events.groovy正在加载CustomTestType,但它失败了,因为它坚持认为CustomTestResult它不在类路径上。

暂时搁置一下,将插件提供的类放到类路径中以开始测试周期的开销如此之大似乎很疯狂……我不太确定我在哪里被绊倒了。任何帮助或指示将不胜感激。

4

2 回答 2

1

您是否尝试过通过可通过classLoader变量 in访问的 ClassLoader 简单地加载有问题的类_Events.groovy

Class customTestTypeClass = classLoader.loadClass('custom.test.CustomTestType')
// use nice groovy overloading of Class.newInstance
return customTestTypeClass.newInstance(name, relativeSourcePath)

您应该在此过程中迟到,eventAllTestsStart以使其有效。

于 2012-11-12T14:48:48.467 回答
1

@Ian Roberts 的 回答让我大致指出了正确的方向,并结合了这个插件_Events.groovy的脚本,我设法通过了这个解决方案:grails-cucumber

首先,_Events.groovy变成了这样:

eventAllTestsStart = { if (!otherTests) otherTests = [] }

eventTestPhasesStart = { phases ->
  if (!phases.contains('other')) { return }

  // classLoader.loadClass business per Ian Roberts:
  otherTests << classLoader.loadClass('custom.test.CustomTestType').newInstance('js', 'js')
}

这比我在这个线程开始时的可读性要强得多。但是:我处于大致相同的位置:ClassNotFoundException_Events.groovyCustomTestType试图创建custom.test. CustomTestResult. 所以在里面CustomTestType,我添加了以下方法:

private GrailsTestTypeResult createResult(passed, failed) {
  try {
    return new customTestResult(passed, failed)
  } catch(ClassNotFoundException cnf) {
    Class customTestResult = buildBinding.classLoader.loadClass('custom.test.CustomTestResult')
    return customTestResult.newInstance(passed, failed)
  }
}

所以伊恩是对的,因为classLoader我来救援了——我只是在两个地方需要它的魔力。

于 2012-11-15T01:59:44.680 回答