对相对路径使用 require [英] Using require with relative paths

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

问题描述

我们对 Protractor 进行了大量的端到端测试.我们遵循页面对象模式,这有助于我们保持测试干净和模块化.我们还有一组辅助函数,可帮助我们遵循 DRY 原则.>

问题:

单个规范可能需要多个页面对象和辅助模块.例如:

"使用严格";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");描述(登录功能",函数(){beforeEach(函数(){browser.get("/#login");localStoragePage.clear();});//...});

您可以看到我们在每个 require 语句中都有该目录遍历:./../...这是因为我们有一个 specs 目录,我们将规范和多个目录保存在其中,按测试中的应用程序功能分组.

问题:

在量角器中处理相对路径问题的规范方法是什么?

换句话说,我们希望避免遍历树,向上导入模块.相反,从基础应用程序目录下移会更简洁.

<小时>

尝试和想法:

有一篇关于解决这个问题的好文章:更好的 Node.js 本地 require() 路径,但在使用 Protractor 开发测试时,我不确定哪些选项是推荐的.

我们也尝试使用 require.main 构建路径,但它指向 node_modules/protractor 目录而不是我们的应用程序目录.

解决方案

我遇到了同样的问题,最终得到了以下解决方案.在我的 Protractor 配置文件中,我有一个变量,用于存储 e2e 测试的基本文件夹的路径.此外,Protractor 配置提供了 onPrepare 回调,您可以在其中使用名为 global 的变量为您的测试创建全局变量.您将它们定义为该 global 变量的属性,并使用与在测试中使用 globals browserelement 相同的方式.我用它来创建自定义全局要求函数来加载不同类型的实体:

//__dirname 返回此特定配置文件的路径//假设 protractor.conf.js 在项目的根目录下var basePath = __dirname + '/test/e2e/';///path/to/project/test/e2e/出口.config = {onPrepare: 函数 () {//"relativePath" - 路径,相对于 "basePath" 变量//如果您的实体文件有后缀 - 您也可以将它们保留在这里//不要每次都在测试文件中提及它们global.requirePO = 函数(相对路径){return require(basePath + 'po/' + relativePath + '.po.js');};global.requireHelper = 函数(相对路径){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.js描述(登录功能",函数(){beforeEach(函数(){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天全站免登陆