Getting Started with Automation: When, Why & How
Getting Started with Automation: When, Why & How
Automation is one of those topics everyone talks about — and few start correctly. In this post I’ll walk you through: deciding what to automate, what to avoid, selecting tools, building a simple test, and how to integrate automation into CI. I’ll show runnable examples in both Python (Playwright + pytest) and JavaScript (Playwright + Cypress) so you can pick what fits your stack.
Why automation — the real business case
Automation isn’t about being fancy or saving a few clicks. You automate to:
- Increase confidence — run the same checks consistently on every build
- Save time — free human testers to do higher-value exploratory work
- Reduce human error — eliminate flaky manual repetition
- Provide fast feedback — testers and developers learn about regressions immediately
What to automate — a practical decision matrix
Not every test should be automated. Use this quick matrix to decide:
| Question | Automate? |
|---|---|
| Is this test stable (UI rarely changes)? | Yes |
| Is it run often (smoke/regression)? | Yes |
| Is it deterministic (no manual captchas or human review)? | Yes |
| Is it exploratory or UX-specific? | No — manual |
| Is the ROI low (one-off check)? | No — manual |
Common categories to automate
- Core flows (login, checkout, payments)
- APIs and contract tests (fast and reliable)
- Smoke tests for deployments
- Regression tests for critical business logic
When not to automate (and why)
Don’t automate everything. Avoid automating:
- UI layouts that change frequently during design iteration
- Visual aesthetics that require human judgment (use visual testing selectively)
- One-off migration checks (unless repeated)
- Tasks that are cheaper to do manually than maintain automation for
Choosing your tooling — a short guide
There are many tools — here’s how I recommend choosing based on your needs:
- Selenium: Mature, language-agnostic, good for legacy systems and wide browser coverage.
- Playwright: Modern, fast, supports multiple browsers, reliable selectors — great for modern web apps.
- Cypress: Great DX (developer experience), fast, but runs in Chrome-family browsers (good for many apps).
- API tools: Postman/Newman, REST-assured (Java), or direct HTTP clients — choose based on language.
Test pyramid: where automation delivers the most value
Remember the test pyramid: lots of unit tests (fast), a healthy set of API/integration tests, and a small number of UI tests. This keeps your CI quick and stable.
Project example — what I automated first
At an e-commerce startup I joined, deployments were daily and the checkout was fragile. We started by automating:
- API contract tests for payments
- End-to-end smoke: login → add to cart → checkout (single critical path)
- Regression of promo code logic (data-driven)
This gave immediate protection for revenue-critical flows while leaving exploratory testing for UX changes to humans.
How to design a simple, maintainable UI test
Design tests with readability, maintainability, and resilience in mind:
- Use page objects or component wrappers to centralize selectors
- Use test data factories (create via API) to avoid brittle UI flows
- Keep tests atomic and fast — each test should verify one thing
- Retry only for known transient flakiness, not to hide issues
Sample automation in Python — Playwright + pytest
Below is a minimal example: install with pip install playwright pytest and initialize Playwright with playwright install.
# tests/test_login.py
import pytest
from playwright.sync_api import sync_playwright
def test_login_success():
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto("https://demo.saucedemo.com/")
page.fill("#user-name", "standard_user")
page.fill("#password", "secret_sauce")
page.click("#login-button")
assert page.locator(".inventory_list").is_visible()
browser.close()
Run with pytest -q. Keep this as a smoke test in CI to verify a deployment.
Sample automation in JavaScript — Playwright
Install with npm init -y then npm i -D @playwright/test and npx playwright install.
// tests/login.spec.js
const { test, expect } = require('@playwright/test');
test('login succeeds with valid credentials', async ({ page }) => {
await page.goto('https://demo.saucedemo.com/');
await page.fill('#user-name', 'standard_user');
await page.fill('#password', 'secret_sauce');
await page.click('#login-button');
await expect(page.locator('.inventory_list')).toBeVisible();
});
Run with npx playwright test. Playwright includes powerful test runner features (parallel, retries, traces).
Quick Cypress example (JavaScript)
Cypress has a different execution model (runs in browser). Install with npm i -D cypress.
// cypress/e2e/login.cy.js
describe('Login', () => {
it('logs in with valid credentials', () => {
cy.visit('https://demo.saucedemo.com/');
cy.get('#user-name').type('standard_user');
cy.get('#password').type('secret_sauce');
cy.get('#login-button').click();
cy.get('.inventory_list').should('be.visible');
});
});
Data-driven tests — a practical pattern
For flows that need multiple inputs (promo codes, user roles), parameterize tests instead of duplicating code.
// Playwright (JS) example with multiple users
const users = [
{ user: 'standard_user', pass: 'secret_sauce' },
{ user: 'problem_user', pass: 'secret_sauce' }
];
for (const u of users) {
test(`login ${u.user}`, async ({ page }) => {
await page.goto('https://demo.saucedemo.com/');
await page.fill('#user-name', u.user);
await page.fill('#password', u.pass);
await page.click('#login-button');
await expect(page.locator('.inventory_list')).toBeVisible();
});
}
Selectors — choose the right ones
Prefer stable attributes like data-test-id or semantic ids. Avoid brittle selectors like long CSS paths or text that may change.
CI Integration (GitHub Actions example)
Automate tests on each PR. A simple GitHub Actions workflow for Playwright:
name: Playwright Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: npm ci
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Run tests
run: npx playwright test --reporter=list
- name: Upload Playwright Report
if: always()
uses: actions/upload-artifact@v3
with:
name: playwright-report
path: playwright-report
Test reporting & flaky tests
Collect test reports and traces. Playwright and Cypress provide trace and video artifacts — use them. If a test is flaky, identify whether it’s the test, the app, or infra. Flaky test = technical debt; file bugs against flaky tests and prioritize fixing them.
Design patterns for maintainable automation
- Page Object Model (POM): Encapsulate page interactions.
- Fixture factories: Create test data via API to keep UI flows fast.
- Retry policies: Use judicious retries with logging, not to hide issues.
- Tagging tests: Tag slow vs fast; smoke vs regression.
Common mistakes when starting automation
- Automating unstable UIs too early
- Not investing in test data management
- Writing end-to-end suites that take hours
- Ignoring CI flakiness (tests pass locally but fail in CI)
Measuring automation success
Track these KPIs:
- Time to feedback (how long until failures are visible)
- Test pass rate in CI
- Automation coverage (regression tests automated)
- Flakiness rate (failing tests vs runs)
Sample roadmap — first 3 months
- Month 1: Automate smoke test (login → key action), integrate to CI
- Month 2: Add API contract tests and data factories
- Month 3: Build regression suite for critical flows + reporting
Hands-on mini-project (90 minutes)
Goal: Automate the login + simple verification for a demo app (e.g., saucedemo)
- Pick a stack (Python Playwright or JS Playwright/Cypress)
- Write a single test that logs in and verifies dashboard
- Run locally, then add a simple CI workflow
- Share the repo or run log with a teammate and ask for feedback
When to bring SDET or QA automation engineer on board
When automation needs deeper systems knowledge (infrastructure, mocking, performance), bring in an SDET. They help design reliable frameworks and integrate testing into the delivery pipeline.
Integrating automation into team process
Make automation a team effort: define ownership, create PR checks, and use test reports in standups. Automation should help developers move faster, not block them with false negatives.
Final tips — automation hygiene
- Review tests during code reviews
- Keep tests fast (aim under 5 minutes for smoke)
- Archive old brittle tests — not every test must live forever
- Share failures as learning moments — postmortems generate stronger tests
Closing — your automation mindset
Automation amplifies your testing power — but only when chosen and built well. Start with the smallest critical path, invest in design patterns, and measure outcomes. The goal is reliable, fast feedback that makes the whole team confident to ship.

Comments
Post a Comment