Mastering TypeScript Template Literals for Efficient Test Automation

Mastering TypeScript Template Literals for Efficient Test Automation

TypeScript's template literals: A game changer for test automation

TypeScript is a sophisticated JavaScript superset that provides optional static typing and other capabilities to assist developers in writing more robust and maintainable code. Template literals are one of TypeScript's many beneficial features, allowing you to easily build strings that contain expressions and variables.

A template literal is a string surrounded by backticks (') rather than single or double quotation marks. You can utilize placeholders within a template literal, which are represented by a dollar sign and curly brackets ($expression). At that moment, the value of the expression within the curly brackets is evaluated and added to the string. This makes it simple to build strings that contain dynamic data, such as variables or function call outcomes.

let name = "Srinivasan Sekar";
let age = 31;
console.log(`My name is ${name} and I am ${age} years old.`);
// Output: "My name is Srinivasan Sekar and I am 31 years old.

Two placeholders, $name and $age, are present in this example's template literal and are respectively replaced by the values of the name and age variables.

Test Automation Usecases

In test automation, template literals are very helpful since they make test code easier to comprehend and manage. To develop dynamic test cases, for instance, where the intended result relies on the input, utilize template literals. Here is an illustration of a test case that makes use of a template literal to verify that a function produces the desired outcome:

function addition(a: number, b: number): number {
  return a + b;
}

let a = 2;
let b = 3;
let expectedResult = `${a} + ${b} = ${addition(a, b)}`;

console.log(expectedResult);
// Output: "2 + 3 = 5"

The creation of dynamic test case descriptions is another application for template literals in test automation. To make it simpler to understand what the test case is checking for, you could use a template literal, for instance, to include the input values in the description of the test case. Here's an illustration:

describe('Test add function', () => {
  it(`adds ${a} and ${b} to equal ${add(a, b)}`, () => {
    expect(addition(a, b)).toEqual(5);
  });
});

In this example, a test case is defined using it function and the test case's first input is a template literal that specifies what it is checking for. Even if you are unfamiliar with the function being tested, it is simple to comprehend what the test case is doing as a result.

Additionally, dynamic test data can be produced using template literals. To generate an array of test data, for instance, where each member includes a distinct input value, use a template literal. Here's an illustration:

let testData = [
  { a: 1, b: 2 },
  { a: 3, b: 4 },
  { a: 5, b: 6 },
];

testData.forEach(data => {
  it(`adds ${data.a} and ${data.b} to equal ${add(data.a, data.b)}`, () => {
    expect(addition(data.a, data.b)).toEqual(data.a + data.b);
  });
});

In this illustration, the testData array holds several test cases, each of which is an object with the values a and b. The array is iterated over using the forEach method, which executes a test case for each element. The test case generates a dynamic test case description with the input values and the anticipated outcome using a template literal. This also makes it simple to observe the many inputs being supplied to the function and to comprehend what the test case is looking for.

API Tests

It's common practice to utilize placeholders in the URL and request body for dynamic data like user IDs or authentication tokens while testing an API. These dynamic data can be included in URLs and request bodies in a legible and maintainable manner by using template literals. Here is an illustration of an API test that generates a dynamic URL using a template literal:

const userId = '78926';
const url = `https://api.sample.com/users/${userId}`;

describe('Test user API', () => {
    it(`should return user details for id ${userId}`, async () => {
    const response = await axios.get(url);
    expect(response.status).toEqual(200);
    expect(response.data.id).toEqual(userId);
  });
});

UI tests

Selectors are frequently used to locate elements on a page when evaluating a user interface. Selectors that incorporate dynamic data, such as user IDs or names, can be made understandable and manageable by using template literals. Here is an illustration of a user interface test that builds a dynamic selector using template literals:

const userName = 'John Doe';
const selector = `//span[contains(text(), '${userName}')]`;

describe('Test user profile', () => {
    it(`should display user name ${userName}`, async () => {
    await page.goto('https://sample.com/userProfile');
    const element = await page.$(selector);
    expect(element).toBeTruthy();
  });
});

New Types

Using a method known as string literal types in TypeScript, template literals can be utilized to create new kinds. The creation of new kinds based on string literal values, such as template literals, is possible with the help of string literal types.

type direction = 'right' | 'left'

// string literal types created using Template Literal Type
type relativeLocators = `to${direction}Of`

// Type created without using Template Literal Type
type relativeLocatorsUsingUnion =
  | 'toLeftOf'
  | 'toRightOf'

DB tests

In SQL queries used for database testing, placeholders for changeable information like dates or user IDs are frequently used. SQL queries that contain these dynamic values in a legible and manageable manner can be made using template literals. Here is an illustration of a database test that generates a dynamic SQL query using a template literal:

const startDate = '2022-01-01';
const endDate = '2022-12-31';
const sql = `SELECT * FROM orders WHERE date BETWEEN '${startDate}' AND '${endDate}'`;

describe('Test orders', () => {
    it(`should return orders between ${startDate} and ${endDate}`, async () => {
    const rows = await db.query(sql);
    expect(rows.length).toBeGreaterThan(0);
  });
});

Load tests

Placing placeholders in the test script for dynamic numbers like the number of concurrent users or requests per second is a typical practice when performing load testing. These dynamic values can be included in test scripts in a comprehensible, manageable manner by using template literals. Here is an illustration of a load test that builds a dynamic test script using a template literal:

const concurrentUsers = 100;
const requestsPerSecond = 50;
const script = `
  var user = new User("https://example.com");
  user.addAction("visitHomepage", "GET", "/");
  user.addAction("login", "POST", "/login", {
    username: "testuser",
    password: "password"
  });

  runUsers(user, ${concurrentUsers}, ${requestsPerSecond});
`;

describe('Test website load', () => {
    it(`should handle ${concurrentUsers} concurrent users and ${requestsPerSecond} requests per second`, async () => {
    await loadtest.loadTest(script);
    expect(loadtest.getAvgResponseTime()).toBeLessThan(1000);
  });
});

In this case, the test script uses template literals to incorporate the dynamic values of concurrentUsers and requestsPerSecond in the load test. The runUsers function is used to mimic a certain number of concurrent users making requests at a certain pace. Changing the number of concurrent users or requests per second is made simple by this, eliminating the need to manually update the test script.

Conclusion

Finally, template literals are a strong TypeScript feature that may be used in a variety of ways in test automation. They are capable of producing dynamic test cases, test case descriptions, test data, and test case-specific strings. You may make your tests more legible and maintainable by utilizing template literals in your test code, which makes it easier to understand what your tests are doing and helps to ensure that your tests are correct.

Did you find this article valuable?

Support Srinivasan Sekar by becoming a sponsor. Any amount is appreciated!