Search code examples
node.jstestingpostmanpuppeteernewman

Modify environment with tests while running Postman Newman in NodeJS


I'm running Newman in a Node Script. The collection has environment variables such as {{claimNum}} that would increment with each post by the test.

Example:

I have this collection request body

 <ClaimIdentification>
      <company>0001</company>
      <office>100</office>
      <claimNum>{{claimNum}}</claimNum>
 </ClaimIdentification>

And in the global environment JSON:

  {
  "enabled": true,
  "key": "claimNum",
  "value": "15200",
  "type": "text"
},

And the collection has this test:

pm.globals.set("claimNum", + pm.globals.get("claimNum") + 1);

But when ran in the script, the global.json file won't be modified and the "value" would stay the same. When this same parameters are run in the desktop app, it works.

Is there a solutions for this, should this work?

UPDATE1:

This is the newman script:

  collection: require('${__dirname}/ThirdServiceInjured.json'),
  reporters: 'json',
  globals: require('${__dirname}/globals.json')

}).on('done', function (err, summary) {
  if (err || summary.error) {
      console.error('>>> ERROR - Collection run failed.');
  }
  else {
    console.log(success('Collection run completed:'));  
    console.log(summary.run.executions[0].response.text());
  }
});

UPDATE 2:

Using this script and still not writing over the enviroment:

const newman = require('newman'); // require newman in your project
const fs = require('fs');
const envName = '${__dirname}/environment_qbe600.json';
const env = require('${__dirname}/environment_qbe600.json');

newman.run({
  collection: require('${__dirname}/ThirdServiceInjured.json'),
  reporters: 'cli',
  environment: envName,
  iterationCount: 3

}).on('done', function (err, summary) {
  if (err || summary.error) {
      console.error('>>> ERROR - Collection run could failed.');
}
else {
  const newmanValue = summary.environment.values.members[0].value;
  env.values[0].value = newmanValue;
  console.log(summary.run.executions[0].response.text());
  fs.writeFile(envName, JSON.stringify(env, null, 2), function (err) {
    if (err) return
  })
}
});

UPDATE 3:

This is the enviroment:

