JavaScript for Testers Part 1: JS Basics for Postman

Written by ifoysol | Published 2023/05/22
Tech Story Tags: javascript | software-testing | postman | programming | javascript-tutorial | api-testing | api | tutorial

TLDRThis piece is a log of the author’s personal challenge to learn the bare minimum basics of JavaScript for API testing with the Postman tool. The target audience of this piece is SQA engineers and testers who have prior knowledge of one or two programming languages and clearly know what they are doing to get what output.via the TL;DR App

README.FIRST

This write-up is a log of the author’s personal challenge to learn the bare minimum basics of JavaScript in a tight timeline for a specific purpose.

Please, take this piece as a “foundation building up reading” if you are someone like me who just want to take API testing and the automation of rigorous tasks a step further with Postman and JavaScript. The author logged the bare-minimum JS basics he thinks are needed for API testing scripting in Postman. As such, this article omitted a good number of important topics like forEach and while loops and try-catch flow etc. that are a must for those who want to learn JS seriously.

The target audience of this log is SQA engineers and testers who have prior knowledge of one or two programming languages and clearly know what they are doing to get what output.

Scripting Scopes in Postman: Pre-request Script and Tests

Just a humble revision to the scripting scopes in Postman is given below:

  • Pre-request Script: In this tab, we write the scripts that will be run before making an HTTP request. These scripts include setting up and assigning environment variables, any modification of the request body, etc.

  • Tests: Scripts written in this tab are run after an HTTP request ends. These scripts include different tests like looking for specific data in the response body, setting up environment variables for the next request/s, testing response codes and time, etc.

  • Response: Response body is shown in this window. We can select format options like JSON, HTML etc. from there.

  • Console: This tab prints the request headers, errors, and any JavaScript code outputs.

You need not to worry about running the collection. It is available in the cloud here.

For this tutorial, I used test APIs in DummyJSON.

Postman has a node.js runtime that gives us the ability to modify HTTP requests dynamically.

The scripts we write in the Pre-request and Tests tabs are run in the Postman sandbox.

The following resources are two must bookmarks for an API tester who uses Postman

Scripting in Postman

Postman JavaScript reference

Day 1: Variables

Variables are the fundamental building blocks of a program or script. We store values in them. A variable in JavaScript can be declared using either var, let or const keywords.

As I have a specific scope for writing test cases for Postman, I have chosen let and const for brevity after doing some R&D with a JS veteran and on the internet.

  • Using let for variables that can be changed dynamically
let x = "ASDF"; 
console.log(x);
x = [1,2,3];
console.log(x);

  • Using const for variables that should be untouched
const lifeOfGeek = {
    first: "Family",
    second: "Geeky Things",
    third: "Career"
}; 

// avoid an accidental assignment in the same scope
lifeOfGeek = {
    first: "Greed",
    second: "Drugs",
    third: "Polygamy"
};
/*
$ node lifeOfGeek.js 
{ first: 'Family', second: 'Geeky Things', third: 'Career' }
life = {
     ^
TypeError: Assignment to constant variable.
...
*/

In the following example, we will declare some JS variables, set and get Postman environment variables in the Pre-request Script and Tests tabs that are the fundamental building blocks to script in the API testing tool.

Example Request: DAY_1_All_Products_VARIABLES

Action : Submit

The following codes are self-explanatory:

Pre-request Script tab

// Set an environment variable without any initial value 
pm.environment.set("eighthProduct");

// Set an environment variable with an initial value 
pm.environment.set("PI", 3.141);

Tests tab

// Assign response data in a JSON object
let jsonData = pm.response.json();

// Assign the 6th object to sixthProduct
let sixthProduct = jsonData["products"][5]; 
console.log("sixthProduct: ", sixthProduct);

// Assigning value to a pre-request script environment variable 
pm.environment.set("eighthProduct", jsonData["products"][7]);
console.log("eighthProduct: ", pm.environment.get("eighthProduct"));
console.log("PI: ", pm.environment.get("PI"));

