問題描述
我們在 Protractor 上進行了相當多的端到端測試.我們遵循頁面對象模式,這有助于我們保持測試的清潔和模塊化.我們還有一組輔助函數來幫助我們遵循 DRY 原則.p>
問題:
單個規范可能需要多個頁面對象和幫助模塊.例如:
"使用嚴格";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("登錄功能", function () {之前(函數(){browser.get("/#login");localStoragePage.clear();});//...});
您可以看到我們在每個 require 語句中都有該目錄遍歷:./../..
.這是因為我們有一個 specs
目錄,我們將規范和多個目錄保存在其中,這些目錄按正在測試的應用程序功能分組.
問題:
在 Protractor 中解決相對路徑問題的規范方法是什么?
換句話說,我們希望避免遍歷樹,向上導入模塊.而是從基本應用程序目錄中下去會更干凈.
<小時>嘗試和想法:
關于解決這個問題有一篇很棒的文章:更好的 Node.js 本地 require() 路徑,但我不確定在使用 Protractor 開發測試時推薦使用哪個選項.
我們也嘗試過使用 require.main
來構造路徑,但它指向 node_modules/protractor
目錄而不是我們的應用程序目錄.
我遇到了同樣的問題,我最終得到了以下解決方案.在我的 Protractor 配置文件中,我有一個變量,它存儲了我的 e2e 測試的基本文件夾的路徑.此外,Protractor 配置提供了 onPrepare
回調,您可以在其中使用名為 global
的變量為您的測試創建全局變量.您將它們定義為該 global
變量的屬性,并使用與在測試中使用全局 browser
或 element
相同的方式.我用它來創建自定義全局 require 函數來加載不同類型的實體:
//__dirname 重新調整此特定配置文件的路徑//假設 protractor.conf.js 在項目的根目錄下var basePath = __dirname + '/test/e2e/';///path/to/project/test/e2e/出口.config = {onPrepare: 函數 () {//relativePath" - 相對于basePath"變量的路徑//如果你的實體文件有后綴 - 你也可以把它們放在這里//更不用說每次都在測試文件中global.requirePO = function (relativePath) {return require(basePath + 'po/' + relativePath + '.po.js');};global.requireHelper = function (relativePath) {return require(basePath + 'helpers/' + relativePath + '.js');};}};
然后您可以立即在測試文件中使用這些全局實用方法:
"使用嚴格";var localStorageHelper = requireHelper('localStorage');///path/to/project/test/e2e/helpers/localStorage.jsvar loginPage = requirePO('登錄');///path/to/project/test/e2e/po/login.po.jsvar productShowPage = requirePO('product/show');///path/to/project/test/e2e/po/product/show.po.jsdescribe("登錄功能", function () {之前(函數(){browser.get("/#login");localStorageHelper.clear();});//...});
We have a rather big set of end-to-end tests on Protractor. We are following the Page Object pattern which helps us to keep our tests clean and modular. We also have a set of helper functions which help us to follow the DRY principle.
The Problem:
A single spec may require multiple page objects and helper modules. For instance:
"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();
});
// ...
});
You can see that we have that directory traversal in every require statement: ./../..
. This is because we have a specs
directory where we keep the specs and multiple directories inside grouped by application functionality under test.
The Question:
What is the canonical way to approach the relative path problem in Protractor?
In other words, we'd like to avoid traversing the tree, going up to import modules. It would be much cleaner to go down from the base application directory instead.
Attempts and thoughts:
There is a great article about approaching this problem: Better local require() paths for Node.js, but I'm not sure which of the options is a recommended one when developing tests with Protractor.
We've also tried to use require.main
to construct the path, but it points to the node_modules/protractor
directory instead of our application directory.
I had the same problem and I ended up with the following solution.
In my Protractor config file I have a variable which stores a path to a base folder of my e2e tests. Also, Protractor config provides the onPrepare
callback, where you can use a variable called global
to create global variables for your tests. You define them as a properties of that global
variable and use the same way you use globals browser
or element
in tests. I've used it to create custom global require functions to load different types of entities:
// __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');
};
}
};
And then you can use these global utility methods in your test files right away:
"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();
});
// ...
});
這篇關于將 require 與相對路徑一起使用的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!