更好的集成maven/qunit/phantomjs的方法是什么?

16

我一直在研究如何在我们的Maven CI环境中进行最佳的JS单元测试。目前我在我的Maven项目中拼凑出了以下内容:

  • qunit资源(JS/CSS文件)
  • qunit测试HTML文件(每个被测试文件一个),如果需要则包含HTML固定装置
  • 索引HTML文件,它将测试HTML文件作为超链接有序列表的引用
  • PhantomJS运行文件,其中:
    • 打开索引HTML文件并解析测试文件列表
    • 打开每个测试文件
    • 对于每个文件,截取qunit测试结果的屏幕截图
    • 如果有任何失败,则以"1"状态退出
    • 如果没有失败,则以"0"状态退出
  • shell文件,如果未安装phantomjs,则会以“0”退出,如果已安装,则会调用phantomjs测试
  • pom.xml更改,以在构建的测试阶段运行phantomjs测试:

    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.1</version>
            <executions>
                <execution>
                    <id>PhantomJS Unit Testing</id>
                    <phase>test</phase>
                    <goals>
                        <goal>exec</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <executable>${project.basedir}/src/main/webapp/unittest/phantomcheck</executable>
                <arguments>
                    <argument>${project.basedir}/src/main/webapp/unittest/qunit-runner.js</argument>
                    <argument>${project.basedir}/src/main/webapp/unittest/tests/index.html</argument>
                    <argument>${project.build.directory}/surefire-reports</argument>
                </arguments>
            </configuration>
        </plugin>
    </plugins>
    

    所以,这很好地实现了目的。它在我们的开发和构建机器上运行qunit测试(只要安装了PhantomJS)。测试在无头浏览器环境中运行,对qunit测试没有限制。我见过的其他maven/qunit集成由于在Rhino或其他JS环境中运行测试而不支持编写类型的测试而失败。此外,PhantomJS使我们能够获得测试运行的截图,这在排除任何故障时非常有帮助。

    我的方法的缺点是需要在构建/开发机器上安装PhantomJS。我不知道如何将phantomJS捆绑到依赖项中,以使开发人员不必担心安装PhantomJS。有人能给我一个方向吗?我该如何开始?


请查看我的Maven插件(phantomjs-qunit-runner)。http://code.google.com/p/phantomjs-qunit-runner/ 这里有使用细节: http://kennychua.net/blog/running-qunit-tests-in-a-maven-continuous-integration-build-with-phantomjs - Kenny Chua
@KennyChua: 问问题的人想要一个下载 PhantomJS 依赖项的工具,但是你的插件不支持这个功能。 :-( - Jonathan Benn
你好。你提到过你能够运行多个测试(你的陈述是:“索引HTML文件,该文件将测试HTML文件作为超链接有序列表引用”)。你是如何做到的?我尝试了几种方法,但都没有成功。你能展示一下你的代码吗?也许我的测试运行器与你的不同;你使用的是哪一个?提前感谢你。 - David Jensen
5个回答

5

phantomjs-maven-plugin 提供了一个 install 目标,可以安装 phantomjs,以便您无需预先安装它。安装完成后,它会设置一个属性,该属性包含可供其他插件使用的可执行文件路径。此外,它还有一个 exec 目标,用于执行 phantomjs 脚本。免责声明:我编写了这个插件。


1
感谢这个优秀的插件,我能够使用它来解决自己的问题,并写出了一篇很棒的答案。 :) - Jonathan Benn
@Kyle 你创建的插件做得很好!@jonathan-benn 我按照Github上的描述使用了你的插件,但是无法使其工作。请在这里检查问题并帮助我找出我的pom.xml文件中哪里出了问题:http://stackoverflow.com/q/32678881/2079692 - Anudeep Samaiya
@Kyle,在构建过程中如何调用phantomjs-maven-plugin,并在Java EE项目中安装二进制文件?我能否将其设置为使用自定义位置? - Anudeep Samaiya
@Kyle没有关于设置自定义位置的任何内容...我想在Tomcat容器中运行我的测试...这就是为什么loc很重要的原因。 - Anudeep Samaiya
@AnudeepSamaiya,看一下outputDirectory参数。另外,你应该在一个新的问题中问这些事情。 - Kyle
显示剩余2条评论

