【问题标题】:Is there a way to speed up AngularJS protractor tests?有没有办法加快 AngularJS 量角器测试?
【发布时间】:2014-09-04 08:31:28
【问题描述】:

我已经为我的应用程序创建了测试。一切正常,但运行缓慢,即使只测试了 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 等无头浏览器。有没有人有这些更快的经验? 任何关于我如何做到这一点的建议将不胜感激。

【问题讨论】:

  • 在标记问题并建议结束时,请礼貌地解释原因。希望作为提出这些建议的人,您是量角器方面的专家。
  • 我建议分片。当我赶时间时,我会同时启动 10 个浏览器。确保您的套件是独立的(它们的运行顺序无关紧要)。
  • 嗨 Samantha,我以前用过 phantomJS,但我只考虑将它用于快速烟雾测试,归根结底,它不能代表用户交互,但它会大大加快您的测试速度。谨慎使用。除了上面提到的之外,如果不查看您的测试代码,将很难进一步帮助您。您的代码是否在 github 上的公共仓库或其他任何地方可用?例如,您可以通过在每次测试后不关闭浏览器等来节省时间......
  • 量角器测试基于承诺。所以总会有分辨率的滞后。考虑跨不同浏览器并行运行测试。此外(糟糕)手动运行测试单独获得更好的结果

标签: angularjs protractor


【解决方案1】:

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

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

【讨论】:

  • 我在我的问题中添加了更多细节。你认为我可以使用 shardTestFiles: true 吗?问题是我有两组测试,它们需要按顺序运行。
  • 嗨 Samantha,shardTestFiles 依赖于您的测试能够以任何顺序运行。在您的情况下,id 考虑完全拥有两个不同的存储库,因此您可以配置两个不同的运行器,以便在 CI 中相互运行。或者您可以找到一种以编程方式将它们联系在一起的方法。
【解决方案2】:

注入数据

您可以做的一件事可以大大提高性能,那就是不要重复测试。我的意思是,您最终会多次填写虚拟数据以达到一个步骤。这也是人们需要以特定顺序运行测试(以加快数据输入)的主要原因之一。

如果您想在网格(数据表)上测试过滤,就是一个例子。填写数据不是此操作的一部分。为了测试过滤器,您必须做一件烦人的事情。通过调用服务来添加数据,您可以绕过 UI 和 seleniums 一般缓慢(我还建议在服务器端使用迁移将值直接注入数据库)。

这样做的一个好方法是向您的页面对象添加一个帮助器,如下所示:

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] 将模块替换为双精度或模拟模块。您需要在调用 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']
}

【讨论】:

    【解决方案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()
        )
    

    【讨论】:

      【解决方案4】:

      我正在使用 grunt-protractor-runner v0.2.4,它使用量角器 ">=0.14.0-0

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

      希望对你有帮助

      【讨论】:

      • 谢谢。您是否查看过设置:chromeOnly:true 我在这里读到过:angular.github.io/protractor/#/server-setup 这表明不使用 Selenium 会加快速度。但是,除了此页面底部的几行之外,我找不到任何详细信息。
      【解决方案5】:

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

      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);
      }
      

      请注意:上面的代码不是我写的,我是在网上找方法来加快自己测试的。

      【讨论】:

      • 您对性能提升的幅度有任何衡量标准吗?我想这取决于使用了多少动画,但你有任何数据吗?
      【解决方案6】:

      据我所知:

      • 并行运行测试
      • 注入数据以防您只测试 UI 元素
      • 使用 CSS 选择器,不使用 xpath(浏览器有原生的 CSS 引擎,而 xpath 引擎的性能不如 CSS 引擎)
      • 在高性能机器上运行它们
      • 对在多次测试中经常重复的指令尽可能多地使用 beforeAll() 和 beforeEach() 方法

      【讨论】:

        【解决方案7】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-04-05
          • 1970-01-01
          • 1970-01-01
          • 2023-03-18
          • 1970-01-01
          • 2019-09-07
          • 2015-08-09
          • 1970-01-01
          相关资源
          最近更新 更多