有没有办法加速AngularJS量角器测试?

时间:2014-09-04 08:31:29

标签: angularjs protractor

我为我的应用程序创建了测试。一切正常,但运行缓慢,即使只有1/3的应用程序进行了测试,仍然需要大约十分钟才能让protrator创建测试数据,填写字段,点击提交按钮等。

我正在使用Google Crome进行测试。当我看着量角器逐一填写字段时,它似乎很慢。

以下是我的测试套件的一个示例:

suites: {
    login: ['Login/test.js'],            
    homePage: ['Home/test.js'],          
    adminPage: ['Admin/Home/test.js'],
    adminObjective: ['Admin/Objective/test.js'],
    adminObjDetail: ['Admin/ObjectiveDetail/test.js'],
    adminTopic: ['Admin/Topic/test.js'],
    adminTest: ['Admin/Test/test.js'],
    adminUser: ['Admin/User/test.js'],
    adminRole: ['Admin/Role/test.js']
},

这是一个测试组:

    login: ['Login/test.js'],            
    homePage: ['Home/test.js'],          
    adminUser: ['Admin/User/test.js'],
    adminRole: ['Admin/Role/test.js']

这是另一个测试组:

    adminPage: ['Admin/Home/test.js'],
    adminObjective: ['Admin/Objective/test.js'],
    adminObjDetail: ['Admin/ObjectiveDetail/test.js'],
    adminTopic: ['Admin/Topic/test.js'],
    adminTest: ['Admin/Test/test.js'],

这两个组可以独立运行,但必须按照我上面的顺序运行。在答案之后,我确实阅读了关于共享但我不确定这是否有助于我的情况,因为我的测试需要按顺序运行。理想情况下,我希望在一个浏览器中运行一组测试,而在另一个浏览器中设置另一组测试。

我读过像PhantomJS这样的无头浏览器。有没有人有这些更快的经验? 关于如何做到这一点的任何建议都将非常感激。

7 个答案:

答案 0 :(得分:11)

我们目前使用并行运行测试的"shardTestFiles: true",如果您有多个测试,这可能会有所帮助。

我不确定你在这里测试什么,无论是数据创建还是最终结果。如果是后者,您可能需要考虑模拟数据创建,或者以其他方式绕过UI。

答案 1 :(得分:7)

在数据中注入

你可以做的一件事就是给你带来性能上的重大提升,就是不要加倍测试。我的意思是你最终会多次填充虚拟数据以达到一个步骤。它也是人们需要测试以某种顺序运行(加速数据输入)的主要原因之一。

此示例是您要在网格(数据表)上测试过滤。填写数据不是此操作的一部分。它只是一个烦人的事情,你必须做到测试过滤。通过调用服务来添加数据,您可以绕过UI和selenium一般缓慢(Id也建议在服务器端通过使用迁移将值直接注入数据库)。

一个很好的方法是在页面对象中添加一个帮助程序,如下所示:

module.exports = {
    projects: {
        create: function(data) {
            return browser.executeAsyncScript(function(data, callback) {
                var api = angular.injector(['ProtractorProjectsApp']).get('apiService');
                api.project.save(data, function(newItem) {
                    callback(newItem._id);
                })
            }, data);
        }
    }
};

