【问题标题】:TestFX Spock Gradle Project Openjdk 11 - Zero Test ResultsTestFX Spock Gradle 项目 Openjdk 11 - 零测试结果
【发布时间】:2019-09-17 13:48:22
【问题描述】:

为什么我的 Spock 测试没有执行,而我在执行时得到零测试结果

./gradlew clean test

使用我的 TestFX Spock Gradle 项目 使用 Openjdk 11


以下是零测试结果:


我的 Spock 测试类编译成功但没有执行。

这是我的控制台

Working Directory: /home/~/EclipseProjects/gradleTestfxSpock
Gradle user home: /home/~/.gradle
Gradle Distribution: Gradle wrapper from target build
Gradle Version: 5.0
Java Home: /usr/lib/jvm/jdk-11.0.2+9
JVM Arguments: None
Program Arguments: None
Build Scans Enabled: false
Offline Mode Enabled: false
Gradle Tasks: clean test


> Configure project :
Found module name 'mtd'

> Task :clean
> Task :compileJava
> Task :compileGroovy NO-SOURCE
> Task :processResources
> Task :classes
> Task :compileTestJava NO-SOURCE
> Task :compileTestGroovy
> Task :processTestResources
> Task :testClasses
> Task :test

BUILD SUCCESSFUL in 6s
6 actionable tasks: 6 executed

这是我的 build.gradle

plugins {    
    id 'org.openjfx.javafxplugin' version '0.0.7'   
    id 'application'
    id 'groovy'
}

mainClassName = 'mtd/gradleTestfxSpock.Main'

sourceCompatibility = 11
targetCompatibility = 11

repositories {  
    jcenter()   
}

dependencies {
    implementation 'org.testfx:testfx-spock:4.0.15-alpha'
    testCompile    'org.testfx:testfx-core:4.0.15-alpha'        

    testCompile (group: 'org.spockframework', name: 'spock-core', version: '1.3-groovy-2.5')
    testCompile ('org.codehaus.groovy:groovy-all:2.5.6')
    testRuntime(
        'com.athaydes:spock-reports:1.2.7',
        'cglib:cglib-nodep:3.2.4'
    )
}

javafx {
    version = "11.0.2"
    modules = [ 'javafx.controls',
            'javafx.fxml',
            'javafx.web'
          ]
}

compileJava {
    doFirst {
        options.compilerArgs = [
                '--module-path', classpath.asPath,
                '--add-modules', 'javafx.controls',
                '--add-modules', 'javafx.fxml',
                '--add-modules', 'javafx.web'
        ]
    }
}

test {
    doFirst {
        jvmArgs = [
            '--module-path', classpath.asPath,
            '--add-modules', 'ALL-MODULE-PATH',
            '--add-exports', 'javafx.graphics/com.sun.javafx.application=org.testfx'            
        ]
    }
}

这是我的 module-info.java

module mtd {

requires javafx.controls;
requires javafx.fxml;
requires transitive javafx.graphics;
requires javafx.web;

requires org.testfx;
requires testfx.spock;  

opens gradleTestfxSpock to javafx.graphics;

exports gradleTestfxSpock;      
}

这是我的 Spock 测试代码

package gradleTestfxSpock;

import org.testfx.framework.spock.ApplicationSpec;
import javafx.stage.Stage


public class MainTest extends ApplicationSpec{


    def "Main Test 01"() {              
        expect:     
        println("you are in Main test 01");     
    }

    @Override
    public void start(Stage arg0) throws Exception {
        // TODO Auto-generated method stub      
    }


}

这是我的 JavaFX 代码

package gradleTestfxSpock;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{        
        Parent root = FXMLLoader.load(getClass().getResource("/fxml/sample.fxml"));        
        primaryStage.setTitle("Hello World");
    primaryStage.setScene(new Scene(root, 300, 275));
    primaryStage.show();
    }


    public static void main(String[] args) {
    launch(args);
    }
}

控制器

package gradleTestfxSpock;
public class Controller {
}

这是我的 eclipse gradle 项目结构


在其他 eclipse gradle 项目中,我已经成功执行了 TestFX Junit4 测试没有 Spock


另外,我已经成功地执行了相同的Spock Test without TestFXwithout JUnit


我确实注意到这个 Spock 测试的一些警告:

Working Directory: /home/~/EclipseProjects/gradleSpock
Gradle user home: /home/~/.gradle
Gradle Distribution: Gradle wrapper from target build
Gradle Version: 5.0
Java Home: /usr/lib/jvm/jdk-11.0.2+9
JVM Arguments: None
Program Arguments: None
Build Scans Enabled: false
Offline Mode Enabled: false
Gradle Tasks: clean test

> Task :clean
> Task :compileJava
> Task :compileGroovy NO-SOURCE
> Task :processResources NO-SOURCE
> Task :classes
> Task :compileTestJava NO-SOURCE
> Task :compileTestGroovy
> Task :processTestResources NO-SOURCE
> Task :testClasses

