web-dev-qa-db-ja.com

相対パスでrequireを使用する

Protractorには、かなり大きなエンドツーエンドのテストセットがあります。テストをクリーンでモジュール化した状態に保つのに役立つページオブジェクトパターンに従っています。また、 DRY原則 に従うのに役立つ一連のヘルパー関数もあります。

問題:

単一の仕様では、複数のページオブジェクトとヘルパーモジュールが必要になる場合があります。例えば:

"use strict";

var helpers = require("./../../helpers/helpers.js");
var localStoragePage = require("./../../helpers/localStorage.js");
var sessionStoragePage = require("./../../helpers/sessionStorage.js");

var loginPage = require("./../../po/login.po.js");
var headerPage = require("./../../po/header.po.js");
var queuePage = require("./../../po/queue.po.js");

describe("Login functionality", function () {

    beforeEach(function () {
        browser.get("/#login");

        localStoragePage.clear();
    });

    // ...

});

すべてのrequireステートメントでそのディレクトリトラバーサルがあることがわかります。./../..。これは、テスト対象のアプリケーション機能別にグループ化された仕様と複数のディレクトリを保持するspecsディレクトリがあるためです。

質問:

分度器の相対パス問題にアプローチする標準的な方法は何ですか?

言い換えれば、ツリーを走査してモジュールをインポートすることを避けたいのです。代わりに、ベースアプリケーションディレクトリから下に行く方がずっときれいです。


試みと考え:

この問題へのアプローチに関するすばらしい記事があります: Node.jsのローカルrequire()パスの改善 .

また、 require.main はパスを作成しますが、node_modules/protractorアプリケーションディレクトリではなくディレクトリ。

51
alecxe

私は同じ問題を抱えていて、次の解決策になりました。私のProtractor設定ファイルには、e2eテストのベースフォルダーへのパスを格納する変数があります。また、Protractorconfigは onPrepare コールバックを提供します。このコールバックでは、globalテスト用のグローバル変数を作成します。それらをそのglobal変数のプロパティとして定義し、テストでグローバルbrowserまたはelementを使用するのと同じ方法を使用します。さまざまなタイプのエンティティをロードするためのカスタムグローバルrequire関数を作成するために使用しました。

// __dirname retuns a path of this particular config file
// assuming that protractor.conf.js is in the root of the project
var basePath = __dirname + '/test/e2e/';
// /path/to/project/test/e2e/

exports.config = {

    onPrepare: function () {

        // "relativePath" - path, relative to "basePath" variable

        // If your entity files have suffixes - you can also keep them here
        // not to mention them in test files every time

        global.requirePO = function (relativePath) {
            return require(basePath + 'po/' + relativePath + '.po.js');
        };

        global.requireHelper = function (relativePath) {
            return require(basePath + 'helpers/' + relativePath + '.js');
        };

    }

};

そして、テストファイルでこれらのグローバルユーティリティメソッドをすぐに使用できます。

"use strict";    

var localStorageHelper = requireHelper('localStorage');
// /path/to/project/test/e2e/helpers/localStorage.js 

var loginPage = requirePO('login');
// /path/to/project/test/e2e/po/login.po.js

var productShowPage = requirePO('product/show');
// /path/to/project/test/e2e/po/product/show.po.js


describe("Login functionality", function () {

    beforeEach(function () {
        browser.get("/#login");

        localStorageHelper.clear();
    });

    // ...

});
26

私たちは同じ問題に直面しており、すべてのページオブジェクトとヘルパーファイルをノードパッケージに変えることにしました。テストでそれらを要求することはvar Header = require('header-po')と同じくらい簡単になりました。パッケージに変換するもう1つの利点は、適切なバージョン管理を使用できることです。

以下に簡単な例を示します。

./ page-objects/header-po/index.js

//page-objects/header-po/index.js

'use strict';

var Header = function () {
    this.goHome = function () {
        $('#logo a').click();
    };
  };

module.exports = Header;

./ page-objects/header-po/package.json

{
    "name": "header-po",
    "version": "0.1.1",
    "description": "Header page object",
    "main": "index.js",
    "dependencies": {}
}

./ package.json

{
    "name": "e2e-test-framework",
    "version": "0.1.0",
    "description": "Test framework",
    "dependencies": {
        "jasmine": "^2.1.1",
        "header-po": "./page-objects/header-po/",
    }
}

./ tests/header-test.js

'use strict';

var Header = require('header-po');

var header = new Header();

describe('Header Test', function () {
    it('clicking logo in header bar should open homepage', function () {
        browser.get(browser.baseUrl + '/testpage');
        header.goHome();
        expect(browser.getCurrentUrl()).toBe(browser.baseUrl);
    });
});
18
finspin

私も同じ問題を抱えています。 Michael Radionovと同様の解決策を行いましたが、グローバル関数を設定せず、分度器自体にプロパティを設定しました。

protractor.conf.js

onPrepare: function() {
  protractor.basePath = __dirname;
}

test-e2e.js

require(protractor.basePath+'/helpers.js');

describe('test', function() {
   .......
});
10
allenhwkim

私が働いている場所で使用している方法は、あなたにとって良い解決策だと思います。すべての処理方法の簡単な例を投稿しました。これはかなり素晴らしいb/cであり、specファイルでページオブジェクト関数を呼び出すだけで、specでrequireを使用する必要はありません。

どこでもrequire()を使用せずに別のモジュールからノードモジュールを呼び出す

2
BarretV