All skills
asyrafhussin avatar

/testing-best-practices

@575c801

Unit testing, integration testing, and test-driven development principles. Use when writing tests, reviewing test code, improving test coverage, or setting up testing strategy. Triggers on "write tests", "review tests", "testing best practices", or "TDD".

Use this Skill: https://skilld.dev/gh/asyrafhussin/agent-skills/testing-best-practices

This session only. Nothing lands on disk.

rulescov-edge-cases.md

≈1.1k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Cover Edge Cases

Impact: MEDIUM (catches 35% of production bugs caused by unexpected input values)

Test boundary values, empty inputs, null/undefined, and special characters. Most production bugs live at the edges, not in the happy path.

Incorrect

// ❌ Bad: only testing the happy path
describe('StringUtils', () => {
  test('truncates a long string', () => {
    expect(truncate('Hello World', 5)).toBe('He...');
  });
});

describe('ArrayUtils', () => {
  test('finds the maximum value', () => {
    expect(findMax([3, 1, 4, 1, 5])).toBe(5);
  });
});

describe('UserValidator', () => {
  test('validates a correct email', () => {
    expect(validateUser({ name: 'Alice', email: 'alice@example.com', age: 25 })).toBe(true);
  });
});

Problems:

  • What happens when truncate receives an empty string? A string shorter than the limit?
  • What does findMax return for an empty array? An array with one element? Negative numbers?
  • What if age is 0, -1, or Number.MAX_SAFE_INTEGER?
  • Production crashes from unhandled edge cases that happy-path tests never exercise

Correct

// ✅ Good: systematically test edge cases and boundary values
describe('StringUtils - truncate', () => {
  test('truncates string longer than limit', () => {
    expect(truncate('Hello World', 5)).toBe('He...');
  });

  test('returns original string when shorter than limit', () => {
    expect(truncate('Hi', 10)).toBe('Hi');
  });

  test('returns original string when exactly at limit', () => {
    expect(truncate('Hello', 5)).toBe('Hello');
  });

  test('handles empty string', () => {
    expect(truncate('', 5)).toBe('');
  });

  test('handles limit of zero', () => {
    expect(truncate('Hello', 0)).toBe('...');
  });

  test('handles special characters and unicode', () => {
    expect(truncate('Hello! @#$%', 7)).toBe('Hell...');
  });

  test('handles null input gracefully', () => {
    expect(truncate(null as unknown as string, 5)).toBe('');
  });
});

describe('ArrayUtils - findMax', () => {
  test('finds max in a normal array', () => {
    expect(findMax([3, 1, 4, 1, 5])).toBe(5);
  });

  test('handles single-element array', () => {
    expect(findMax([42])).toBe(42);
  });

  test('throws for empty array', () => {
    expect(() => findMax([])).toThrow('Array must not be empty');
  });

  test('handles negative numbers', () => {
    expect(findMax([-5, -1, -3])).toBe(-1);
  });

  test('handles zero', () => {
    expect(findMax([0, -1, -2])).toBe(0);
  });

  test('handles duplicate max values', () => {
    expect(findMax([5, 5, 3, 5])).toBe(5);
  });

  test('handles Number.MAX_SAFE_INTEGER', () => {
    expect(findMax([1, Number.MAX_SAFE_INTEGER, 3])).toBe(Number.MAX_SAFE_INTEGER);
  });
});

describe('UserValidator - edge cases', () => {
  test('rejects empty name', () => {
    expect(validateUser({ name: '', email: 'a@b.com', age: 25 })).toBe(false);
  });

  test('rejects undefined email', () => {
    expect(validateUser({ name: 'Alice', email: undefined as unknown as string, age: 25 })).toBe(false);
  });

  test('rejects age of zero', () => {
    expect(validateUser({ name: 'Alice', email: 'a@b.com', age: 0 })).toBe(false);
  });

  test('rejects negative age', () => {
    expect(validateUser({ name: 'Alice', email: 'a@b.com', age: -1 })).toBe(false);
  });

  test('handles name with special characters', () => {
    expect(validateUser({ name: "O'Brien-Smith", email: 'a@b.com', age: 30 })).toBe(true);
  });

  test('rejects age exceeding reasonable maximum', () => {
    expect(validateUser({ name: 'Alice', email: 'a@b.com', age: 200 })).toBe(false);
  });
});

Benefits:

  • Boundary values (0, -1, empty, max) catch off-by-one errors and unguarded code paths
  • Null/undefined tests verify defensive coding works in practice
  • Special character tests prevent encoding and parsing bugs
  • Each edge case documents an assumption the code makes about its inputs

Reference: Boundary Value Analysis

Source: SKILL.md on GitHub

No alerts16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill provides comprehensive guidelines and best practices for unit testing, integration testing, and Test-Driven Development (TDD). It consists entirely of documentation and illustrative code examples using industry-standard tools like Jest and Vitest. No security risks or malicious patterns were detected.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    29 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 575c801. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Steadyupdated 7 months ago
metadata
{
  "author": "agent-skills",
  "version": "2.0.0"
}

README badge

README badge for asyrafhussin/agent-skills/testing-best-practices