Monday, May 5, 2025

Best ways to Parameterize tests in playwright

In this example we will explore various technique to parameterize the test in playwright. In Playwright, parameterization typically refers to running tests with different sets of data to ensure your application behaves correctly under various conditions. This is often achieved using test parameterization techniques, allowing you to reuse test logic with multiple inputs. Below, I’ll explain how to implement parameterization in Playwright with examples.

Best ways to Parameterize tests in playwright



What is Parameterization?

Parameterization in testing means running the same test logic multiple times with different input values or data sets.

  1. Increased Test Coverage: By running the same script with various parameters, you can verify different test scenarios, ensuring comprehensive coverage of your application.
  2. Reduced Code Duplication: Parameterization helps you avoid writing redundant code for similar test cases, making your test suite more maintainable.
  3. Efficient Testing: Parameterization allows you to test multiple data sets, configurations, and inputs without having to write separate test scripts for each case.
  4. Improved Maintainability: Changes in test data or configurations are easier to manage when the script is parameterized.


Approaches to Parameterization in Playwright


1. Parameterizing with forEach()

In this example we are using forEach() loop to retrieve multiple data and pass it to test method.
// @ts-nocheck
import { test, expect } from '@playwright/test';

// Example : 1
[
  { user: 'standard_user', password: 'secret_sauce' },
  { user: 'locked_out_user', password: 'secret_sauce' },
  { user: 'problem_user', password: 'secret_sauce' },
  { user: 'performance_glitch_user', password: 'secret_sauce' }
].forEach(({ user, password }) => {

test(`testing with ${user}`, async ({ page }) => {
    await page.goto('https://www.saucedemo.com/v1/');    
    await page.locator('[data-test="username"]').fill('standard_user');    
    await page.locator('[data-test="password"]').fill('secret_sauce');    
    await page.getByRole('button', { name: 'LOGIN' }).click();
    await expect(page.locator('#inventory_filter_container')).toContainText('Products');    
  });
}); 

Output :
D:\playwright Project\Playwright-tutorial>npx playwright test parameterise.spec.js --project=chromium --headed

Running 4 tests using 2 workers

    1 [chromium]  tests\parameterise.spec.js:12:5  testing with locked_out_user (1.6s)
    2 [chromium]  tests\parameterise.spec.js:12:5  testing with standard_user (1.9s)
    3 [chromium]  tests\parameterise.spec.js:12:5  testing with problem_user (1.3s)
    4 [chromium]  tests\parameterise.spec.js:12:5  testing with performance_glitch_user (1.1s)

  4 passed (4.9s)

2. Parameterizing with for() loop

In this example we are using for() loop to retrieve multiple data and pass it to test method.

// @ts-nocheck
import { test, expect } from '@playwright/test';


const userData = [
  { user: 'standard_user', password: 'secret_sauce' },
  { user: 'locked_out_user', password: 'secret_sauce' },
  { user: 'problem_user', password: 'secret_sauce' },
  { user: 'performance_glitch_user', password: 'secret_sauce' }
  ];

  test.describe('Login Tests', () => {
    for (const { user, password  } of userData) {
      test(`Login with ${user} and ${password}`, async ({ page }) => {
        await page.goto('https://www.saucedemo.com/v1/');    
        await page.locator('[data-test="username"]').fill('standard_user');    
        await page.locator('[data-test="password"]').fill('secret_sauce');    
        await page.getByRole('button', { name: 'LOGIN' }).click();
        await expect(page.locator('#inventory_filter_container')).toContainText('Products');    
      });
    }
  });

Output :

D:\playwright Project\Playwright-tutorial>npx playwright test parameterise.spec.js --project=chromium --headed

Running 4 tests using 2 workers

    1 [chromium]  tests\parameterise.spec.js:15:11  Login Tests  Login with standard_user and secret_sauce (1.7s)
    2 [chromium]  tests\parameterise.spec.js:15:11  Login Tests  Login with locked_out_user and secret_sauce (1.8s)
    3 [chromium]  tests\parameterise.spec.js:15:11  Login Tests  Login with problem_user and secret_sauce (1.2s)
    4 [chromium]  tests\parameterise.spec.js:15:11  Login Tests  Login with performance_glitch_user and secret_sauce (1.1s)        

  4 passed (4.8s)

3. Parameterizing with custom fixture

You can create a custom fixture that accepts parameters, by modifying the test context:

userFixture.js
const base = require('@playwright/test');

exports.test = base.test.extend({
  userData: async ({}, use, testInfo) => {
    // Parameter from test title or metadata
    const user = testInfo.title.includes('admin') 
      ? { user: 'standard_user', password: 'secret_sauce' } 
      : { user: 'problem_user', password: 'secret_sauce' };

    await use(user);
  }
});

parameterise.spec.js
// @ts-nocheck
import { test } from '../fixtures/userFixture';
import { expect } from '@playwright/test';

test('Login as admin', async ({ page, userData }) => {
    await page.goto('https://www.saucedemo.com/v1/');    
    await page.locator('[data-test="username"]').fill(userData.user);    
    await page.locator('[data-test="password"]').fill(userData.password);    
    await page.getByRole('button', { name: 'LOGIN' }).click();    
    await expect(page.locator('#inventory_filter_container')).toContainText('Products');   
});

test('Login as problem_user', async ({ page, userData }) => {
    await page.goto('https://www.saucedemo.com/v1/');    
    await page.locator('[data-test="username"]').fill(userData.user);    
    await page.locator('[data-test="password"]').fill(userData.password);    
    await page.getByRole('button', { name: 'LOGIN' }).click();    
    await expect(page.locator('#inventory_filter_container')).toContainText('Products');   
});

Output:
D:\playwright Project\Playwright-tutorial>npx playwright test parameterise.spec.js --project=chromium --headed

Running 2 tests using 2 workers

    1 [chromium]  tests\parameterise.spec.js:6:5  Login as admin (2.1s)
    2 [chromium]  tests\parameterise.spec.js:14:5  Login as problem_user (2.1s)

  2 passed (4.2s)

This is all about parameterize test in playwright. Parameterized testing in Playwright allows us to run the same test logic with multiple sets of inputs, increasing test coverage and reducing duplication.


No comments:

Post a Comment