f in x
Software Testing — Pyramid, Automation and Strategies for Code That Won't Keep You Up at Night
> cd .. / HUB_EDITORIALE
Sviluppo di siti web

Software Testing — Pyramid, Automation and Strategies for Code That Won't Keep You Up at Night

[2026-06-24] Author: Ing. Calogero Bono

Have you ever pushed a change to production only to discover hours later that a trivial detail broke everything? We have. And every time we ask ourselves: why didn't we write a test first?

Software testing is not a waste of time. It's the way a project stops being fragile and becomes reliable. We at Meteora Web have worked for years on heterogeneous stacks – WordPress, Laravel, React – and have seen projects die from a lack of tests. Others grew because testing was part of the code's DNA.

This pillar page covers everything you need to set up a solid software testing strategy, from individual developer to CI/CD pipeline. No abstract theory: only what really works.

Why is software testing the best investment for a project?

We often hear: “The client doesn't pay for tests, they pay for features.” That's only superficially true. A bug in production costs far more than the time spent preventing it. Software testing is a form of insurance. You pay a premium today to avoid a disaster tomorrow.

We learned this the hard way: an e-commerce client had a checkout form that, under certain conditions, threw a 500 error. It surfaced in production, with lost orders and support tickets. An integration test would have caught it in 5 minutes.

What good testing delivers

  • Fewer production bugs – fewer incidents, fewer late-night calls.
  • Safe refactoring – you can change the code knowing tests protect it.
  • Living documentation – tests explain what the system should do.
  • Less anxiety during deployments – the pipeline tells you everything is fine.

If you haven't started yet, the best time is now. The second best time is after reading this guide.

Sponsored Protocol

How to balance unit, integration and E2E in software testing?

The testing pyramid is the most famous model: many unit tests at the base, fewer integration tests, even fewer end-to-end tests. Ideal proportion? Around 70% unit, 20% integration, 10% E2E. But it's not carved in stone – it depends on context.

Unit tests – the solid foundation

They test a single function or method, isolated from everything else. Fast, easy to write, immediate feedback. With Jest or PHPUnit you write them in seconds. Example:

function sum(a, b) {
  return a + b;
}

test('adds two positive numbers', () => {
  expect(sum(2, 3)).toBe(5);
});

Integration tests – the glue

They verify that multiple components work together: database, APIs, external services. Slower than unit tests, but they catch real problems. We use them a lot on Laravel with PHPUnit and a test database.

E2E tests – the user simulation

They test the entire flow as a user would. Tools like Playwright or Cypress launch a browser and interact with the app. Slowest and most fragile, but irreplaceable to verify the system really works.

A common mistake is focusing only on E2E. We see companies spend huge budgets on end-to-end tests while neglecting unit tests. Result: slow suite, tests breaking for any CSS selector typo. Respect the pyramid: more unit, less E2E.

Which tools to choose for software testing in JavaScript and PHP?

Each ecosystem has its champions. Here are the ones we use daily in production.

JavaScript / TypeScript

  • Jest – the most widespread for React, Node.js, Vue. Snapshots, built-in mocking, coverage. Our pick for Laravel + Vue projects.
  • Vitest – faster than Jest, native to Vite. We prefer it in new projects.
  • Playwright – cross-browser E2E. Supports Chromium, Firefox, WebKit. Parallel execution, auto-retry, trace viewer debugging.

PHP

  • PHPUnit – the de facto standard. Used by Laravel, Symfony, Magento. Reliable, mature, with data providers and mocking.
  • Pest – elegant alternative to PHPUnit, cleaner syntax. We use it in new Laravel projects because it reduces boilerplate.
  • Laravel Dusk – E2E for Laravel, but less performant than Playwright. We prefer Playwright even for Laravel apps.

The right choice

No perfect tool. We recommend: Jest (or Vitest) for frontend unit/integration, PHPUnit (or Pest) for PHP backend, Playwright for E2E. Then evaluate mutation testing with Stryker to see if your tests are robust.

Sponsored Protocol

TDD: Red, Green, Refactor – a mantra that works

Test-Driven Development is simple: first write a test that fails (Red), then write the minimal code to make it pass (Green), finally improve the code (Refactor). Seems slow? At first yes, then it becomes faster than coding without tests.

We use TDD when logic is complex or when refactoring will be frequent. For example, on a price calculation module with discounts and taxes: we write edge cases first, then implement. The test becomes the spec.

Practical example in JavaScript

// Red: write a failing test
test('calculates 10% discount', () => {
  expect(calculateDiscount(100)).toBe(90);
});

// Green: minimal implementation
function calculateDiscount(price) {
  return price * 0.9;
}