Sample response

{
    "products": [
        {
            "id": 1,
            "title": "iPhone 9",
            "description": "An apple mobile which is nothing like apple",
            "price": 549,
            "discountPercentage": 12.96,
            "rating": 4.69,
            "stock": 94,
            "brand": "Apple",
            "category": "smartphones",
            "thumbnail": "https://i.dummyjson.com/data/products/1/thumbnail.jpg",
            "images": [
                "https://i.dummyjson.com/data/products/1/1.jpg",
                "https://i.dummyjson.com/data/products/1/2.jpg",
                "https://i.dummyjson.com/data/products/1/3.jpg",
                "https://i.dummyjson.com/data/products/1/4.jpg",
                "https://i.dummyjson.com/data/products/1/thumbnail.jpg"
            ]
        },
...

Please read the Day 1 section in my GitHub repository 7_Days_of_JS to learn more about JavaScript variables.

Day 2: Arrays

Arrays are indexed collections of the same or different types of objects. The behavior of arrays varies on the philosophy of programming languages. A JavaScript array can hold multiple types of objects in its indexes.

The basics of JS arrays are available here in my GitHub repository. The examples are well commented.

In the following Tests script, we will extract an array from a JSON response and append some arbitrary data in it.

Example Request: Day_2_All_Products_ARRAYS

Action: Send

Now look at the response JSON in the Body tab of the response window. We will extract the images array of the sixth item from it, which holds different images of a MacBook Pro.

...
{
            "id": 6,
            "title": "MacBook Pro",
            "description": "MacBook Pro 2021 with mini-LED display may launch between September, November",
            "price": 1749,
            "discountPercentage": 11.02,
            "rating": 4.57,
            "stock": 83,
            "brand": "Apple",
            "category": "laptops",
            "thumbnail": "https://i.dummyjson.com/data/products/6/thumbnail.png",
            "images": [
                "https://i.dummyjson.com/data/products/6/1.png",
                "https://i.dummyjson.com/data/products/6/2.jpg",
                "https://i.dummyjson.com/data/products/6/3.png",
                "https://i.dummyjson.com/data/products/6/4.jpg"
            ]
        }, 
...

Let’s parse the JSON, extract and print the expected array in the console

let jsonData = pm.response.json();
let sixthElementImages = jsonData.products[5]["images"];
/*
The above statement is equivalent to the following-
let sixthElementImages = jsonData["products"][5]["images"];
*/
console.log("sixthElementImages values: ", sixthElementImages);
/*
Expected Output 
"sixthElementImages values: "
> (4) ["https://i.dummyjson.com/data/products/6/1.png", "https://i.dummyjson.com/data/products/6/2.jpg", "https://i.dummyjson.com/data/products/6/3.png", "https://i.dummyjson.com/data/products/6/4.jpg"]
*/

Click the small arrow sign beside (4) to expand the object for a more readable formatted view.

The array contains four URLs to a MacBook Pro laptop.

Now, we will push different types of objects into it and see the effect.

sixthElementImages.push("A Quick Brown Fox");
sixthElementImages.push(["https://discord.com/", "https://www.notion.so/"]);
sixthElementImages.push(3.1141);

console.log("After push sixthElementImages values: ", sixthElementImages);
/*
Expected Output
"After push sixthElementImages values: " 
> (7) ["https://i.dummyjson.com/data/products/6/1.png", "https://i.dummyjson.com/data/products/6/2.jpg", "https://i.dummyjson.com/data/products/6/3.png", "https://i.dummyjson.com/data/products/6/4.jpg", "A Quick Brown Fox", …]
	0: "https://i.dummyjson.com/data/products/6/1.png"
	1: "https://i.dummyjson.com/data/products/6/2.jpg"
	2: "https://i.dummyjson.com/data/products/6/3.png"
	3: "https://i.dummyjson.com/data/products/6/4.jpg"
	4: "A Quick Brown Fox"
	5: [2]
		0: "https://discord.com/"
		1: "https://www.notion.so/"
	6: 3.1141
	*/

Notice, the length of sixthElementImages is increased from 4 to 7 as we pushed three new objects into it. Basic indexed operations are similar to other programming languages.

An interesting twist for geeks— a JS array is an object under-the-hood. PoC

console.log(typeof sixthElementImages);

Day 3: Objects

Objects, a key:value pair entity, play a vital role in JavaScript language that is used to store different types of data, variables, and functions for using them efficiently. In JavaScript, we can directly declare objects without creating a class.

Let’s declare a simple object.

const pcConfig = { // ... 1
	cpu: 'intel i5', 
	cores: 4,
	ram: '16 GB',
	motherBoard: 'Asus',
	'operating-system': {  // ... 2
		name: 'Debian',
		version: 11, 
		bits: 64
	}  
};

Some features of an object to be noticed:

  • It is a common practice to declare an object with const for avoiding unexpected assignments. This will be elaborated on later.

  • Although key/property names can be written without quotations, it is mandatory to use them if the key contains any special character or words reserved for JS.

Here is a PoC why we use const for declaring an object

const pcConfig = { // ... 1
	cpu: 'intel i5', 
	cores: 4,
	ram: '16 GB',
	motherBoard: 'Asus',
	'operating-system': {  // ... 2
		name: 'Debian',
		version: 11, 
		bits: 64
	}  
};

pcConfig["rgbLight"] = "N/A"; 

console.log(pcConfig);

pcConfig = "ASDF"; // avoid accidental reassignment

/*
$ node objectTest.js # Expected output 
{
  cpu: 'intel i5',
  cores: 4,
  ram: '16 GB',
  motherBoard: 'Asus',
  'operating-system': { name: 'Debian', version: 11, bits: 64 },
  rgbLight: 'N/A'
}
pcConfig = "ASDF"; 
         ^
TypeError: Assignment to constant variable.
...
*/

There are two more important fundamental concepts of deep and shallow copy of JavaScript objects discussed in my GitHub repository. The code is self-explanatory with necessary comments.

In the following example, we will convert a JS object into a JSON object and send the request body in a POST method to create an entity in the remote server.

// Declare a JS object
const jsObject = {
  id: 1000,
  title: 'Linux Phone 10',
  description: 'Custom Linux OS on custom embeded system',
  price: 1000,
  discountPercentage: 50,
  rating: 4.99,
  stock: 150,
  brand: 'Not Applicable',
  category: 'smartphones',
  thumbnail: 'https://linuxstans.com/wp-content/uploads/2022/02/[email protected]'
};
// The type is object
console.log(typeof jsObject);

// Convert the object into a string
let jsonData = JSON.stringify(jsObject);
// Notice: They keys or properties are now in double quotes
console.log(jsonData);

// The type is string
console.log(typeof jsonData);

Note: Keep in mind that JSON and JS objects are two different things.

Now paste this string into the POST request body, select raw radio button and select JSON from the right drop-down menu and finally, click the Beautify button to make the string more readable.

Example Request: Day_3_POST_Add_Product_OBJECTS

Action: Submit

JSON in Body tab after beautification

{
    "id": 1000,
    "title": "Linux Phone 10",
    "description": "Custom Linux OS on custom embeded system",
    "price": 1000,
    "discountPercentage": 50,
    "rating": 4.99,
    "stock": 150,
    "brand": "Not Applicable",
    "category": "smartphones",
    "thumbnail": "https://linuxstans.com/wp-content/uploads/2022/02/[email protected]"
}

Day 4: Loops

A loop repeats the workflow of a code block for a limited or infinite time. There are four types of for loops in JavaScript

  • Conventional
  • for.. in loop
  • for .. of loop
  • forEach loop that calls a callback function to control the workflow

I will discuss forEach and while in a future article.

The syntax of the first three type of for loops are:

// Conventional
for(let i = 0; i < lengthOfArray; i++){
    //codes here
}
// for .. in
for(index in object){
    //codes here
}

// for .. of
for(object of objectCollection){
    //codes here
}

A rule of thumb to remember the for.. in vs for .. of is

  • an in of for.. in returns the index of an object
  • an of of for.. of returns the value or object of a collection of objects

Day 5: Flow

The basic execution flow of a JavaScript code is controlled by if else blocks.

The following code chunk written in the Tests block filters outs odd-number product ids that are divisible by 15 and 23

Example Request: Day_5_All_Products_FLOW

Action: Send

let jsonData = pm.response.json();
let productsArray = jsonData["products"];

for(element of productsArray){
    // Filer the odd ids that are divisable by 15
    if(element["id"] % 2 !== 0 && element["id"] % 15 === 0){
        console.log(element)
    }

    // Filer the odd ids that are divisable by 23
    else if(element["id"] % 2 !== 0 && element["id"] % 23 === 0){
        console.log(element)
    }
}

/*
Sample Output 
{id: 15, title: "Eau De Perfume Spray", description: "Genuine  Al-Rehab spray perfume from UAE/Saudi Arabia/Yemen High Quality"…}
 
{id: 23, title: "Orange Essence Food Flavou", description: "Specifications of Orange Essence Food Flavour For Cakes and Baking Food Item"…}
 
{id: 45, title: "Malai Maxi Dress", description: "Ready to wear, Unique design according to modern standard fashion, Best fitting ,Imported stuff"…}
 
{id: 69, title: "Golden Watch Pearls Bracelet Watch", description: "Product details of Golden Watch Pearls Bracelet Watch For Girls - Golden Chain Ladies Bracelate Watch for Women"…}
 
{id: 75, title: "Seven Pocket Women Bag", description: "Seven Pocket Women Bag Handbags Lady Shoulder Crossbody Bag Female Purse Seven Pocket Bag"…}

*/

I will discuss try and catch in a future article.

Day 6: Functions

A function is a group of codes that we can reuse in a scope. This is the very first concept of code re-usability. The format of a function in JavaScript is given below

function functionName(param1, param2, ...){
	// Codes here 
	return returnValue1, returnValue1, ... ;
}

// Calling a function
functionName(param1, param2, ...);

Let’s write a basic function in the Tests tab that will check if an input is a prime number or not.

function isPrime (number) {
	let prime = true;
	if (number === 1 || number === 0) {
		return prime = false;
	}

	for (let i = 2; i < number; i++) {
		if (number % i === 0) {
			return prime = false;
		}
	}
	return prime;
}

Now, we will use this code block in a Postman request to filter out products that have a prime number price value.

Example Request: Day_6_All_Products_FUNCTIONS

Action: Send

let jsonData = pm.response.json();
let productsArray = jsonData["products"];
console.log("Products that have prime no. price values")
for(element of productsArray){
    // Filter prices that are prime in vlaues
    if(isPrime(element["price"])){
        console.log(element);
    }
}

/*
// A truncated view of the output in the Console

> {id: 69, title: "Golden Watch Pearls Bracelet Watch", description: "Product details of Golden Watch Pearls Bracelet Watch For Girls - Golden Chain Ladies Bracelate Watch for Women"…}
...
id: 69
title: "Golden Watch Pearls Bracelet Watch"
description: "Product details of Golden Watch Pearls Bracelet Watch For Girls - Golden Chain Ladies Bracelate Watch for Women"
price: 47
...
*/

Wrapping it Up

So far this was my 7-day journey to explore the tip of the JavaScript iceberg. In the next installment, I will come back with the basics of how to write test cases in Postman using JavaScript along with other necessary API testing tips and tricks.

I also wish to make Bangla video tutorials on API testing with JS and Postman in the future.

Until then, Happy Hacking!


Written by ifoysol | An avid learner, a parent, a self taught hardcore tester who breaks things to fix them.
Published by HackerNoon on 2023/05/22