Невозможно использовать HtmlUnitDriver в тесте Geb-Spock Grails из-за проблем с зависимостями

Я пытаюсь использовать HtmlUnitDriver в функциональном тесте Geb-Spock в Grails 2.3.7. Я создаю проект, используя Maven.

Когда я запускаю тест с использованием этого драйвера, я получаю:

java.lang.NoClassDefFoundError: org/w3c/dom/ElementTraversal

Я думаю, что получаю эту ошибку, потому что мне пришлось исключить xml-apis:

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-htmlunit-driver</artifactId>
    <version>2.41.0</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>xml-apis</groupId>
            <artifactId>xml-apis</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Но я должен был это сделать, потому что иначе при запуске maven и запуске модульных тестов я получаю ошибку:

Fatal error forking Grails JVM: java.lang.reflect.InvocationTargetException
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at org.grails.launcher.GrailsLauncher.launch(GrailsLauncher.java:150)
    at org.grails.maven.plugin.tools.ForkedGrailsRuntime.main(ForkedGrailsRuntime.java:168)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.grails.launcher.GrailsLauncher.launch(GrailsLauncher.java:144)
... 1 more
Caused by: java.lang.LinkageError: loader constraint violation: when resolving overridden method "org.apache.tools.ant.helper.ProjectHelper2$RootHandler.setDocumentLocator(Lorg/xml/sax/Locator;)V" the class loader (instance of org/grails/launcher/RootLoader) of the current class, org/apache/tools/ant/helper/ProjectHelper2$RootHandler, and its superclass loader (instance of <bootloader>), have different Class objects for the type andler.setDocumentLocator(Lorg/xml/sax/Locator;)V used in the signature
at org.apache.tools.ant.helper.ProjectHelper2.parseUnknownElement(ProjectHelper2.java:131)
at org.apache.tools.ant.helper.ProjectHelper2.parseAntlibDescriptor(ProjectHelper2.java:111)
at org.apache.tools.ant.taskdefs.Antlib.createAntlib(Antlib.java:91)
at org.apache.tools.ant.taskdefs.Definer.loadAntlib(Definer.java:440)
at org.apache.tools.ant.taskdefs.Definer.execute(Definer.java:292)
at org.apache.tools.ant.ComponentHelper.checkNamespace(ComponentHelper.java:877)
at org.apache.tools.ant.ComponentHelper.getDefinition(ComponentHelper.java:308)
at org.apache.tools.ant.ComponentHelper.createComponent(ComponentHelper.java:285)
at org.apache.tools.ant.ComponentHelper.createComponent(ComponentHelper.java:264)
at org.apache.tools.ant.UnknownElement.makeObject(UnknownElement.java:417)
at org.apache.tools.ant.UnknownElement.maybeConfigure(UnknownElement.java:163)
at groovy.util.AntBuilder.performTask(AntBuilder.java:314)
at groovy.util.AntBuilder.nodeCompleted(AntBuilder.java:264)
at groovy.util.BuilderSupport.doInvokeMethod(BuilderSupport.java:147)
at groovy.util.AntBuilder.doInvokeMethod(AntBuilder.java:203)
at groovy.util.BuilderSupport.invokeMethod(BuilderSupport.java:64)
at org.codehaus.gant.GantBuilder.invokeMethod(GantBuilder.java:99)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:45)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.gant.GantBinding.initializeGantBinding(GantBinding.groovy:108)
at org.codehaus.gant.GantBinding.<init>(GantBinding.groovy:42)
at org.codehaus.groovy.grails.cli.GrailsScriptRunner.executeScriptWithCaching(GrailsScriptRunner.java:428)
at org.codehaus.groovy.grails.cli.GrailsScriptRunner.callPluginOrGrailsScript(GrailsScriptRunner.java:414)
at org.codehaus.groovy.grails.cli.GrailsScriptRunner.executeCommand(GrailsScriptRunner.java:378)
at org.codehaus.groovy.grails.cli.GrailsScriptRunner.executeCommand(GrailsScriptRunner.java:345)
... 6 more

Поэтому я думаю, что это какие-то проблемы с зависимостью. Но я не знаю, как с этим справиться. Я попытался проанализировать дерево зависимостей, но не знаю, как проверить, кому нужен этот org/xml/sax/Locator или org/w3c/dom/ElementTraversal.

Я пытался исключить не только xml-apis из HtmlUnitDriver, но и xalan и xerces, но это не помогло.