这里的代码不是最干净但你得到了它的一般要点。另一种方法是使用[Protractor#addMockModule] [1]用double或mock替换模块。在调用Protractor#get()之前,需要添加此代码。如果它与现有服务具有相同的名称,它将在应用程序服务覆盖后加载。

您可以按如下方式使用它:

var dataUtilMockModule = function () {
     // Create a new module which depends on your data creation utilities
    var utilModule = angular.module('dataUtil', ['platform']);
    // Create a new service in the module that creates a new entity
    utilModule.service('EntityCreation', ['EntityDataService', '$q', function (EntityDataService, $q) {

        /**
         * Returns a promise which is resolved/rejected according to entity creation success
         * @returns {*}
         */
        this.createEntity = function (details,type) {
            // This is your business logic for creating entities
            var entity = EntityDataService.Entity(details).ofType(type);
            var promise = entity.save();
            return promise;
        };
    }]);
};

browser.addMockModule('dataUtil', dataUtilMockModule);

这两种方法都可以为您的测试带来显着的加速。

分片测​​试

对测试进行分片意味着拆分套件并将它们并行运行。在量角器中这样做非常简单。将shardTestFiles和maxInstences添加到您的功能配置应允许您(在这种情况下)以并行方式运行最多两次测试。增加maxInstences以增加运行的测试次数。 注意:注意不要将数字设置得太高。浏览器可能需要多个线程,并且在打开新窗口时也存在初始化成本。

capabilities: {
    browserName: 'chrome',
    shardTestFiles: true,
    maxInstances: 2
},

设置PhantomJS(来自量角器文档)

注意:我们建议不要使用PhantomJS进行Protractor测试。有很多报道的问题,PhantomJS崩溃并且表现与真实浏览器不同。

为了使用PhantomJS进行本地测试,您需要全局安装或相对于项目安装。有关全局安装,请参阅PhantomJS下载页面(http://phantomjs.org/download.html)。对于本地安装运行:npm install phantomjs

将phantomjs添加到驱动程序功能中,如果使用本地安装,则包含二进制文件的路径:

capabilities: {
  'browserName': 'phantomjs',

  /* 
   * Can be used to specify the phantomjs binary path.
   * This can generally be ommitted if you installed phantomjs globally.
   */
  'phantomjs.binary.path': require('phantomjs').path,

  /*
   * Command line args to pass to ghostdriver, phantomjs's browser driver.
   * See https://github.com/detro/ghostdriver#faq
   */
  'phantomjs.ghostdriver.cli.args': ['--loglevel=DEBUG']
}

答案 2 :(得分:3)

我发现的另一个速度提示是,每次测试我都会登录并在测试完成后退出。现在我检查我是否已经在我的帮助方法中使用以下内容登录;

  # Login to the system and make sure we are logged in.
  login: ->
    browser.get("/login")
    element(By.id("username")).isPresent().then((logged_in) ->
      if logged_in == false
        element(By.id("staff_username")).sendKeys("admin")
        element(By.id("staff_password")).sendKeys("password")
        element(By.id("login")).click()
    )

答案 3 :(得分:2)

我使用grunt-protractor-runner v0.2.4,它使用量角器"> = 0.14.0-0< 1.0.0"。 这个版本比最新版本快2到3倍(grunt-protractor-runner@1.1.4取决于protractor@^1.0.0)

所以我建议你试试并测试以前版本的量角器

希望这有帮助

答案 4 :(得分:2)

除了上面提到的重要提示外,我还建议禁用Angular / CSS动画,以便在非无头浏览器中运行时加快速度。我个人在我的'conf.js'文件中的“onPrepare”函数中使用我的Test Suite中的以下代码:

onPrepare: function() {
    var disableNgAnimate = function() {
        angular
            .module('disableNgAnimate', [])
            .run(['$animate', function($animate) {
                $animate.enabled(false);
            }]);
    };

    var disableCssAnimate = function() {
        angular
            .module('disableCssAnimate', [])
            .run(function() {
                var style = document.createElement('style');
                style.type = 'text/css';
                style.innerHTML = '* {' +
                    '-webkit-transition: none !important;' +
                    '-moz-transition: none !important' +
                    '-o-transition: none !important' +
                    '-ms-transition: none !important' +
                    'transition: none !important' +
                    '}';
                document.getElementsByTagName('head')[0].appendChild(style);
            });
    };

    browser.addMockModule('disableNgAnimate', disableNgAnimate);
    browser.addMockModule('disableCssAnimate', disableCssAnimate);
}

请注意:我没有写上面的代码,我在网上找到了加速自己测试的方法。

答案 5 :(得分:2)

据我所知:

  • 并行运行测试
  • 在您仅测试UI元素的情况下注入数据
  • 使用CSS选择器,没有xpath(浏览器有CSS的本机引擎,而xpath引擎不是CSS引擎的性能)
  • 在高性能机器上运行它们
  • 尽可能多地使用beforeAll()和beforeEach()方法,以获取在多次测试中经常重复的说明

答案 6 :(得分:1)

使用Phantomjs将大大减少基于GUI的浏览器所需的持续时间,但我发现更好的解决方案是以独立于其他测试的任何顺序运行测试,可以通过使用轻松实现ORM(jugglingdb,sequelize等等)和TDB框架,为了使它们更易于管理,可以使用茉莉或黄瓜框架,它具有针对单个测试的连接之前和之后。所以现在我们可以通过“shardTestFiles:true”来支持我们的机器可以承受的最大实例。