{
  "id": "ecabb925-829e-69f8-2348-f71dc76c0e87",
  "name": "Test",
  "values": [
    {
      "enabled": true,
      "key": "host",
      "value": "${___server}",
      "type": "text"
    },
    {
      "enabled": true,
      "key": "company",
      "value": "0001",
      "type": "text"
    },
    {
      "enabled": true,
      "key": "claimNbr",
      "value": "14600",
      "type": "text"
    },
    {
      "enabled": true,
      "key": "dni",
      "value": "150",
      "type": "text"
    },
    {
      "enabled": true,
      "key": "cost",
      "value": "107000",
      "type": "text"
    },
    {
      "enabled": true,
      "key": "testNum",
      "value": "157",
      "type": "text"
    }
  ],
  "timestamp": 1515789551332,
  "_postman_variable_scope": "environment",
  "_postman_exported_at": "2018-01-12T20:39:14.795Z",
  "_postman_exported_using": "Postman/5.5.0"

And the test section from the collection:

"event": [
    {
        "listen": "test",
        "script": {
            "type": "text/javascript",
            "exec": [
                "pm.environment.set(\"claimNbr\", +pm.environment.get(\"claimNbr\") + 1);",
                "pm.environment.set(\"testNum\", +pm.environment.get(\"testNum\") + 1);",
                "pm.environment.set(\"dni\", +pm.environment.get(\"dni\") + 1);",
                "pm.environment.set(\"cost\", +pm.environment.get(\"cost\") + 1000);"
            ]
        }
    }
],

Solution

  • Having looked at the following recent issue on the Postman Github account

    If you change the global variable to be a environment variable that would allow you to see the updated value each time it's run. I just changed your test code to environment rather than global.

    pm.environment.set("claimNum", + pm.environment.get("claimNum") + 1)
    

    I created a basic node script to run Newman with the Collection and Environment files exported from Postman:

    var newman = require('newman')
    
    newman.run({
        collection: `${__dirname}/default_collection.json`,
        environment: `${__dirname}/default_environment.json`,
        reporters: 'cli',
        iterationCount: 10
      }, (err) => {
        if (err) { throw err }
      })
    

    My two files referenced in the newman script:

    default_collection.json

    {
        "info": {
            "name": "Test_Collection",
            "_postman_id": "d08f1b36-591a-f25f-aaaa-4368ca966fb4",
            "description": "",
            "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
        },
        "item": [
            {
                "name": "Test_Request",
                "event": [
                    {
                        "listen": "test",
                        "script": {
                            "id": "068b6634-e310-46e9-86fc-265376c65ff6",
                            "type": "text/javascript",
                            "exec": [
                                "console.log(pm.environment.get('claimNum'))"
                            ]
                        }
                    }
                ],
                "request": {
                    "method": "POST",
                    "header": [
                        {
                            "key": "Content-Type",
                            "value": "application/json"
                        }
                    ],
                    "body": {
                        "mode": "raw",
                        "raw": "{\n\t\"id\": {{claimNum}}\n}"
                    },
                    "url": {
                        "raw": "localhost:3000/test",
                        "host": [
                            "localhost"
                        ],
                        "port": "3000",
                        "path": [
                            "test"
                        ]
                    },
                    "description": ""
                },
                "response": []
            }
        ],
        "event": [
            {
                "listen": "prerequest",
                "script": {
                    "id": "4c1d562f-e4d5-4017-8f25-48ac0b6aa3fc",
                    "type": "text/javascript",
                    "exec": [
                        ""
                    ]
                }
            },
            {
                "listen": "test",
                "script": {
                    "id": "026c029e-a427-4624-b196-3d8982a103f1",
                    "type": "text/javascript",
                    "exec": [
                        "pm.environment.set(\"claimNum\", + pm.environment.get(\"claimNum\") + 1)"
                    ]
                }
            }
        ]
    }
    

    default_environment.json

    {
      "id": "539073e6-adab-f812-95b0-82d4d82ce4b2",
      "name": "test_environment",
      "values": [
        {
          "enabled": true,
          "key": "claimNum",
          "value": "9",
          "type": "text"
        }
      ],
      "timestamp": 1515782483636,
      "_postman_variable_scope": "environment",
      "_postman_exported_at": "2018-01-12T18:42:04.661Z",
      "_postman_exported_using": "Postman/5.5.0"
    }
    

    I added iterationCount: 10 to the script so that I could see the claimNum increase on each iteration.

    Newman Test Run

    In Postman, I added a simple console.log() to write out the claimNum on each test run - You can see the output in the image above.

    console.log(pm.environment.get('claimNum'))
    

    My request body in using JSON but the {{claimNum}} would work the same with XML like in your example.

    This one solution to the problem but as it's using not using a global variable and I'm unsure of your requirement - It might not be what you're after.


    UPDATE 1

    Depending on the use case that you have - The environment file can be updated to show the last run value and can use this value in the next request - So that it's not repeatedly running a test against the same value in the static file. Running the following code would run the test and then update the value in the default_environment.json file.

    const newman   = require('newman')
    const fs       = require('fs');
    const fileName = `${__dirname}/default_environment.json`;
    const file     = require(fileName);
    
    newman.run({
        collection: `${__dirname}/default_collection.json`,
        environment: `${__dirname}/default_environment.json`,
        reporters: 'cli',
        iterationCount: 3
    }).on('done', function (err, summary) {
      if (err || summary.error) {
        console.error('>>> ERROR - Collection run failed.');
      }
      else {
        const newmanValue = summary.environment.values.members[0].value
        file.values[0].value = newmanValue
    
        fs.writeFile(fileName, JSON.stringify(file, null, 2), function (err) {
          if (err) return
        })
      }
    }) 
    

    My environment file would look something like this following the test run:

    {
      "name": "test_environment",
      "values": [
        {
          "enabled": true,
          "key": "claimNum",
          "value": 19,
          "type": "text"
        }
      ]
    }
    

    File Update


    UPDATE 2

    Having modified the code again with the new information this is working locally for me:

    Newman Run Script

    const newman  = require('newman')
    const fs      = require('fs')
    const envName = `${__dirname}/default_environment.json`
    const env     = require(envName)
    
    newman.run({
      collection: require(`${__dirname}/default_collection.json`),
      reporters: 'cli',
      environment: envName,
      iterationCount: 3
    
    }).on('done', function (err, summary) {
      if (err || summary.error) {
          console.error('ERROR - Collection run could failed')
    }
    else {
      const claimNbr  = summary.environment.values.members[0].value
      const testNum   = summary.environment.values.members[1].value
      const dni       = summary.environment.values.members[2].value
      const cost      = summary.environment.values.members[3].value
    
      env.values[0].value = claimNbr
      env.values[1].value = testNum
      env.values[2].value = dni
      env.values[3].value = cost
    
      fs.writeFile(envName, JSON.stringify(env, null, 2), function (err) {
        if (err) return
      })
      console.log('Collection run complete') 
    }
    })
    

    The test section in the Collection file

        "name": "Test_Request",
        "event": [
            {
                "listen": "test",
                "script": {
                    "id": "a407e1e2-4961-4c65-af1b-22190b1ab0cc",
                    "type": "text/javascript",
                    "exec": [
                        "pm.environment.set(\"claimNbr\", + pm.environment.get(\"claimNbr\") + 1)",
                        "pm.environment.set(\"testNum\", + pm.environment.get(\"testNum\") + 1)",
                        "pm.environment.set(\"dni\", + pm.environment.get(\"dni\") + 1)",
                        "pm.environment.set(\"cost\", + pm.environment.get(\"cost\") + 1000)",
                        "",
                        "console.log(JSON.stringify(pm.response.json()))"
                    ]
                }
            }
        ]
    

    Postman Request Body

    Postman Request Body

    Script Running and Updating the environment file

    Newman Run