pom.xml выглядит так:

...
<properties>
    <grails.version>2.3.7</grails.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <h2.version>1.3.170</h2.version>
    <gebVersion>0.7.2</gebVersion>
    <seleniumVersion>2.41.0</seleniumVersion>
    <spockVersion>0.7</spockVersion>
    <gebSpockVersion>0.9.0-RC-1</gebSpockVersion>
</properties>

<dependencies>
    <dependency>
        <groupId>org.grails</groupId>
        <artifactId>grails-plugin-async</artifactId>
        <version>${grails.version}</version>
        <exclusions>
            <exclusion>
                <groupId>org.grails.plugins</groupId>
                <artifactId>spock</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.grails</groupId>
        <artifactId>grails-plugin-rest</artifactId>
        <version>${grails.version}</version>
    </dependency>

    <dependency>
        <groupId>org.grails</groupId>
        <artifactId>grails-plugin-services</artifactId>
        <version>${grails.version}</version>
    </dependency>
    <dependency>
        <groupId>org.grails</groupId>
        <artifactId>grails-plugin-i18n</artifactId>
        <version>${grails.version}</version>
    </dependency>

    <dependency>
        <groupId>org.grails</groupId>
        <artifactId>grails-plugin-databinding</artifactId>
        <version>${grails.version}</version>
    </dependency>

    <dependency>
        <groupId>org.grails</groupId>
        <artifactId>grails-plugin-filters</artifactId>
        <version>${grails.version}</version>
    </dependency>

    <dependency>
        <groupId>org.grails</groupId>
        <artifactId>grails-plugin-gsp</artifactId>
        <version>${grails.version}</version>
    </dependency>

    <dependency>
        <groupId>org.grails</groupId>
        <artifactId>grails-plugin-log4j</artifactId>
        <version>${grails.version}</version>
    </dependency>

    <dependency>
        <groupId>org.grails</groupId>
        <artifactId>grails-plugin-servlets</artifactId>
        <version>${grails.version}</version>
    </dependency>

    <dependency>
        <groupId>org.grails</groupId>
        <artifactId>grails-plugin-url-mappings</artifactId>
        <version>${grails.version}</version>
    </dependency>

    <dependency>
        <groupId>org.grails</groupId>
        <artifactId>grails-resources</artifactId>
        <version>${grails.version}</version>
        <scope>runtime</scope>
    </dependency>

    <dependency>
        <groupId>org.grails</groupId>
        <artifactId>grails-test</artifactId>
        <version>${grails.version}</version>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.grails.plugins</groupId>
                <artifactId>spock</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.grails</groupId>
        <artifactId>grails-plugin-testing</artifactId>
        <version>${grails.version}</version>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.grails.plugins</groupId>
                <artifactId>spock</artifactId>
            </exclusion>
        </exclusions>
    </dependency>


    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>${h2.version}</version>
        <scope>runtime</scope>
    </dependency>

    <dependency>
        <groupId>org.grails.plugins</groupId>
        <artifactId>cache</artifactId>
        <version>1.1.1</version>
        <scope>compile</scope>
        <type>zip</type>
    </dependency>

    <dependency>
        <groupId>org.grails.plugins</groupId>
        <artifactId>hibernate</artifactId>
        <version>3.6.10.9</version>
        <scope>runtime</scope>
        <type>zip</type>
    </dependency>

    <dependency>
        <groupId>org.grails.plugins</groupId>
        <artifactId>database-migration</artifactId>
        <version>1.3.8</version>
        <scope>runtime</scope>
        <type>zip</type>
    </dependency>

    <dependency>
        <groupId>org.grails.plugins</groupId>
        <artifactId>jquery</artifactId>
        <version>1.11.0.2</version>
        <scope>runtime</scope>
        <type>zip</type>
    </dependency>

    <dependency>
        <groupId>org.grails.plugins</groupId>
        <artifactId>jquery-ui</artifactId>
        <version>1.10.3</version>
        <scope>runtime</scope>
        <type>zip</type>
    </dependency>

    <dependency>
        <groupId>org.grails.plugins</groupId>
        <artifactId>resources</artifactId>
        <version>1.2.7</version>
        <scope>runtime</scope>
        <type>zip</type>
    </dependency>

    <dependency>
        <groupId>org.grails.plugins</groupId>
        <artifactId>tomcat</artifactId>
        <version>7.0.52.1</version>
        <scope>provided</scope>
        <type>zip</type>
    </dependency>

    <dependency>
        <groupId>org.grails.plugins</groupId>
        <artifactId>spock</artifactId>
        <version>${spockVersion}</version>
        <scope>test</scope>
        <type>zip</type>
    </dependency>

    <dependency>
        <groupId>org.grails.plugins</groupId>
        <artifactId>geb</artifactId>
        <version>${gebVersion}</version>
        <scope>test</scope>
        <type>zip</type>
    </dependency>

    <dependency>
        <groupId>org.gebish</groupId>
        <artifactId>geb-spock</artifactId>
        <version>${gebSpockVersion}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.spockframework</groupId>
        <artifactId>spock-grails-support</artifactId>
        <version>0.7-groovy-1.8</version>
    </dependency>

    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-htmlunit-driver</artifactId>
        <version>${seleniumVersion}</version>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>xalan</groupId>
                <artifactId>xalan</artifactId>
            </exclusion>
            <exclusion>
                <groupId>xml-apis</groupId>
                <artifactId>xml-apis</artifactId>
            </exclusion>
            <exclusion>
                <groupId>xerces</groupId>
                <artifactId>xercesImpl</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-chrome-driver</artifactId>
        <version>${seleniumVersion}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-firefox-driver</artifactId>
        <version>${seleniumVersion}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-support</artifactId>
        <version>${seleniumVersion}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.solr</groupId>
        <artifactId>solr-solrj</artifactId>
        <version>4.3.0</version>
        <exclusions>
            <exclusion>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.2.5</version>
    </dependency>
    <dependency>
        <groupId>commons-httpclient</groupId>
        <artifactId>commons-httpclient</artifactId>
        <version>3.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpmime</artifactId>
        <version>4.2.5</version>
    </dependency>
    <dependency>
        <groupId>org.tuckey</groupId>
        <artifactId>urlrewritefilter</artifactId>
        <version>4.0.3</version>
    </dependency>

    <dependency>
        <groupId>co.freeside</groupId>
        <artifactId>betamax</artifactId>
        <version>1.1.2</version>
        <scope>test</scope>
    </dependency>