> Task :test
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.codehaus.groovy.vmplugin.v7.Java7$1 (file:/home/dm/.gradle/caches/modules-2/files-2.1/org.codehaus.groovy/groovy/2.5.6/6936e700f0fb1b50bac0698ada4347a769d40199/groovy-2.5.6.jar) to constructor java.lang.invoke.MethodHandles$Lookup(java.lang.Class,int)
WARNING: Please consider reporting this to the maintainers of org.codehaus.groovy.vmplugin.v7.Java7$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

BUILD SUCCESSFUL in 9s
4 actionable tasks: 4 executed

结论

如果使用 JUnit 的 TestFX 工作,并且单独使用 Spock 工作,但使用 Spock 的 TestFX 不起作用,那么配置是否有问题:

'org.testfx:testfx-spock:4.0.15-alpha'

非常感谢任何想法或帮助。

ps 忘了说我也在Netbeans中创建了TestFX/Spock项目,复制了eclipse项目,得到了同样的结果!


更多测试

不幸的是,在下面的 cmets 中,按照 Leonard Bruenings 非常好的建议进行的更多测试组合没有奏效。

我修改后的 module-info.java 看起来像:

module mtd {

requires javafx.controls;
requires javafx.fxml;
requires transitive javafx.graphics;
requires javafx.web;

requires org.testfx.junit;
requires org.testfx;
requires testfx.spock;
requires spock.core;
requires junit;

opens gradleTestfxSpock to javafx.graphics, org.testfx, testfx.spock, spock.core, junit, org.testfx.junit;

exports gradleTestfxSpock;      
}

我将它添加到我的 gradle.build 依赖项中以防万一:

implementation 'org.testfx:testfx-junit:4.0.15-alpha'

还是不开心……

【问题讨论】:

  • 我还没用过带模块路径的spock,但是你可能需要打开你的模块来spock和junit?
  • 伟大的想法 Leonard - 谢谢 - 有道理。不幸的是没有工作。请参阅我的主要帖子中的“更多测试”编辑。
  • 考虑一下,我让 Spock 在没有 TestFX 的情况下在 Openjdk11 的 gradle 项目中工作,而且我不需要打开我的项目。这是我的模块信息:模块 mtd { 导出 gradleSpock; }
  • 您是否检查过此处的 Java 11 部分 github.com/TestFX/TestFX 您需要包含其他库。
  • 是的,我已经仔细检查了这个 TestFX Java 11 部分。除了 TestFX 依赖项之外,它只是规定添加在 Java 11 中变得独立的 JavaFX 模块——这些只是我在上面的 build.gradle 中包含的 JavaFX 11 模块与 Java 11 的标准操作。当然,除非我在这里错过了其他任何东西。非常感谢您指出这一点。

标签: gradle javafx spock testfx openjdk-11


【解决方案1】:

解决方案

我发现这个插件是问题所在,正在停止成功执行我的 Spock 测试:

`plugins {    
    id 'org.openjfx.javafxplugin' version '0.0.7'
 }`

当我从 build.gradle 中删除它时,我的 TestFX Spock 测试工作正常。

有了这个重新设计的 build.gradle 和 module-info.java,我可以成功地执行我的 Spock 测试:

plugins { 
    id 'application'
    id 'groovy'
}

ext {
    moduleName = "mtd"
    mainQualifiedClassName = "gradleTestfxSpock.Main"
}

application {
    mainClassName = "$moduleName/$mainQualifiedClassName"
}

sourceCompatibility = 11
targetCompatibility = 11

repositories {  
    jcenter()   
}

dependencies {
    implementation("org.openjfx:javafx-fxml:11:linux")
    implementation("org.openjfx:javafx-web:11:linux")
    implementation("org.openjfx:javafx-media:11:linux")
    implementation("org.openjfx:javafx-base:11:linux")
    implementation("org.openjfx:javafx-graphics:11:linux")
    implementation("org.openjfx:javafx-controls:11:linux")

    testImplementation ('org.testfx:testfx-spock:4.0.15-alpha')
    testImplementation ('org.testfx:testfx-core:4.0.15-alpha')

    testImplementation (group: 'org.spockframework', name: 'spock-core', version: '1.3-groovy-2.5')
    testImplementation ('org.codehaus.groovy:groovy-all:2.5.6')

    testRuntimeOnly (
            'com.athaydes:spock-reports:1.2.7',
            'cglib:cglib-nodep:3.2.4'
    )
}


compileJava {
    doFirst {
       options.compilerArgs = [
            '--module-path', classpath.asPath,
            '--add-modules', 'javafx.controls',
            '--add-modules', 'javafx.fxml',
            '--add-modules', 'javafx.web'
       ]
    }
}

run {
    doFirst {
        jvmArgs = [
                '--module-path', classpath.asPath,
                '--patch-module', "$moduleName=" + files(sourceSets.main.output.resourcesDir).asPath,
                '--module', mainClassName
        ]   
    }
}

我需要添加到 build.gradle 的运行部分:

  1. '--module', mainClassName

    -这样才能找到mainClassName

  2. '--patch-module', "$moduleName=" + files(sourceSets.main.output.resourcesDir).asPath

    -提供对资源文件的访问,例如getClass().getResource("/fxml/sample.fxml")


