【问题标题】:How to Write Global Functions in Postman如何在 Postman 中编写全局函数
【发布时间】:2018-01-22 06:13:29
【问题描述】:

我需要帮助编写一个通用函数以在一组请求中使用,这将有助于构建框架。

我尝试过使用以下格式

以下函数在第一个函数的Test选项卡中声明

postman.setGlobalVariable("function", function function1(parameters)
{
  //sample code
});

我在预请求中使用了以下内容

var delay = eval(globals.function);
delay.function1(value1);

我收到以下错误

评估预请求脚本时出错:无法读取未定义的属性“function1”。

谁能帮我定义全局/通用函数并在请求中使用它们?

提前致谢

【问题讨论】:

标签: javascript postman


【解决方案1】:

在对象(或任何你想要的)上使用猴子补丁很容易实现。

选项 #1

关于集合级别的脚本

Object.prototype.doSomething = (foo) => console.log(foo);

在任何其他地方:

pm.doSomething('bar');

// or

postman.doSomething('bar');

选项 #2

关于集合级别的脚本

Utilities = {};
Utilities.getParam = (foo) => console.log(foo);

在任何其他地方

Utilities.getParam('bar');

【讨论】:

    【解决方案2】:

    上面的很多例子都会有 pm 变量的问题。为了在您的自定义 utils 方法中访问 pm 变量,您需要在 eval 之后将其传递进去。最重要的是,为您的实用程序提供一些模块化是很好的。将此粘贴为名称下的全局变量的值 -> Util

    (function () {
        const Util = function (pm) {
            return {
                customUtilFunction: function (customVariable) {
                    pm.environment.set("customVariable", customVariable);
                }
            }
        }
        return Util
    }())

    然后在您的测试中,您可以如下所示调用它。

    const Util = eval(pm.globals.get('Util'))(pm)
    Util.customUtilFunction('myCustomVariableValue')

    【讨论】:

    • 刚刚试过了,还是不行。甚至尝试了几种不同的方式对其进行修改,但仍然无法正常工作。 TypeError: eval(...) is not a function
    • 拳头你应该检查 pm.globals.get('Util') 返回什么。该错误清楚地表明“不是函数”。你能把 console.log(pm.globals.get('Util')) 的结果过去吗?
    【解决方案3】:

    编辑:以下答案仍然有效,您可以跳过并阅读它,但我想先发出警告:如果您尝试在 Postman 中使用它,您可能应该使用一些东西除了邮递员,如摩卡,供您测试。 Postman 适用于中小型应用程序,但使用 postman 维护非常大的多开发人员应用程序可能是一场噩梦。应用内编辑器对于大文件来说是一团糟,而且版本控制可能会出现问题。

    回答
    您可以使用以下语法获得更易读的解决方案和更多可能性来分解您的代码(例如直接在您的预请求脚本中从function2() 调用function1(),或声明包):

    初始化环境(或全局变量):

    postman.setEnvironmentVariable("utils", () => {
        var myFunction1 = () => {
            //do something
        }
        var myFunction2 = () => {
            let func1Result = myFunction1();
            //do something else
        }
        return {
            myPackage: {
                myFunction1,
                myFunction2
            }
        };
    });
    

    然后在以后的测试中使用你的函数:

    let utils = eval(environment.utils)();
    utils.myPackage.myFunction1(); //calls myFunction1()
    utils.myPackage.myFunction2(); //calls myFunction2() which uses myFunction1()
    

    奖金:

    如果您正在调用 API 并且需要在执行测试之前等待调用完成,您可以执行以下操作:

    postman.setEnvironmentVariable("utils", () => {
        var myFunction = (callback) => {
            return pm.sendRequest({
                // call your API with postman here
            }, function (err, res) {
                if (callback) {
                    //if a callback method has been given, it's called
                    callback();
                }
            });
        }
        
        return {
            myPackage: {
                myFunction,
            }
        };
    });
    

    然后使用它:

    utils.myPackage.myFunction(function() {
        console.log("this is the callback !")
        //perform test here
    });
    

    【讨论】:

      【解决方案4】:

      一种更优雅的方法是在预请求脚本中使用全局上下文(而不是变量)。 例如,如果您希望在任何预请求脚本中都可以使用名为 myFunction 的函数,您可以转到 Edit Collection/Pre-request 并设置

      globalThis.myFunction = function(){}
      

      然后您可以在集合内任何请求的任何预请求脚本中调用myFunction(无需对您的函数进行任何字符串化/评估)

      【讨论】:

      • 否:评估预请求脚本时出错:ReferenceError: globalThis is not defined
      【解决方案5】:

      将函数定义为全局变量,然后在所有测试中进行访问。

      pm.environment.set("UTILS", `({ myFunction: (text) => console.log(text) })`)
      

      调用函数

      let utils = eval(pm.environment.get("UTILS"))
      utils.myFunction('Test')
      

      【讨论】:

        【解决方案6】:

        没有eval

        在集合的预请求脚本中定义一个包含您的函数的对象,而不使用letvar 等。这会将其附加到 Postman 的全局沙箱对象。

        utils = {
          myFunc: function() {
            return 'hello';
          }
        };
        

        然后在您请求的预请求或测试脚本部分中调用该函数:

        console.log(utils.myFunc());
        

        【讨论】:

        • 这应该是答案。它以最简洁的方式实现了 OP 所追求的所有功能(全局可访问的功能),并且不使用 eval()。快速的 Google 会告诉您,出于安全性、性能和可调试性的原因,开发人员通常会避免使用 eval()
        • 这一直有效,直到您需要在其中一个函数中执行pm.environment.set('foo', 'bar'); 之类的操作。它运行没有错误,但变量永远不会被设置。
        • @Jake 我没有测试过这个,因为我最近没有使用 Postman,但我很想知道问题是否只是全局上下文无法访问环境上下文?也许pm.variables.set()pm.globals.set() 仍然有效?
        • @jake 我发现了与您描述的相同的问题。对于全局函数,我只是将 pm 作为参数传递给函数,这在我的用例中对我有用。如果我需要其他不在范围内的东西,显然可能会有点混乱。
        • 太棒了。谢谢!通过javascriptio.com/view/116768/… 找到这个并返回分享/信用只是发现它第一次在这里错过了它:D
        【解决方案7】:

        这个问题困扰了我一段时间,直到我找到了上面提到的常见方法。但是,它仍然会为每个 eval 行留下一个警告图标,在 postman 界面中指示“eval 可能有害”。 最近,我找到了另一种方法,并在这里发布: 用户可以在预请求脚本部分创建一个具有您想要的适当功能的原型对象,如下所示:

        Object.prototype.sayHello = function(name){
        console.log(`Hello! ${name}`);
        };
        

        然后在任何地方调用该函数。它只需要一个已定义的对象,如下所示:

        let obj = {};
        obj.sayHello(‘Griffin’);
        

        或者你甚至不需要对象的声明,而是使用一些内置对象,比如 lodash(你假装它有函数 :smile: )

        _.sayHello(‘Griffin’);
        

        它对我有用。我也在邮递员论坛上发布了它 https://community.postman.com/t/global-functions-via-collection-level-folder/5927/6?u=franksunnn110

        【讨论】:

        • 有效!但是要从请求脚本调用收集脚本中以这种方式声明的函数,只需要函数名即可。例如sayHello('Griffin');.
        • 这是我在翻转时代见过的最糟糕的黑客攻击,但它确实有效。这是我设法让它在预请求之间共享代码的唯一方法。经过这么长时间,POSTMAN 没有东西可共享代码真是荒谬。
        【解决方案8】:

        如果你想在全局函数中调用pm.sendRequest,试试这个:

        1. 在collection pre-request中定义全局函数,如下:

          pm.globals.set('globalFunction', parameters => {
              console.log(parameters);
              pm.sendRequest('https://google.com/', function(err, resp) {
                  pm.expect(err).to.not.be.ok;
              });
          });
          
        2. 使用这样的函数:

          eval(globals.globalFunction)('hello world!!');

        注意,我使用箭头样式()=>{} 声明了函数。否则就不行了。

        【讨论】:

        • 这对我不起作用。我收到There was an error in evaluating the Pre-request Script: TypeError: eval(...) is not a function
        【解决方案9】:

        您可以通过将该函数分配给集合、环境或全局变量来声明一个全局函数,如下所示:

        • 创建一个集合变量,即global_func
        • 在变量值中写下这段代码,

        (数字)=> { 返回数字 * 数字 }

        在您的收藏中的其他地方重复使用此功能

        let numberSquared = eval(pm.variables.get('global_func'))(5)
        

        现在,numberSqaure 变量的值为 25

        =================================

        如果你需要声明一个函数库: 您可以创建一个集合变量并将其分配给这段代码:

        ({
            print:function() {
                console.log('hello Postman')
            },
            squared:function(number) {
                return number * number
            }
        })
        

        注意:函数已用括号括起来

        重复使用这个库:

        let lib = eval(pm.variables.get('global_func'))
        lib1.print()
        console.log(lib1.squared(4))
        

        祝你好运:)

        【讨论】:

          【解决方案10】:

          我使用这个小技巧:

          pm.globals.set('loadUtils', function loadUtils() {
              let utils = {};
              utils.reuseableFunction = function reuseableFunction() {
                  let jsonData = JSON.parse(responseBody);
              }
              return utils;
          } + '; loadUtils();');
          tests['Utils initialized'] = true;
          

          在另一个请求中我可以重用全局变量loadUtils

          const utils = eval(globals.loadUtils);
          utils.reuseableFunction();
          

          您也可以查看developer roadmap of the Postman team。集合级脚本已列入近期议程,应该很快就会提供,直到那时您可以使用所示方法。

          【讨论】:

          • 注意:小心添加JSON.parse(responseBody);或pm.response.json();到您的实用程序,因为:首先,它在预请求脚本中不起作用,因为无法从那里访问响应对象。其次,在响应正文中没有可用 JSON 的情况下,它也可能无法在“测试”选项卡中工作:例如,XML 或 HTML。在引用响应对象的情况下,应考虑为测试和预请求脚本设置单独的工具。
          猜你喜欢
          • 1970-01-01
          • 2017-02-21
          • 2020-07-16
          • 1970-01-01
          • 2012-05-09
          • 2017-11-05
          • 2016-08-02
          • 2018-08-28
          • 1970-01-01
          相关资源
          最近更新 更多