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.

rulesdata-fixtures.md

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

Test Fixtures

Impact: HIGH (test data reusability and consistency)

Use fixtures to manage reusable test data and complex setup scenarios. Organize fixtures by domain or entity, include expected values alongside input data, and create fixture loaders for database setup.

Incorrect

// ❌ Bad: Repeated inline data setup across tests
describe('ReportService', () => {
  test('generates sales report', async () => {
    // Setup data inline — duplicated across tests
    const salesData = [
      { date: '2024-01-01', product: 'Widget', quantity: 10, price: 29.99 },
      { date: '2024-01-01', product: 'Gadget', quantity: 5, price: 49.99 },
      { date: '2024-01-02', product: 'Widget', quantity: 15, price: 29.99 },
      { date: '2024-01-02', product: 'Gadget', quantity: 8, price: 49.99 },
      // ... 50 more lines of data
    ];

    await db.insert('sales', salesData);

    const report = await reportService.generate('sales', { month: 'january' });

    expect(report.totalRevenue).toBe(1799.55);
  });

  test('filters report by product', async () => {
    // Same data duplicated again
    const salesData = [
      { date: '2024-01-01', product: 'Widget', quantity: 10, price: 29.99 },
      // ... same 50+ lines
    ];

    await db.insert('sales', salesData);

    const report = await reportService.generate('sales', {
      month: 'january',
      product: 'Widget'
    });

    expect(report.items).toHaveLength(2);
  });
});

Problems:

  • Large blocks of inline data are duplicated across multiple tests
  • Expected values are hardcoded without connection to the fixture data
  • Database setup logic is repeated in every test
  • Changes to test data require updates in many places

Correct

// ✅ Good: Fixtures organized by domain with expected values
// fixtures/sales.fixture.ts
export const salesFixtures = {
  january2024: [
    { date: '2024-01-01', product: 'Widget', quantity: 10, price: 29.99 },
    { date: '2024-01-01', product: 'Gadget', quantity: 5, price: 49.99 },
    { date: '2024-01-02', product: 'Widget', quantity: 15, price: 29.99 },
    { date: '2024-01-02', product: 'Gadget', quantity: 8, price: 49.99 }
  ],

  january2024Expected: {
    totalRevenue: 1099.55,
    widgetRevenue: 749.75,
    gadgetRevenue: 349.80,
    widgetCount: 25,
    gadgetCount: 13
  }
};

// fixtures/users.fixture.ts
export const userFixtures = {
  admin: {
    id: 'user-admin',
    email: 'admin@example.com',
    role: 'admin',
    permissions: ['read', 'write', 'delete', 'admin']
  },

  regularUser: {
    id: 'user-regular',
    email: 'user@example.com',
    role: 'user',
    permissions: ['read']
  },

  premiumUser: {
    id: 'user-premium',
    email: 'premium@example.com',
    role: 'user',
    subscription: 'premium',
    permissions: ['read', 'write', 'export']
  }
};

// helpers/fixture-loader.ts
export class FixtureLoader {
  constructor(private db: Database) {}

  async loadSales(fixture: typeof salesFixtures.january2024): Promise<void> {
    await this.db.insert('sales', fixture);
  }

  async loadUsers(...users: Array<typeof userFixtures.admin>): Promise<void> {
    await this.db.insert('users', users);
  }

  async clearAll(): Promise<void> {
    await this.db.truncate(['sales', 'users', 'products']);
  }
}

// Clean tests using fixtures
describe('ReportService', () => {
  let fixtureLoader: FixtureLoader;

  beforeAll(() => {
    fixtureLoader = new FixtureLoader(db);
  });

  beforeEach(async () => {
    await fixtureLoader.clearAll();
  });

  describe('sales reports', () => {
    beforeEach(async () => {
      await fixtureLoader.loadSales(salesFixtures.january2024);
    });

    test('calculates total revenue for month', async () => {
      const report = await reportService.generate('sales', { month: 'january' });

      expect(report.totalRevenue).toBe(
        salesFixtures.january2024Expected.totalRevenue
      );
    });

    test('filters by product', async () => {
      const report = await reportService.generate('sales', {
        month: 'january',
        product: 'Widget'
      });

      expect(report.totalRevenue).toBe(
        salesFixtures.january2024Expected.widgetRevenue
      );
    });
  });
});

describe('AuthorizationService', () => {
  beforeEach(async () => {
    await fixtureLoader.clearAll();
  });

  test('admin can delete resources', async () => {
    await fixtureLoader.loadUsers(userFixtures.admin);

    const canDelete = await authService.checkPermission(
      userFixtures.admin.id,
      'delete'
    );

    expect(canDelete).toBe(true);
  });

  test('regular user cannot delete resources', async () => {
    await fixtureLoader.loadUsers(userFixtures.regularUser);

    const canDelete = await authService.checkPermission(
      userFixtures.regularUser.id,
      'delete'
    );

    expect(canDelete).toBe(false);
  });
});

Benefits:

  • Same data is reused across multiple tests without duplication
  • All tests use identical baseline data for consistency
  • Test data is updated in one place when requirements change
  • Fixtures describe test scenarios and serve as documentation
  • Pre-calculated expected values stored alongside input data prevent drift
  • Test logic is cleanly separated from test data

Reference: Django Docs — Fixtures

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