Quick Vite Test working example I can refer to later.
> npm init vite vite-test
Need to install the following packages:
create-vite@3.1.0
Ok to proceed? (y)
✔ Select a framework: › React
✔ Select a variant: › TypeScript
> cd vite-test
> npm install
> npm run dev
> open http://localhost:5173/
npm install -D vitest react-test-renderer jsdom @testing-library/react @testing-library/user-event @testing-library/jest-dom @vitest/ui @vitest/coverage-c8
// vite.config.ts
/// <reference types="vitest" />
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: "jsdom",
setupFiles: "./src/test/setup.ts",
// you might want to disable it, if you don't have tests that rely on CSS
// since parsing CSS is slow
css: true,
},
});
Add scripts to package.json
"scripts": {
...
"test": "vitest",
"coverage": "vitest run --coverage",
"test:ui": "vitest --ui"
},
// src/components/Input.tsx
type InputProps = {
label: string;
name: string;
error?: string | undefined;
} & React.DetailedHTMLProps<
React.InputHTMLAttributes<HTMLInputElement>,
HTMLInputElement
>;
export const Input = ({ label, name, error, ...props }: InputProps) => {
return (
<>
<label htmlFor={name}>{label}</label>
<input name={name} id={name} {...props} />
{error ? <span role="alert">{error}</span> : null}
</>
);
};
// src/components/input.test.tsx
import "@testing-library/jest-dom";
import { render, screen, userEvent } from "../utils/test-utils";
import { Input } from "./Input";
describe("Input", async () => {
it("should render the input", () => {
render(
<Input
name="email"
type="email"
error={undefined}
placeholder="Email"
label="Email Address"
aria-label="Email Address"
/>
);
expect(screen.getByText("Email Address")).toBeInTheDocument();
expect(
screen.getByRole("textbox", {
name: /email address/i,
})
).toBeInTheDocument();
});
it("should change input value", async () => {
render(
<Input
name="email"
type="email"
error={undefined}
placeholder="Email"
label="Email Address"
aria-label="Email Address"
/>
);
screen.logTestingPlaygroundURL();
const input = screen.getByRole("textbox", {
name: /email address/i,
});
expect(input).toBeInTheDocument();
await userEvent.type(input, "1337");
expect(input).toHaveValue("1337");
});
it("should render the input with error", () => {
render(
<Input
name="email"
type="email"
placeholder="Email"
label="Email Address"
aria-label="Email Address"
error="Please enter your email"
/>
);
expect(
screen.getByRole("textbox", {
name: /email address/i,
})
).toBeInTheDocument();
expect(screen.getByRole("alert")).toHaveTextContent(
"Please enter your email"
);
});
});
// src/test/setup.ts
import "@testing-library/jest-dom";
// src/utils/test-utils.ts
/* eslint-disable import/export */
import { cleanup, render } from "@testing-library/react";
import { afterEach } from "vitest";
afterEach(() => {
cleanup();
});
const customRender = (ui: React.ReactElement, options = {}) =>
render(ui, {
// wrap provider(s) here if needed
wrapper: ({ children }) => children,
...options,
});
export * from "@testing-library/react";
export { default as userEvent } from "@testing-library/user-event";
// override render export
export { customRender as render };