DEV Community

Cover image for WET vs. DRY: Testing Principles You Should Know
artshllaku
artshllaku

Posted on

2

WET vs. DRY: Testing Principles You Should Know

In software development, writing clear and maintainable tests is as crucial as writing the code itself. Two commonly discussed principles in this context are WET (Write Everything Twice) and DRY (Don’t Repeat Yourself).

These principles help guide how we structure tests, balancing readability, maintainability, and efficiency. Let’s dive into what they mean, explore examples, and understand when to apply each approach.

📝 What is WET Testing?

WET testing is a style where repetition in test cases is allowed. While often seen as less ideal, this approach can prioritize simplicity and clarity—particularly for straightforward tests.

Pros of WET Tests:

  • Simplicity: Easy to read and understand, especially for newcomers.
  • Isolation: Each test stands on its own, avoiding dependencies.
  • Quick to Write: Ideal for smaller projects or simpler scenarios.

Example of WET Testing:

describe('Login Tests - WET', () => {
  test('should allow user to login with valid credentials', async () => {
    await page.goto('https://example.com/login');
    await page.fill('input[name="username"]', 'user1');
    await page.fill('input[name="password"]', 'password1');
    await page.click('button[type="submit"]');
    await expect(page).toHaveURL('https://example.com/dashboard');
  });

  test('should show an error with invalid credentials', async () => {
    await page.goto('https://example.com/login');
    await page.fill('input[name="username"]', 'user1');
    await page.fill('input[name="password"]', 'wrongpassword');
    await page.click('button[type="submit"]');
    await expect(page).toHaveText('Invalid username or password');
  });
});
Enter fullscreen mode Exit fullscreen mode

In this example, the login steps are repeated across tests.

✨ What is DRY Testing?

DRY testing focuses on minimizing redundancy by abstracting shared logic into reusable functions or setups. This approach shines in complex or large projects.

Pros of DRY Tests:

  • Reduced Redundancy: Centralizes logic, avoiding repetition.
  • Ease of Maintenance: Changes only need to be made in one place.
  • Cleaner Code: Focuses tests on behavior rather than setup.

Example of DRY Testing:

describe('Login Tests - DRY', () => {
  const login = async (username, password) => {
    await page.goto('https://example.com/login');
    await page.fill('input[name="username"]', username);
    await page.fill('input[name="password"]', password);
    await page.click('button[type="submit"]');
  };

  test('should allow user to login with valid credentials', async () => {
    await login('user1', 'password1');
    await expect(page).toHaveURL('https://example.com/dashboard');
  });

  test('should show an error with invalid credentials', async () => {
    await login('user1', 'wrongpassword');
    await expect(page).toHaveText('Invalid username or password');
  });
});
Enter fullscreen mode Exit fullscreen mode

Here, the login function centralizes the shared steps, making the tests cleaner and easier to maintain.

💡 When to Use WET vs. DRY?

From personal experience, choosing between WET and DRY depends on your project’s complexity and requirements.

Use WET when:

  • Your tests are simple and isolated.
  • The code is unlikely to change frequently.
  • You prioritize clarity over abstraction.

Use DRY when:

  • You have repeated logic across multiple tests.
  • The codebase is large and maintainability is a concern.
  • You need to refactor tests for efficiency.

🔑 Key Takeaways
While the DRY principle is generally preferred, WET tests have their place. Strive for a balance that enhances both clarity and maintainability. For smaller projects or straightforward scenarios, a WET approach might suffice. However, in larger, more complex test suites, adopting DRY can significantly improve your workflow.

Ultimately, the goal is to write tests that are clear, maintainable, and efficient—whatever approach gets you there!

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay