casperJS - grunt-casper:循环运行多个测试套件

时间:2015-08-24 14:15:24

标签: node.js gruntjs casperjs

制备

您好我正在将CasperJS与grunt-casper( github.com/iamchrismiller/grunt-casper )结合使用,以便在我们的GUI开发过程中运行自动功能和回归测试以进行验证。

我们像这样使用它, gruntfile.js 中的casper runner:

casper: {
      componentTests: {
        options: {
          args: ['--ssl-protocol=any', '--ignore-ssl-errors=true', '--web-security=no'],
          test: true,
          includes: ['tests/testutils/testutils.js']
        },
        files: {
          'tests/testruns/logfiles/<%= grunt.template.today("yyyy-mm-dd-hhMMss") %>/componenttests/concat-testresults.xml': [
            'tests/functionaltests/componenttests/componentTestController.js']
         }
      },

因为在这里可以看到我们通常只使用SSL参数运行casper测试,并且在这里只调用一个Controllerclass而不是列出单个测试(这是我问题的根源之一)。 grunt-casper提供负责测试的对象,并且在每个Controllerclass中包含并连接测试....

...现在 componentTestController.js 如下所示:

var config = require('../../../testconfiguration');
var urls = config.test_styleguide_components.urls;
var viewportSizes = config.test_styleguide_components.viewportSizes;
var testfiles = config.test_styleguide_components.testfiles;
var tempCaptureFolder = 'tests/testruns/temprun/';
var testutils = new testutils();

var x = require('casper').selectXPath;

casper.test.begin('COMPONENT TEST CONTROLLER', function(test) {

  casper.start();

  /* Run tests for all given URLs */
  casper.each(urls, function(self, url, i) {

    casper.thenOpen(url, function() {

      /* Test different viewport resolutions for every URL */
      casper.each(viewportSizes, function(self, actViewport, j) {

        /* Reset the viewport */
        casper.then(function() {
          casper.viewport(actViewport[0], actViewport[1]);
        });

        /* Run the respective tests */
        casper.then(function() {

          /* Single tests for every resolution and link */
          casper.each(testfiles, function(self, actTest, k) {

            casper.then(function() {
              require('.'+actTest);
            });

          });

        });

      });

    });

  });

  casper.run(function() {
    test.done();
  });
});

在这里你可以看到我们运行一个3级循环进行测试

  1. JSON配置文件中提供的所有URL,包含在ARRAY of String [&#34; url1.com&#34;,&#34; url2.com&#34; .....& #34; urln.com&#34;]
  2. 所有VIEWPORT SIZES,以便在我们所需的Viewport分辨率中测试每个URL,以测试组件的正确责任行为
  3. 所有TESTFILES,所有测试文件只包含一个TEST STUB是什么意思,没有开始,开始或其他什么,它都在一个大的Testsourrounding。
  4. 可能这已经是狡猾的,可以用更好的方式完成,所以如果是这样的话我会很高兴如果有人在这里提出建议,但不要忘记那个grunt-casper是作为跑步者参与的。

    问题

    到目前为止,这么好,一般工具工作正常,我们建造的工程按照我们的期望工作。但问题是,因为所有的测试文件都是在一个大的单个上下文中运行的,所以一个失败的组件会使整个套件失败。

    在正常情况下,这是我支持的行为,但在我们的情况下,我没有看到任何正确的解决方案,而不是记录错误/使单个testcomponent失败并继续运行。

    实施例: 我运行了一个测试,就像上面描述的setUp一样:

              /* Single tests for every resolution and link */
              casper.each(testfiles, function(self, actTest, k) {
    
                casper.then(function() {
                  require('.'+actTest);
                });
    
              });
    

    我们包含2个如下所示的测试文件:

    包含testfile1.js

    casper.then(function () {
      casper.waitForSelector(x("//a[normalize-space(text())='Atoms']"),
        function success() {
          casper.test.assertExists(x("//a[normalize-space(text())='Atoms']"));
          casper.click(x("//a[normalize-space(text())='Atoms']"));
        },
        function fail() {
          casper.test.assertExists(x("//a[normalize-space(text())='Atoms']"));
        });
    });
    

    包含testfile2.js

    casper.then(function () {
      casper.waitForSelector(x("//a[normalize-space(text())='Buttons']"),
        function success() {
          casper.test.assertExists(x("//a[normalize-space(text())='Buttons']"));
          casper.click(x("//a[normalize-space(text())='Buttons']"));
        },
        function fail() {
          testutils.createErrorScreenshot('#menu > li.active > ul > li:nth-child(7)', tempCaptureFolder, casper, 'BUTTONGROUPS#2-buttons-menu-does-not-exist.png');
          casper.test.assertExists(x("//a[normalize-space(text())='Buttons']"));
        });
    });
    

    因此,如果testfile1.js中的断言失败,那么everthing就会失败。那么我怎样才能继续使用testfile2.js,即使第一次失败?这可以配置吗?可以用某种方式封装吗?

    仅供参考,这不起作用: https://groups.google.com/d/msg/casperjs/3jlBIx96Tb8/RRPA9X8v6w4J

    几乎类似的问题

    我的问题几乎与此类似: https://stackoverflow.com/a/27755205/4353553

    这个家伙在这里有几乎我尝试的另一种方法,但也遇到了他的问题,因为多个测试套件在一个循环中运行出现问题: groups.google.com/forum /#!话题/ casperjs / VrtkdGQl3FA

    很多建议

1 个答案:

答案 0 :(得分:0)

希望我理解你所要求的东西 - 有没有办法来抑制失败的断言的异常抛出行为?

Tester的断言方法实际上允许覆盖在失败的断言上抛出异常的默认行为:

var message = "This test will always fail, but never throw an exception and fail the whole suite.";
test.assert(false, message, { doThrow: false });

并非所有断言帮助程序都有此选项,而我能想到的唯一其他解决方案是捕获异常:

var message = "This test will always fail, but never throw an exception and fail the whole suite.";
try {
  test.assertEquals(true, false, message);
} catch (e) { /* Ignore thrown exception. */ }

这两种方法都远非理想,因为我们的案例中的要求是不要抛出所有断言。

需要覆盖Tester实例的核心断言方法的另一个短期解决方案是(但仍然非常hacky):

// Override the default assert method. Hopefully the test
// casper property doesn't change between running suites.
casper.test.assert =
casper.test.assertTrue = (function () {
  // Save original assert.
  var __assert = casper.test.assert;
  return function (subject, message, context) {
    casper.log('Custom assert called!', 'debug');
    try {
      return __assert.apply(casper.test, arguments);
    }
    catch (error) {
      casper.test.processAssertionResult(error.result);
      return false;
    }
  };
})();

那就是说,我目前正在寻找一个非侵入性的解决方案来解决这个问题&#34; (也无法为doThrow设置默认值)。以上内容与我目前正在使用的Casper JS 1.1-beta3有关。