module mtd {

requires javafx.controls;
requires javafx.fxml;
requires transitive javafx.graphics;
requires javafx.web;


exports gradleTestfxSpock;
}

【讨论】:

    【解决方案2】:

    我不是这方面的专家,这可能就是为什么我花了很长时间才达到这一点的原因,但 FWIW 我想我可能会提到我已经设法让它工作:通过“它”我的意思是:Java 11、JavaFX、TestFX-Spock 和使用 javafxplugin。如果可以的话,一个帮助过我的人 José Pereda,appears to recommend using it。所以我只是想我会把我的文件精简到最低限度。没有 module-info.java,我在我的应用程序代码以及 Spock 和 Gradle 中使用 Groovy。

    (精简)build.gradle:

    plugins {
        id 'java-library'
        id 'groovy'
        id 'eclipse'
        id 'application'
        id 'org.openjfx.javafxplugin' version '0.0.8'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        api 'org.apache.commons:commons-math3:3.6.1'
        implementation 'com.google.guava:guava:27.0.1-jre'
        // although not using JUnit I think it's best to leave this line
        // (included at start by Gradle):
        testImplementation 'junit:junit:4.12'
        implementation 'org.codehaus.groovy:groovy-all:2.5.8'
        testImplementation 'org.spockframework:spock-core:1.2-groovy-2.5'
        testImplementation 'org.testfx:testfx-spock:4.0.15-alpha'
    }
    mainClassName = 'core.App'
    group 'Project'
    version '1.0'
    sourceCompatibility = 11
    javafx {
        version = "13"
        modules = [ "javafx.controls", "javafx.fxml" ]
    }
    

    src/main/groovy/core/main.groovy:

    package core
    // (imports omitted)
    public class App extends Application {
        void start(Stage primaryStage) throws Exception{
            Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"))
            primaryStage.title = "Hello World"
            primaryStage.scene = new Scene(root, 300, 275)
            primaryStage.show()
        }
        def main(String[] args) {
            launch( App.class, args)
        }
    }
    
    class Controller {
        @FXML
        TextField inputField
        @FXML
        Label label
        @FXML
        Button applyButton
        public void applyButtonClicked () {
            label.text = inputField.text
        }
    }
    

    src/test/groovy/core/test.groovy:

    package core
    // (imports omitted)
    class FuncSpec extends ApplicationSpec {
        void init() throws Exception {
            FxToolkit.registerStage { new Stage() }
        }
        def cleanup() {
            FxToolkit.hideStage()
            // as explained for org.testfx.robot.KeyboardRobot, passing an
            // empty array of the appropriate type releases all keys/mouse buttons
            // NB this is how you create an empty typed array in Groovy
            release(new KeyCode[0])
            release(new MouseButton[0])
        }
        @Override
        public void start(Stage stage) throws Exception {
            Parent mainNode = FXMLLoader.load( App.class.getResource("sample.fxml"))
            stage.scene = new Scene(mainNode)
            stage.show()
            stage.toFront()
        }
        def "test English input"(){
            when: 
            Label label = lookup("#label").query()
            clickOn("#inputField")
            write("This is a test!")
            clickOn("#applyButton")
    
            then:
            label.text == "This is a test!"
        }
    }
    

    src/main/resources/core/sample.fxml // 注意包含“core”(包名)

    <?xml version="1.0" encoding="UTF-8"?>
    <?import javafx.scene.control.Button?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.control.TextField?>
    <?import javafx.scene.layout.AnchorPane?>
    <?import javafx.scene.layout.ColumnConstraints?>
    <?import javafx.scene.layout.GridPane?>
    <?import javafx.scene.layout.RowConstraints?>
    <GridPane alignment="center" hgap="10" vgap="10"
        xmlns:fx="http://javafx.com/fxml/1"
        xmlns="http://javafx.com/javafx/8.0.111"
        fx:controller="core.Controller">
        <children>
            <TextField layoutX="15.0" layoutY="25.0" fx:id="inputField" />
            <Label layoutX="15.0" layoutY="84.0" text="TEXT GOES HERE"
                fx:id="label" />
            <Button layoutX="124.0" layoutY="160.0" mnemonicParsing="false"
                text="Apply" onAction="#applyButtonClicked" fx:id="applyButton" />
        </children>
    </GridPane>
    

    【讨论】:

    • 感谢您的参考,但让我澄清一下,我不是该插件的作者。尽管如此,我已经为它做出了贡献,并且我确实建议将其用于任何带有 Gradle 的 JavaFX 11+ 项目。插件问题可以报告here
    • 非常感谢您的发帖 - 这是一个非常有用的参考。我注意到与我的 2 个不同之处:您指定 javafx { version = "13" } 而我有 version = "11.0.2" 而您没有像我一样的 module-info.java。不知道这些是否重要。当我回到这个问题时,我会跟随你的领导并重新测试。
    猜你喜欢
    • 2013-05-31
    • 2015-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    • 2014-08-13
    相关资源
    最近更新 更多