Буду признателен за любые замечания по поводу решения данного вопроса.

Изменить

Я попробовал версии, предложенные erdi, поэтому:

selenium-htmlunit-driver  2.26.0
                     geb  0.9.0-RC-1
               geb-spock  0.9.0-RC-1
              (and spock  0.7)

Я получаю сообщение об ошибке:

2014-05-23 14:37:06,008 [main] ERROR javascript.StrictErrorReporter  
- runtimeError: message=[The data necessary to complete this operation 
is not yet available.] 
sourceName=[http://localhost:8080/search-web-app/static/plugins/jquery-1.11.0.2/js/jquery/jquery-1.11.0.min.js] line=[2] lineSource=[null] lineOffset=[0]

Драйвера Firefox и Chrome работают нормально (тесты пройдены). Причина, по которой я хотел бы, чтобы драйвер HtmlUnit работал, заключается в том, что мы хотим запускать тесты на сервере Jenkins. Насколько я понимаю, HtmlUnit это тот, который позволяет, потому что он не открывает браузер (пожалуйста, поправьте меня, если я неправильно понимаю).


person nuoritoveri    schedule 19.05.2014    source источник
comment
Что я обычно делаю, когда мне нужно запустить тесты браузера в CI, так это запускаю реальный браузер вместе с Xvfb в качестве виртуального дисплея.   -  person erdi    schedule 26.05.2014
comment
Спасибо за объяснение, в итоге я использовал для этого PhantomJS. Он медленнее, чем другие драйверы, поэтому мне пришлось добавить waitFor{...}, чтобы заставить его работать, но в остальном все в порядке.   -  person nuoritoveri    schedule 26.05.2014


Ответы (1)


Самая новая версия HtmlUnitDriver, которую мне удалось запустить с Grails, — 2.26.0. В любом случае, вам действительно следует избегать использования HtmlUnitDriver, так как он плохо работает с более сложными веб-страницами. Почти всегда лучше использовать в тестах настоящий браузер.

Обратите внимание, что последней версией Geb является 0.9.2, и вам не следует использовать разные версии для geb-spock и подключаемого модуля Grails Geb (0.9.0-RC-1 и 0.7.2).

person erdi    schedule 21.05.2014