web-dev-qa-db-ja.com

AngularJS分度器テストを高速化する方法はありますか?

アプリケーションのテストを作成しました。すべてが機能しますが、実行速度が遅く、アプリケーションの3分の1しかテストされていなくても、プロトレーターがテストデータを作成し、フィールドに入力し、送信ボタンをクリックするのに約10分かかります。

テストにはGoogleCromeを使用しています。分度器がフィールドに1つずつ入力するのを見ると、遅いようです。

これが私のテストスイートの例です:

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']
},

これは1つのテストグループです。

    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'],

2つのグループは独立して実行できますが、上記の順序で実行する必要があります。回答後、共有について読みましたが、テストを順番に実行する必要があるため、これが私の状況に役立つかどうかはわかりません。理想的には、1つのテストセットを1つのブラウザーで実行し、もう1つのセットを別のブラウザーで実行したいと思います。

PhantomJSなどのヘッドレスブラウザについて読みました。誰かがこれらがより速いという経験を持っていますか?私がこれをどのように行うことができるかについてのアドバイスをいただければ幸いです。

20

現在、テストを並行して実行する "shardTestFiles:true" を使用しています。これは、複数のテストがある場合に役立ちます。

ここで何をテストしているか、データの作成か最終結果かはわかりません。後者の場合は、代わりにデータ作成をモックするか、他の方法でUIをバイパスすることを検討してください。

11
madz

データへの注入

パフォーマンスを大幅に向上させるためにできることの1つは、ダブルテストを行わないことです。これが意味するのは、ステップに到達するためにダミーデータを何度も入力することになるということです。また、(データ入力を高速化するために)特定の順序でテストを実行する必要がある主な理由の1つでもあります。

この例は、グリッド(データテーブル)でフィルタリングをテストする場合です。データの入力は、このアクションの一部ではありません。フィルタリングをテストするためにあなたがしなければならないのは、ただ面倒なことです。サービスを呼び出してデータを追加することで、UIとセレンの一般的な速度低下を回避できます(Idは、移行を使用してDBに直接値を挿入することにより、サーバー側でもこれを推奨します)。

これを行う良い方法は、次のようにページオブジェクトにヘルパーを追加することです。

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

この中のコードは最もクリーンではありませんが、一般的な要点を理解できます。もう1つの方法は、[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を機能構成に追加すると、(この場合)最大2つのテストを並列で実行できるようになります。 maxInstencesを増やして、実行するテストの数を増やします。 注:数値を高く設定しすぎないように注意してください。ブラウザは複数のスレッドを必要とする場合があり、新しいウィンドウを開く際の初期化コストもあります。

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

PhantomJSの設定(分度器のドキュメントから)

注:分度器でのテストにはPhantomJSを使用しないことをお勧めします。 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']
}
7
James Drew

私が見つけたもう1つの速度のヒントは、すべてのテストについて、テストの完了後にログインおよびログアウトしていたことです。ここで、ヘルパーメソッドで次の方法で既にログインしているかどうかを確認します。

  # 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
map7

私が知っていることから:

  • テストを並行して実行する
  • uI要素のみをテストする場合にデータを挿入する
  • cSSセレクターを使用し、xpathを使用しない(ブラウザーにはCSSのネイティブエンジンがあり、xpathエンジンはCSSエンジンとしてのパフォーマンスではありません)
  • 高性能マシンで実行します
  • 複数のテストで頻繁に繰り返す命令には、可能な限りbeforeAll()メソッドとbeforeEach()メソッドを使用します
2

上記の優れたヒントに加えて、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);
}

注意:上記のコードは作成していません。自分のテストを高速化する方法を探しているときにオンラインで見つけました。

2
John Stennett

分度器 "> = 0.14.0-0 <1.0.0"を使用するgrunt-protractor-runnerv0.2.4を使用しています。このバージョンは、最新バージョンより2倍または3倍高速です(protractor@^1.0.0に応じて[email protected]

したがって、以前のバージョンの分度器を試してテストすることをお勧めします

お役に立てれば

2
Cétia

Phantomjsを使用すると、GUIベースのブラウザーでかかる時間が大幅に短縮されますが、他のテストとは独立して任意の順序で実行できるようにテストを管理することをお勧めします。ORM(を使用すると簡単に実現できます。 jugglingdb、sequelizeなど)およびTDBフレームワーク、およびそれらをより管理しやすくするために、個々のテストのフックアップの前後にあるジャスミンまたはキュウリのフレームワークを使用できます。これで、マシンが「shardTestFiles:true」で耐えられる最大のインスタンスに対応できるようになりました。

1
Hardik Sheth