Advanced (अपडेट: 2/6/2026)

Claude Code टेस्ट रणनीति: Vitest, Testing Library, Playwright और CI

Claude Code से unit, integration, E2E और CI टेस्ट की व्यावहारिक रणनीति बनाएं।

Claude Code टेस्ट रणनीति: Vitest, Testing Library, Playwright और CI

टेस्ट रणनीति का मतलब सिर्फ ज्यादा टेस्ट लिखना नहीं है। इसका मतलब है यह तय करना कि कौन सा व्यवहार तेज unit test से सुरक्षित होगा, किस सीमा को integration test चाहिए, और कौन से कारोबारी flow को E2E test में रखना चाहिए।

अगर आप Claude Code से केवल “tests जोड़ दो” कहते हैं, तो वह surface-level assertions, कमजोर CSS selectors या ऐसी tests बना सकता है जो सिर्फ मौजूदा implementation को दोहराती हैं। बेहतर prompt में test layer, expected behavior, चलाने वाला command और edit की सीमा साफ लिखी जाती है।

यह लेख आधिकारिक Claude Code common workflows, Vitest coverage, Testing Library queries, और Playwright के locators, assertions, CI से मिलाकर अपडेट किया गया है।

पहले test pyramid तय करें

flowchart TB
  E2E["E2E: signup, checkout, revenue CTA"]
  INT["Integration: API, DB, forms, components"]
  UNIT["Unit: calculation, validation, permissions"]
  E2E --> INT --> UNIT
Layerअनुमानक्या बचाता हैTools
Unit60-70%pure logic, validation, permissionsVitest
Integration20-30%components, API, DB boundariesVitest + Testing Library
E2E5-10%signup, purchase, revenue pathsPlaywright
CI gateहर PRlint, types, tests, reportsGitHub Actions

Price calculation को unit test चाहिए। Checkout button को integration test चाहिए। Article CTA से products page तक जाने वाला flow E2E के लिए सही है।

न्यूनतम setup

npm i -D vitest @vitest/coverage-v8 jsdom \
  @testing-library/react @testing-library/jest-dom @testing-library/user-event \
  @playwright/test
npx playwright install --with-deps
{
  "scripts": {
    "test": "vitest --run",
    "test:watch": "vitest",
    "test:coverage": "vitest --run --coverage",
    "test:e2e": "playwright test"
  }
}
// vitest.config.ts
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    environment: "jsdom",
    setupFiles: ["./test/setup.ts"],
    coverage: {
      provider: "v8",
      reporter: ["text", "html"],
      thresholds: {
        lines: 80,
        functions: 80,
        branches: 75,
        statements: 80,
      },
    },
  },
});
// test/setup.ts
import "@testing-library/jest-dom/vitest";

Vitest documentation में v8 और istanbul दोनों coverage providers बताए गए हैं। Node और Chromium वाले projects में v8 अक्सर सबसे सीधा विकल्प है।

उदाहरण 1: price logic का unit test

// src/lib/pricing.ts
export type PriceInput = {
  unitPrice: number;
  quantity: number;
  discountRate?: number;
  taxRate?: number;
};

export function calculateTotal({
  unitPrice,
  quantity,
  discountRate = 0,
  taxRate = 0.1,
}: PriceInput): number {
  if (!Number.isInteger(quantity) || quantity < 0) {
    throw new Error("quantity must be a non-negative integer");
  }
  if (unitPrice < 0) throw new Error("unitPrice must be non-negative");
  if (discountRate < 0 || discountRate > 1) {
    throw new Error("discountRate must be between 0 and 1");
  }
  const discounted = unitPrice * quantity * (1 - discountRate);
  return Math.round(discounted * (1 + taxRate));
}
// src/lib/pricing.test.ts
import { describe, expect, it } from "vitest";
import { calculateTotal } from "./pricing";