2

使用Kyle的答案和另一个插件,我成功地得到了一个完整的解决方案,它不需要任何东西,只需预先安装maven并设置phantomjs和qunit以允许运行测试。我从一个maven-grunt插件 (github.com/eirslett/frontend-maven-plugin) 开始,并按照这篇指南中的步骤 (http://blog.trifork.com/2014/10/07/setting-up-maven-to-use-gruntnodejs/) 进行设置。然后我尝试在maven中使用qunit,但遇到了phantomjs的问题,并找到了这篇文章,发现了Kyle的插件 (github.com/klieber/phantomjs-maven-plugin)。我必须使用这篇指南中解释的自定义qunit源代码 (http://techblog.dorogin.com/2013/08/issues-with-grunt-contrib-qunit.html)。这使我能够使用Kyle的插件安装phantomjs,然后通过grunt选项将二进制文件链接到自定义的qunit。最终我的pom文件看起来像:

`    <plugin>
        <groupId>com.github.klieber</groupId>
        <artifactId>phantomjs-maven-plugin</artifactId>
        <version>0.4</version>
        <executions>
          <execution>
            <phase>generate-resources</phase>
            <goals>
              <goal>install</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <version>1.9.8</version>
        </configuration>
      </plugin>
      <plugin>
        <groupId>com.github.eirslett</groupId>
        <artifactId>frontend-maven-plugin</artifactId>
        <version>0.0.20</version>
        <executions>
          <execution>
            <id>install node and npm</id>
            <phase>generate-resources</phase>
            <goals>
              <goal>install-node-and-npm</goal>
            </goals>
            <configuration>
              <nodeVersion>v0.10.33</nodeVersion>
              <npmVersion>1.3.6</npmVersion>
            </configuration>
          </execution>
          <execution>
            <id>npm install</id>
            <phase>generate-resources</phase>
            <goals>
              <goal>npm</goal>
            </goals>
            <configuration>
              <arguments>install</arguments>
            </configuration>
          </execution>
          <execution>
            <id>grunt build</id>
            <phase>generate-resources</phase>
            <goals>
              <goal>grunt</goal>
            </goals>
            <configuration>
              <arguments>--phantomPath=${phantomjs.binary}</arguments>
            </configuration>
          </execution>
        </executions>
      </plugin>
`  

我的Gruntfile.js看起来像:

`    module.exports = function(grunt) {
      grunt.loadNpmTasks('grunt-croc-qunit');
      grunt.initConfig({
      pkg: grunt.file.readJSON('package.json'),
      qunit: {
        options: {
          'phantomPath': grunt.option('phantomPath')
        },
        all:['src/test/*.html']
      }
  });
  grunt.registerTask('default',['qunit']);
};`  

我的 package.json 文件如下:

`    {
  "name":"reporting",
  "version":"0.0.1",
  "dependencies": {
    "grunt": "~0.4.5",
    "grunt-cli": "~0.1.13",
    "grunt-croc-qunit":"~0.3.0"
  },
  "devDependencies":{ }
}`  

也抱歉关于格式。这是我的第一个帖子。 - samroxsox

2

Kyle的回答基础上,我找到了一个可靠的解决方案。谢谢你,Kyle!

解决方案是使用phantomjs-maven-plugin Maven插件。我在我的pom.xml文件中添加了该插件,如下所示(您需要升级Maven到v3.1或更高版本才能使用该插件):

<plugin>
    <groupId>com.github.klieber</groupId>
    <artifactId>phantomjs-maven-plugin</artifactId>
    <version>0.4</version>
    <executions>
        <execution>
            <goals>
                <goal>install</goal>
                <goal>exec</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <version>1.9.7</version>
        <checkSystemPath>false</checkSystemPath>
        <script>src/test/qunit/run-qunit-testsuite.js</script>
        <arguments>
            <argument>src/test/qunit/testsuite.qunit.html</argument>
        </arguments>
    </configuration>
</plugin>

重要提示:在上面的pom.xml代码中,请务必像我一样使用相对(而不是绝对)文件引用。如果你使用绝对引用(从${basedir}开始),会导致PhantomJS的工作目录发生奇怪的变化,浪费几个小时时间。在pom.xml中使用相对引用将使HTML文件中的引用也是相对的(这将最大限度地提高代码可移植性)。

在上面的插件代码中,我引用了两个文件:run-qunit-testsuite.jstestsuite.qunit.html。HTML文件只是执行所有测试的QUnit文件。JS文件是PhantomJS的驱动程序;它接受一个参数:要加载的HTML QUnit测试文件。

要完成此解决方案,你可以从GMarik的GitHub Gist页面下载示例驱动程序和测试文件。你可以并且应该根据自己的需求调整这些文件(尽管要注意GMarik的页面不包括开源许可证,你需要征得许可才能进行任何侵犯版权的使用)。

将此插件添加到你的Maven代码中后,在执行Maven构建后,你将看到类似于以下输出(改编自GMarik的页面):

[INFO] --- phantomjs-maven-plugin:0.4:exec (default) @ project.name ---
[INFO] Executing phantomjs command
'waitFor()' finished in 200ms.
Tests completed in 21 milliseconds.
5 tests of 5 passed, 0 failed.

如果测试通过,则您的构建将通过。如果测试失败,则您的构建将失败!


嗨,@Jonathan。我按照你提出的所有步骤进行了操作,但仍然无法正常工作。由于某种原因,我的HTML文件中没有任何测试被执行。 - prgrmr
@ideate 你尝试在常规浏览器中执行测试了吗?测试是否在浏览器中执行?你正在使用QUnit吗?我只是用QUnit测试过这个。 - Jonathan Benn
是的,在浏览器中测试执行得很好,我正在使用 Quint。问题是我使用了 GMarik 的 Github 页面上的示例驱动程序,我认为它对我不起作用。 - prgrmr
@ideate 哦,好的。我记得GMarik的驱动程序可以直接使用,但你可能需要调整一下。此外,PhantomJS并不完美,根据你在测试中所做的事情,它可能无法处理。例如,我发现它无法运行某些版本的OpenUI5。如果我是你,我会从一个简单的hello-world QUnit测试开始,看看是否可以运行。然后逐个添加更复杂的QUnit测试,并查看哪个会破坏PhantomJS。通过这种方式,你可能能够分离出问题。 - Jonathan Benn

1
我们刚刚将phantomJS.exe提交到源代码控制中。这样我们就可以确保所有机器上使用的是同一版本的phantomJS。

通常情况下,您希望避免将大型二进制文件检入源代码控制。这是Maven试图解决的问题之一,它通过提供一个简单的框架来下载二进制依赖项。 - Jonathan Benn
CI的一般规则是将构建和测试软件所需的所有内容都保留在源代码控制下。因此,在新机器上,您只需获取所需的代码版本并构建它,而无需手动安装任何工具。我们使用NuGet包管理器来帮助处理某些框架依赖项,但并非所有工具都可用。通过在源代码控制中拥有phantonJS.exe,我们可以确保每个构建都使用相同的版本,并且额外的奖励是我们不依赖于额外的存储库-只需要我们自己的源代码控制系统即可。 - GarethOwen

0

这是一个老问题,但我想我可以链接到我的一个项目,该项目使用PhantomJS和QUnit与TestNG一起运行:

该项目名为qunit-testng。我还有一个示例项目展示了该库的使用。

这是测试输出的屏幕截图:

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接