2

スクリプトのフェーズで実行するカスタム テスト タイプをサポートするために、カスタム テスト タイプ クラス (extending GrailsTestTypeSupport) とカスタム テスト結果クラス (extending )を追加する Grails プラグインを作成しました。これをローカル マシンでテストしたところ、問題なく動作しましたが...GrailsTestTypeResultothertest-app

アプリで使用するプラグインをパッケージ化すると、CI サーバー (Jenkins) でテストが異常終了します。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

@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.groovyましCustomTestTypecustom.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- 私は2つの場所でその魔法を必要とすることになった.

于 2012-11-15T01:59:44.680 に答える
1

classLoaderの変数を介してアクセスできる 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 に答える