javascript 对相对路径使用 require
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31491952/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using require with relative paths
提问by alecxe
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.
我们对 Protractor 进行了大量的端到端测试。我们遵循页面对象模式,这有助于我们保持测试干净和模块化。我们还有一组帮助函数来帮助我们遵循DRY 原则。
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.
你可以看到,我们有一个目录遍历在每一个需要声明:./../..
。这是因为我们有一个specs
目录,我们将规范和多个目录按测试中的应用程序功能分组保存在其中。
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.
有一篇关于解决这个问题的好文章:Better local require() paths for Node.js,但我不确定在使用 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.
我们也尝试使用require.main
来构造路径,但它指向的是node_modules/protractor
目录而不是我们的应用程序目录。
采纳答案by Michael Radionov
I had the same problem and I ended up with the following solution.
In my Protractorconfig file I have a variable which stores a path to a base folder of my e2e tests. Also, Protractorconfig 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:
我遇到了同样的问题,最终得到了以下解决方案。在我的Protractor配置文件中,我有一个变量,用于存储 e2e 测试的基本文件夹的路径。此外,Protractor配置提供了onPrepare
回调,您可以在其中使用名为的global
变量为您的测试创建全局变量。您将它们定义为该global
变量的属性,并使用与使用全局变量browser
或element
在测试中相同的方式。我用它来创建自定义全局要求函数来加载不同类型的实体:
// __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();
});
// ...
});
回答by finspin
We've been facing the same issue and decided to turn all page object and helper files into node packages. Requiring them in tests is now as easy as var Header = require('header-po')
. Another benefit of converting to packages is that you can use proper versioning.
我们一直面临同样的问题,并决定将所有页面对象和帮助文件转换为节点包。在测试中要求它们现在就像var Header = require('header-po')
. 转换为包的另一个好处是您可以使用正确的版本控制。
Here is a simple example:
这是一个简单的例子:
./page-objects/header-po/index.js
./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
./page-objects/header-po/package.json
{
"name": "header-po",
"version": "0.1.1",
"description": "Header page object",
"main": "index.js",
"dependencies": {}
}
./package.json
./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
./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);
});
});
回答by allenhwkim
I have had the same issue. Did similar solution to Michael Radionov's, but not setting a global function, but setting a property to protractor itself.
我有同样的问题。对 Michael Radionov 做了类似的解决方案,但不是设置全局函数,而是设置量角器本身的属性。
protractor.conf.js
量角器配置文件
onPrepare: function() {
protractor.basePath = __dirname;
}
test-e2e.js
测试-e2e.js
require(protractor.basePath+'/helpers.js');
describe('test', function() {
.......
});
回答by BarretV
I think the method we use where I work might be a good solution for you. I have posted a brief example of how we handle everything. It's pretty nice b/c you can just call the page object functions in any spec file and you don't need to use require in the spec.
我认为我们在我工作的地方使用的方法对您来说可能是一个很好的解决方案。我已经发布了一个关于我们如何处理所有事情的简短示例。这是非常好的 b/c 你可以在任何规范文件中调用页面对象函数,你不需要在规范中使用 require 。
Call a node module from another module without using require() everywhere