Test Runner

Write, run, and manage unit, integration, and E2E tests across TypeScript, Python, and Swift using recommended frameworks.

cmanfre7

@cmanfre7

What This Skill Does

Unified CLI for writing and running unit, integration, and E2E tests across TypeScript, Python, and Swift using recommended frameworks like Vitest, pytest, XCTest, and Playwright. Provides quick-start commands, TDD workflow guidance, and common test patterns.

Replaces manually setting up and remembering commands for multiple testing frameworks by providing a single reference with language-specific commands and patterns.

When to Use It

  • Run all unit tests in a TypeScript project with Vitest
  • Execute a specific pytest test by name in a Python project
  • Run Playwright E2E tests in headed mode to debug browser interactions
  • Run Swift tests in parallel to speed up CI pipelines
  • Generate test coverage reports for a Python project with pytest-cov
  • Set up a new test file using the Arrange-Act-Assert pattern

Install

$ openclaw skills install @cmanfre7/test-runner

test-runner

Write and run tests across languages and frameworks.

Framework Selection

LanguageUnit TestsIntegrationE2E
TypeScript/JSVitest (preferred), JestSupertestPlaywright
Pythonpytestpytest + httpxPlaywright
SwiftXCTestXCTestXCUITest

Quick Start by Framework

Vitest (TypeScript / JavaScript)

npm install -D vitest @testing-library/react @testing-library/jest-dom
// vitest.config.ts
import { defineConfig } from 'vitest/config'
export default defineConfig({
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: './tests/setup.ts',
  },
})
npx vitest              # Watch mode
npx vitest run          # Single run
npx vitest --coverage   # With coverage

Jest

npm install -D jest @types/jest ts-jest
npx jest                # Run all
npx jest --watch        # Watch mode
npx jest --coverage     # With coverage
npx jest path/to/test   # Single file

pytest (Python)

uv pip install pytest pytest-cov pytest-asyncio httpx
pytest                          # Run all
pytest -v                       # Verbose
pytest -x                       # Stop on first failure
pytest --cov=app                # With coverage
pytest tests/test_api.py -k "test_login"  # Specific test
pytest --tb=short               # Short tracebacks

XCTest (Swift)

swift test                      # Run all tests
swift test --filter MyTests     # Specific test suite
swift test --parallel           # Parallel execution

Playwright (E2E)

npm install -D @playwright/test
npx playwright install
npx playwright test                    # Run all
npx playwright test --headed           # With browser visible
npx playwright test --debug            # Debug mode
npx playwright test --project=chromium # Specific browser
npx playwright show-report             # View HTML report

TDD Workflow

  1. Red — Write a failing test that describes the desired behavior.
  2. Green — Write the minimum code to make the test pass.
  3. Refactor — Clean up the code while keeping tests green.
┌─────────┐     ┌─────────┐     ┌──────────┐
│  Write   │────▶│  Write  │────▶│ Refactor │──┐
│  Test    │     │  Code   │     │  Code    │  │
│  (Red)   │     │ (Green) │     │          │  │
└─────────┘     └─────────┘     └──────────┘  │
     ▲                                          │
     └──────────────────────────────────────────┘

Test Patterns

Arrange-Act-Assert

test('calculates total with tax', () => {
  // Arrange
  const cart = new Cart([{ price: 100, qty: 2 }]);

  // Act
  const total = cart.totalWithTax(0.08);

  // Assert
  expect(total).toBe(216);
});

Testing Async Code

test('fetches user data', async () => {
  const user = await getUser('123');
  expect(user.name).toBe('Colt');
});

Mocking

import { vi } from 'vitest';

const mockFetch = vi.fn().mockResolvedValue({
  json: () => Promise.resolve({ id: 1, name: 'Test' }),
});
vi.stubGlobal('fetch', mockFetch);

Testing API Endpoints (Python)

import pytest
from httpx import AsyncClient
from app.main import app

@pytest.mark.asyncio
async def test_get_users():
    async with AsyncClient(app=app, base_url="http://test") as client:
        response = await client.get("/users")
    assert response.status_code == 200
    assert isinstance(response.json(), list)

Testing React Components

import { render, screen, fireEvent } from '@testing-library/react';
import { Button } from './Button';

test('calls onClick when clicked', () => {
  const handleClick = vi.fn();
  render(<Button onClick={handleClick}>Click me</Button>);
  fireEvent.click(screen.getByText('Click me'));
  expect(handleClick).toHaveBeenCalledOnce();
});

Coverage Commands

# JavaScript/TypeScript
npx vitest --coverage          # Vitest (uses v8 or istanbul)
npx jest --coverage            # Jest

# Python
pytest --cov=app --cov-report=html    # HTML report
pytest --cov=app --cov-report=term    # Terminal output
pytest --cov=app --cov-fail-under=80  # Fail if < 80%

# View HTML coverage report
open coverage/index.html       # macOS
open htmlcov/index.html        # Python

What to Test

Always test:

  • Public API / exported functions
  • Edge cases: empty input, null, boundary values
  • Error handling: invalid input, network failures
  • Business logic: calculations, state transitions

Don't bother testing:

  • Private implementation details
  • Framework internals (React rendering, Express routing)
  • Trivial getters/setters
  • Third-party library behavior

Top skills in this category