// Refactor: extract constant
const DISCOUNT = 0.1;
function calculateDiscount(price) {
  return price * (1 - DISCOUNT);
}

When to use it

TDD isn't useful for everything. For UI or external service integrations, it's often better to write the code first and then tests. But for domain logic, algorithms, business rules, TDD is a guarantee.

Sponsored Protocol

Mock, stub and spy: isolate code without pain

When doing unit tests, you don't want to depend on databases, external APIs or file systems. Enter test doubles.

  • Stub – provide predefined responses. “When you call this method, always return 42”.
  • Mock – verify a method was called with certain arguments. “Check that the email service was invoked with the right address”.
  • Spy – record calls for later inspection. Similar to mocks but less intrusive.

We use the built-in mocking of Jest and PHPUnit. Beware: over-mocking makes tests false. If you have to mock half the system, maybe the test is too low-level or the design is too coupled.

Performance testing: k6 and Artillery to avoid crashes

A site may work fine with one user, and collapse under a thousand. Load tests simulate real traffic to find bottlenecks.

  • k6 – modern, scriptable in JavaScript, produces detailed reports. We integrate it in CI to verify that a new feature doesn't degrade performance.
  • Artillery – YAML/JS, easy to configure, good for stress testing APIs or WebSockets.

Example k6 script:

import http from 'k6/http';
import { sleep } from 'k6';

export default function () {
  http.get('https://your-site.com/api/products');
  sleep(1);
}

export const options = {
  vus: 10,
  duration: '30s',
};

Run with k6 run script.js. Check latency percentiles, errors, throughput. If P95 exceeds 2 seconds, you have a problem.

Sponsored Protocol

Mutation testing: Stryker for tests that truly matter

Code coverage is a partial indicator. A test can cover 100% of lines but test nothing meaningful. Mutation testing modifies the code (injects bugs) and sees if tests catch them. If not, the test is weak.

Stryker is the main tool for JavaScript and TypeScript. There is also for PHP (Infection). We run it periodically on critical projects. Example command:

npx stryker run

Stryker produces a report with the percentage of “mutants killed”. Target: > 90% killed. If low, your tests aren't protecting the code as they should.

BDD with Cucumber: when behavior matters more than code

Behavior-Driven Development aligns developers, testers and stakeholders. Scenarios are written in Gherkin language: Given, When, Then. Steps are implemented with code.

Feature: Login
  Scenario: Successful login
    Given a registered user with email "mario@example.com"
    When they log in with correct password
    Then they are redirected to the dashboard

Tests become readable by anyone. We use Cucumber with Playwright for E2E: Gherkin scenarios that execute browser actions. Not suitable for unit tests, but powerful for business flows.

How to integrate software testing in a CI/CD pipeline?

A test executed manually is worth little. It must be automatic, run on every push. GitHub Actions is our choice for PHP, Node.js or mixed projects.

Example workflow for Laravel

name: Test
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
          extensions: mbstring, pdo_mysql
      - run: composer install
      - run: cp .env.example .env
      - run: php artisan key:generate
      - run: php artisan migrate --env=testing
      - run: php vendor/bin/phpunit

For frontend projects: npm test then npx playwright test. We use parallel jobs for unit, integration and E2E. E2E tests can be run only on protected branches to save resources.

Sponsored Protocol

What to do now

You don't have to implement everything in one day. Here's a practical sequence:

  1. Start with a test for the next feature – pick a critical module and write a unit test. If you've never tested, start with a simple test.
  2. Measure coverage – install Jest or PHPUnit with coverage. Look at uncovered areas. Don't chase 100%, but cover the most critical functions.
  3. Add an integration test – verify that an API route works with a real (in-memory) database.
  4. Set up CI – configure GitHub Actions to run tests on every push. Don't accept PRs with failing tests.
  5. After a month, add mutation testing – Stryker or Infection will tell you if your tests are solid.
  6. Plan an E2E test for the main flow – with Playwright, simulate the most used user path.

Software testing is not a cost: it's the investment that turns code from a fragile box into a reliable engine. We at Meteora Web do this every day. If you need a consultation to set up your testing strategy, contact us.

Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Ingegnere Informatico, co-fondatore di Meteora Web. Esperto in architetture software, sicurezza informatica e sviluppo sistemi scalabili.
[ Read Full Dossier ]

> METEORA_WEB // DIGITAL AGENCY

We build the digital presence your business deserves.

Websites, social media, online advertising, e-commerce and high-performance hosting, engineered with method by computer engineers in Sciacca, for all of Italy.

> MW_JOURNAL

> READ_ALL()