将 require 与相对路径一起使用 [英] Using require with relative paths

查看:25
本文介绍了将 require 与相对路径一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在 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 变量的属性,并使用与在测试中使用全局 browserelement 相同的方式.我用它来创建自定义全局 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 与相对路径一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