describe("calculateTotal", () => {
  it("calculates a tax-included total", () => {
    expect(calculateTotal({ unitPrice: 1000, quantity: 2 })).toBe(2200);
  });

  it("applies discount before tax", () => {
    expect(
      calculateTotal({ unitPrice: 1000, quantity: 2, discountRate: 0.2 })
    ).toBe(1760);
  });

  it("allows zero quantity", () => {
    expect(calculateTotal({ unitPrice: 1000, quantity: 0 })).toBe(0);
  });

  it("rejects invalid inputs", () => {
    expect(() => calculateTotal({ unitPrice: 1000, quantity: -1 })).toThrow(
      "quantity must be a non-negative integer"
    );
  });
});

Common pitfall है coverage 80% करने के लिए केवल happy paths जोड़ना। Pricing में quantity zero, full discount, invalid rate और rounding ज्यादा जरूरी हैं।

उदाहरण 2: Testing Library से CTA component test

Testing Library ऐसे queries को प्राथमिकता देता है जो user experience के करीब हों। इसलिए getByRole और getByLabelText CSS class से बेहतर हैं।

// src/components/CheckoutButton.tsx
import { useState } from "react";

type Props = {
  stock: number;
  onCheckout: () => Promise<void>;
};

export function CheckoutButton({ stock, onCheckout }: Props) {
  const [submitting, setSubmitting] = useState(false);
  const soldOut = stock <= 0;

  async function handleClick() {
    setSubmitting(true);
    try {
      await onCheckout();
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <button
      type="button"
      disabled={soldOut || submitting}
      aria-busy={submitting}
      onClick={handleClick}
    >
      {soldOut ? "Sold out" : submitting ? "Processing..." : "Buy now"}
    </button>
  );
}
// src/components/CheckoutButton.test.tsx
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { describe, expect, it, vi } from "vitest";
import { CheckoutButton } from "./CheckoutButton";

describe("CheckoutButton", () => {
  it("calls checkout when in stock", async () => {
    const user = userEvent.setup();
    const onCheckout = vi.fn().mockResolvedValue(undefined);

    render(<CheckoutButton stock={3} onCheckout={onCheckout} />);
    await user.click(screen.getByRole("button", { name: "Buy now" }));

    expect(onCheckout).toHaveBeenCalledTimes(1);
  });

  it("prevents checkout when sold out", async () => {
    const user = userEvent.setup();
    const onCheckout = vi.fn().mockResolvedValue(undefined);

    render(<CheckoutButton stock={0} onCheckout={onCheckout} />);
    const button = screen.getByRole("button", { name: "Sold out" });

    expect(button).toBeDisabled();
    await user.click(button);
    expect(onCheckout).not.toHaveBeenCalled();
  });
});

Revenue CTA को .primary-button या सिर्फ snapshot से test करना कमजोर है। Test को role, visible text और click behavior देखना चाहिए।

उदाहरण 3: Playwright E2E छोटा रखें

// playwright.config.ts
import { defineConfig, devices } from "@playwright/test";

const baseURL =
  process.env.PLAYWRIGHT_TEST_BASE_URL ?? "http://127.0.0.1:5173";

export default defineConfig({
  testDir: "./e2e",
  retries: process.env.CI ? 2 : 0,
  use: { baseURL, trace: "on-first-retry" },
  projects: [{ name: "chromium", use: { ...devices["Desktop Chrome"] } }],
  webServer: process.env.PLAYWRIGHT_TEST_BASE_URL
    ? undefined
    : {
        command: "npm run dev -- --host 127.0.0.1",
        url: baseURL,
        reuseExistingServer: !process.env.CI,
      },
});
// e2e/article-cta.spec.ts
import { expect, test } from "@playwright/test";

test("reader can move from article CTA to products", async ({ page }) => {
  await page.goto("/hi/blog/claude-code-testing-strategies");

  await page.getByRole("link", { name: /products|templates/i }).click();

  await expect(page).toHaveURL(/\/products\/?$/);
  await expect(page.getByRole("heading", { name: /products/i })).toBeVisible();
});

Playwright की web-first assertions auto retry करती हैं। Fixed waitForTimeout के बजाय user-visible state का इंतजार करें। Role, label और stable test id का उपयोग करें; deep CSS path और nth() से बचें।

उदाहरण 4: CI gate जोड़ें

# .github/workflows/test.yml
name: Test

on:
  pull_request:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v6
        with:
          node-version: 22
          cache: npm
      - run: npm ci
      - run: npm run test:coverage
      - run: npx playwright install --with-deps
      - run: npm run test:e2e
        env:
          CI: "true"
      - uses: actions/upload-artifact@v5
        if: ${{ !cancelled() }}
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 30

Claude Code GitHub Actions के लिए official docs में GA action anthropics/claude-code-action@v1 दिखाया गया है। पुराने @beta examples को बिना जांचे copy न करें।

Claude Code prompt templates

src/lib/pricing.ts के लिए Vitest unit tests जोड़ें।
Success cases, boundary values और invalid inputs cover करें।
Implementation न बदलें; अगर bug दिखे तो पहले उसे list करें।
npm run test -- pricing चलाकर result summarize करें।
src/components/CheckoutButton.tsx के लिए Testing Library tests जोड़ें।
getByRole और userEvent.setup() इस्तेमाल करें।
CSS selectors, snapshot-only assertions और implementation details से बचें।
In-stock, sold-out और submitting states cover करें।
Article से products page तक CTA flow के लिए केवल एक Playwright E2E test जोड़ें।
waitForTimeout, deep CSS selectors और nth() से बचें।
Web-first assertions इस्तेमाल करें और revenue path पर focus रखें।
Latest CI failure logs पढ़ें।
Failure को lint, typecheck, unit, e2e या environment में classify करें।
Smallest diff से root cause fix करें।
Tests skip न करें और केवल timeout न बढ़ाएं।

आम गलतियां

सब कुछ mock न करें। Payment provider और email delivery mock हो सकते हैं, लेकिन price, permission और persistence को सही layer पर test करना चाहिए।

E2E से हर visual detail lock न करें। E2E को signup, purchase, contact और product clicks जैसे user actions बचाने चाहिए।

Coverage को quality proof न मानें। 80% coverage के बाद भी वही branch छूट सकती है जो charge, delete या publish करती है।

Claude Code को सिर्फ happy path न दें। साथ में लिखें: fragile selectors नहीं, skip नहीं, snapshot-only नहीं, implementation details से coupling नहीं।

CTA

Testing strategy code quality के साथ revenue paths भी बचाती है। पहले free Claude Code cheatsheet से basic commands तय करें, repeated review rules को products and templates में बदलें, और team setup के लिए Claude Code training देखें। आगे पढ़ने के लिए TDD with Claude Code, CI/CD setup, और debugging techniques उपयोगी हैं।

असल में आजमाने का परिणाम

Masa ने यह pattern ClaudeCodeLab के article CTAs और product page flows पर आजमाया। सबसे ज्यादा फायदा बहुत सारे E2E जोड़ने से नहीं, बल्कि pricing logic को unit tests में रखने, CTA behavior को Testing Library से जांचने और article-to-products path के लिए एक Playwright test रखने से हुआ। Claude Code से पहले failure modes list करवाने पर skipped tests और brittle CSS selectors कम हुए। बाकी risk external payment और ad scripts में है, जिन्हें CI evidence और छोटी manual release check के साथ देखना पड़ता है।

#Claude Code #testing #test strategy #Vitest #Playwright
मुफ़्त

मुफ़्त PDF: Claude Code cheatsheet

Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.

हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.

Masa

लेखक के बारे में

Masa

Claude Code workflow और team adoption पर काम करने वाला engineer.