Test Automation
We catch bugs. Not your users.
We design and implement automated testing strategies from unit tests to end-to-end scenarios. Wired into CI/CD, running on every commit.
Why automate tests¶
Manual testing doesn’t scale. Every new feature expands the regression matrix. A team that tests manually either slows the release cycle or stops testing. Both cost money.
Automated tests aren’t a luxury for big companies. They’re basic software development hygiene. Every commit goes through a test suite that verifies nothing is broken in minutes. Developers get feedback immediately — not two days later from a QA team that manually clicked through twenty scenarios.
The result: Faster releases, fewer bugs in production, higher confidence in code. The team focuses on new features instead of firefighting.
The testing pyramid¶
It makes no sense to write only E2E tests. It makes no sense to write only unit tests. An effective testing strategy combines all layers — each catches a different type of bug, each has a different cost/benefit ratio.
Unit tests — the base of the pyramid¶
The fastest, cheapest, most reliable. They test isolated functions, business logic, utilities, data transformations. They run in milliseconds and you fire them hundreds of times a day without thinking.
What to test at the unit level: - Calculations, validations, conversions - Business rules and edge cases - Pure functions and utility modules - State management logic
Tools: Jest, Vitest, pytest, JUnit, XCTest — depending on the language and stack. What matters isn’t the tool but that they run automatically on every commit.
Integration tests — the middle of the pyramid¶
They verify that components work together correctly. Does the API endpoint return the right data? Does the database query work with a real schema? Does the message queue serialize and deserialize correctly?
Integration tests are slower than unit tests but catch an entire category of bugs that unit tests miss — issues at the interface between systems, configuration errors, incompatible data formats.
Typical scenarios: - API contract tests (request → response validation) - Database integrations with a test database - Communication between microservices - Third-party API mocks and stubs
E2E tests — the tip of the pyramid¶
End-to-end tests simulate a real user. They open a browser, click a button, fill out a form, verify the result. Most expensive to maintain but irreplaceable for critical user flows.
Key rule: We write E2E tests only for critical paths. Login, checkout, payment, registration — flows where a bug directly costs money. Non-critical features are tested at lower layers.
Playwright — our default for E2E¶
Playwright by Microsoft is the best tool available today for end-to-end testing of web applications. Cross-browser (Chromium, Firefox, WebKit), fast, stable, with an excellent API.
Why Playwright¶
Auto-waiting: Playwright automatically waits for elements, animations, network requests. No sleep(5000) hacks, no flaky tests from timing issues. Is the element clickable? Click. Not yet? Wait.
Tracing and debugging: Every test generates a trace — screenshot, DOM snapshot, network log, console output at each step. When a test fails in CI, you open the trace viewer and see exactly what happened. No guessing.
Parallelization: Tests run in parallel out-of-the-box. 200 E2E tests in 3 minutes instead of 45 minutes sequentially. The CI pipeline stays fast even as the test suite grows.
Codegen: Playwright can record a user journey and generate a test. Ideal for a quick start — record the flow, tweak the assertions, you have a test. Then refactor it into a robust form with the Page Object Model.
Page Object Model¶
We structure Playwright tests into Page Objects — abstractions over application pages. LoginPage.login(user, pass) instead of repeating page.fill('#email', user); page.click('#submit'). When the UI changes, you fix one Page Object, not twenty tests.
Cypress for component tests¶
Cypress has a strong position in component testing — isolated testing of React/Vue/Angular components without spinning up the whole application. Fast feedback loop, visual debugging, developer-friendly API.
For new projects we typically choose Playwright for E2E and Cypress for component tests. For existing projects with a Cypress E2E suite, we respect the existing investment and extend it.
CI/CD integration¶
Tests without CI/CD are voluntary. And voluntary tests stop running.
Pipeline design¶
Every pull request triggers a test pipeline:
- Lint + type check (30s) — syntax errors, type errors
- Unit tests (1-2 min) — business logic, utilities
- Integration tests (2-3 min) — API, database, services
- E2E tests (3-5 min) — critical user flows
- Performance check (optional) — k6 smoke test against staging
Fail fast: The pipeline stops at the first failure. A unit test fails in 30 seconds? The developer fixes it in a minute. No need to wait 10 minutes for E2E results.
Parallelization and caching¶
GitHub Actions, GitLab CI, CircleCI — all support parallel jobs. Unit tests run concurrently with linting. E2E tests shard across multiple runners. Dependency caching cuts install time from minutes to seconds.
Our benchmark: A complete test suite (500+ unit, 50+ integration, 30+ E2E) in under 10 minutes. That’s an acceptable feedback loop — the developer pushes, grabs a coffee, comes back to green checks.
k6 for performance tests in CI¶
k6 by Grafana Labs: you write in JavaScript, it runs in Go. Ideal for performance tests integrated into a CI/CD pipeline.
Smoke test in CI: Every PR triggers a quick k6 smoke test — 10 virtual users, 30 seconds. It doesn’t replace a full load test, but it catches gross performance regressions: an endpoint suddenly responding 5× slower, a memory leak in new code.
Thresholds: k6 lets you define performance budgets. Response time p95 > 500ms? The test fails, the PR won’t merge. Performance regression caught before deploy.
A testing strategy for your team¶
There is no universal testing strategy. It depends on the stack, team, release cycle and business domain. What works for a fintech with regulatory requirements is overkill for an internal admin tool.
Our approach:
- Audit — we map the current state of testing and identify the biggest risks
- Strategy — we design a tailored testing pyramid and select tools
- Quick wins — we implement the CI/CD pipeline and first tests for critical flows
- Iteration — we gradually expand coverage, train the team, and optimize the pipeline
The most important step? Start. Ten good tests in CI beats 200 tests in a document that nobody runs.
Technology stack¶
E2E: Playwright, Cypress, Selenium (legacy).
Unit/Integration: Jest, Vitest, pytest, JUnit, Go testing, XCTest.
Performance: k6, Gatling, Artillery.
CI/CD: GitHub Actions, GitLab CI, CircleCI, Jenkins, Azure DevOps.
Reporting: Allure, Playwright HTML Reporter, custom Grafana dashboards.
Časté otázky
It depends on scope. A typical setup — CI/CD pipeline, E2E framework, basic test suite — takes 2-4 weeks. ROI kicks in after the first regression bug caught in production that would otherwise cost hours of manual work and lost customers.
Playwright for E2E (cross-browser, fast, reliable), Cypress for component tests and simpler E2E, k6 for performance tests, Jest/Vitest for unit tests. The choice depends on your stack and team.
Yes. We start with characterization tests — capturing the current behavior of the system as a baseline. Then we gradually add tests around the parts that change most frequently. You don't need to test everything at once — an iterative approach works best.
You'll have your first automated tests in a CI/CD pipeline within a week. A complete testing strategy with E2E, integration and unit tests is built iteratively over 4-8 weeks. The result: tests run on every pull request and developers get feedback in minutes.
Short term, you add 10-15 minutes of setup. Medium term, you save hours of debugging. Long term, it's the best investment in velocity — developers refactor with confidence, review is faster, deploy is safe.