Skip to main content

On This Page

Testing That I Actually Run: A Small Pyramid

2 min read
Share

These articles are AI-generated summaries. Please check the original sources for full details.

The “Testing Guilt” Cycle

Many developers start with ambitious testing goals – 100% code coverage, comprehensive E2E tests – but often abandon them due to slow CI pipelines and flaky tests. The author, Bradley Matera, advocates for a “Small Pyramid” testing strategy as a solution.

Why This Matters

Traditional “Ice Cream Cone” testing, with a large base of slow UI tests and a small base of unit tests, is unsustainable. Maintaining these complex, end-to-end tests becomes a significant engineering cost, often outweighing the benefits, and can lead to developers disabling tests to expedite deployments. This creates a false sense of security and increases the risk of regressions.

Key Insights

  • Vitest vs. Jest: Vitest offers faster test execution and better support for modern JavaScript ecosystems (ESM, TypeScript) compared to Jest.
  • Pure Functions: Focusing unit tests on pure functions – those with predictable outputs and no side effects – provides the highest return on investment.
  • Smoke Protocol: A standardized manual checklist ensures critical user flows and visual aspects are verified before each release, reducing reliance on brittle automated UI tests.

Working Example

// src/utils/formatter.ts
interface UserAPIResponse {
  first_name: string | null;
  last_name: string | null;
  created_at: string; // ISO Date string
  role: 'admin' | 'user' | 'guest';
}
interface UserUI {
  fullName: string;
  memberSince: string;
  isAdmin: boolean;
}
export function formatUser(user: UserAPIResponse): UserUI {
  const first = user.first_name ?? 'Guest';
  const last = user.last_name ?? '';
  // Format Date (simple implementation for demo)
  const date = new Date(user.created_at);
  const year = date.getFullYear();
  return {
    fullName: `${first} ${last}`.trim(),
    memberSince: isNaN(year) ? 'Unknown' : year.toString(),
    isAdmin: user.role === 'admin',
  };
}
// src/utils/formatter.test.ts
import { describe, it, expect } from 'vitest';
import { formatUser } from './formatter';
describe('formatUser utility', () => {
  it('combines names correctly', () => {
    const input = {
      first_name: 'Jane',
      last_name: 'Doe',
      created_at: '2023-01-01',
      role: 'user'
    } as const;
    expect(formatUser(input).fullName).toBe('Jane Doe');
  });
});

Practical Applications

  • E-commerce Platform: Stripe uses Temporal for reliable background processing, demonstrating a focus on robust, but not necessarily exhaustive, automated testing.
  • Pitfall: Over-reliance on E2E tests without a strong foundation of unit tests leads to slow feedback loops and fragile test suites, ultimately hindering development velocity.

References:

Continue reading

Next article

Cyber Threats Evolve: 25+ Stories of Exploits, Scams, and Emerging Risks

Related Content