Skip to content

Latest commit

 

History

History
98 lines (74 loc) · 1.73 KB

File metadata and controls

98 lines (74 loc) · 1.73 KB

Testing Guide for Coding Agents

npm test                  # Run tests
npm run test:watch        # Watch mode
npm run test:coverage     # Coverage

Basic Pattern

import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

describe("MyComponent", () => {
  test("does something", async () => {
    const user = userEvent.setup();
    render(<MyComponent />);

    await user.click(screen.getByRole("button"));

    expect(screen.getByText("Result")).toBeInTheDocument();
  });
});

ZMK Mocking

import { setupZMKMocks } from "@cormoran/zmk-studio-react-hook/testing";

let mocks: ReturnType<typeof setupZMKMocks>;
beforeEach(() => {
  mocks = setupZMKMocks();
});

// Success
mocks.mockSuccessfulConnection({ deviceName: "Test" });

// Error
mocks.mockFailedConnection("Error message");

Rules

  • Use semantic queries: getByRole, getByLabelText, getByText
  • Use userEvent, not fireEvent
  • Wait with waitFor() or findBy*
  • Reset mocks in beforeEach()
  • Test behavior, not implementation

Patterns

Context:

const mock = { isConnected: true };
render(
  <Ctx.Provider value={mock}>
    <Component />
  </Ctx.Provider>,
);

Hooks:

const { result } = renderHook(() => useHook());
await act(async () => {
  await result.current.fn();
});

Mock Components:

jest.mock("../../hooks/useHook");
const mockHook = useHook as jest.MockedFunction<typeof useHook>;
mockHook.mockReturnValue({ data: [] });

ZMK Helpers

import {
  setupZMKMocks,
  createMockZMKApp,
  ZMKAppProvider,
} from "@cormoran/zmk-studio-react-hook/testing";

Files

components/
  Component.tsx
  __tests__/Component.test.tsx