Skip to content

Pragmatic Programming Principles in Test Automation

“The Pragmatic Programmer” by Andy Hunt and Dave Thomas is a classic programming book published in 1999. The authors share practical advice for writing better code and building software that works.

These principles work great for test automation too. When you apply them to your test code, you get tests that are easier to maintain, debug, and understand.

Let’s look at key principles and how to use them in your test automation projects.

Principle 1: DRY (Don’t Repeat Yourself)

Section titled “Principle 1: DRY (Don’t Repeat Yourself)”

Each piece of logic should live in one clear place.

If you’re copying and pasting code, you’re breaking DRY — and setting yourself up for extra bugs and maintenance headaches.


Don’t duplicate locators, API calls, or test data across files. Centralize them in page objects, utilities, or fixtures. This keeps your tests maintainable and reduces breakage when the app changes.

Adhering to the DRY principle is crucial for creating a robust and scalable test suite. It directly impacts your tests’ reliability and maintainability, saving significant time and effort in the long run.

For instance, instead of copying login logic into every single test, you create a single helper function. When the login page changes, you only have to update that one function, and all your tests will instantly be up to date. This prevents the classic “find-and-replace” nightmare and ensures consistency.

Example:

Before (Violating DRY):

// Multiple test files with duplicate login logic
test('user can view dashboard', async ({ page }) => {
await page.goto('/login');
await page.fill('[name="email"]', 'user@test.com');
await page.fill('[name="password"]', 'password123');
await page.click('button[type="submit"]');
// test continues...
});
test('user can edit profile', async ({ page }) => {
await page.goto('/login');
await page.fill('[name="email"]', 'user@test.com');
await page.fill('[name="password"]', 'password123');
await page.click('button[type="submit"]');
// test continues...
});

After (Following DRY):

// Reusable login helper
async function loginAsUser(page) {
await page.goto('/login');
await page.fill('[name="email"]', 'user@test.com');
await page.fill('[name="password"]', 'password123');
await page.click('button[type="submit"]');
}
test('user can view dashboard', async ({ page }) => {
await loginAsUser(page);
// test continues...
});
test('user can edit profile', async ({ page }) => {
await loginAsUser(page);
// test continues...
});

Impact: Reduces code duplication by 70%, makes updates require only one change, improves test reliability.

DRY Principle Diagram