Agent skill

Unit Testing

by scaleway in scaleway/ultraviolet

Write Vitest/Testing Library tests the Ultraviolet way — interact with the rendered DOM like a user, following query priority.

Apache-2.0Auto-check passedFrontend & Design

Install Unit Testing

skills CLI
$ npx skills add scaleway/ultraviolet --skill unit-testing -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install scaleway/ultraviolet unit-testing --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/scaleway/ultraviolet.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/unit-testing .claude/skills/unit-testing && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
unit-testing
GitHub stars
127
Token cost
~1.7k tokens
SKILL.md length
740 words
Files
1
Skills in repo
4
Repo updated
First seen
Licence
Apache-2.0

At a glance

Write Vitest/Testing Library tests the Ultraviolet way — interact with the rendered DOM like a user, following query priority.

  • Works in 3 steps: Test the rendered DOM, not component… → Interact with components the way a user… → Write the smallest test that fails if…
  • Updating React component tests
  • SKILL.md covers Guiding principles, Query priority, Ultraviolet conventions and Snapshot policy
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Unit Testing is an agent skill from scaleway/ultraviolet. Write Vitest/Testing Library tests the Ultraviolet way — interact with the rendered DOM like a user, following query priority. Use when creating or updating React component tests, or rewriting snapshot-only tests into behavior assertions.

Its SKILL.md is about 1.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Frontend & Design, covering Unit testing and React components. It works with Testing Library and Vitest. The repository describes itself as: A monorepo Design System with React components. The licence is Apache-2.0.

When your agent uses it

  • Updating React component tests
  • Rewriting snapshot-only tests into behavior assertions

Example prompts

  • “/unit-testing”

Workflow steps

3 steps, taken from the first numbered list in SKILL.md.

  1. Test the rendered DOM, not component instances or implementation details.
  2. Interact with components the way a user would: by visible text, labels, and roles —
  3. Write the smallest test that fails if the logic breaks — a test that goes red on

What it can do on your machine

Read from SKILL.md and the folder at commit 738c080. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Unit Testing loads about 1.7k tokens when it runs. Until then it costs about 63 tokens; SKILL.md has 740 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~63
When it runs · the whole SKILL.md, loaded when a task matches
~1.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from scaleway/ultraviolet at commit 738c080, republished under its Apache-2.0 licence (© scaleway). 740 words, ~1,671 tokens.

Download SKILL.mdSave it as .claude/skills/unit-testing/SKILL.md (or your agent's skills folder).
name
unit-testing
description
Write Vitest/Testing Library tests the Ultraviolet way — interact with the rendered DOM like a user, following query priority. Use when creating or updating React component tests, or rewriting snapshot-only tests into behavior assertions.

Unit Testing with Testing Library

Tests resemble real user interaction. The more a test looks like a user, the more confidence it gives.

Guiding principles

  1. Test the rendered DOM, not component instances or implementation details.
  2. Interact with components the way a user would: by visible text, labels, and roles — never through internals, props, or state.
  3. Write the smallest test that fails if the logic breaks — a test that goes red on the bug.

A component that is hard to query by role or text is usually inaccessible, not a reason to reach for a lower-priority query.

Query priority

Choose the highest query that works, in this order:

  1. Accessible to everyone
    1. getByRole — top preference for almost everything. Use with name to filter by accessible name: getByRole('button', { name: /submit/i }). If you can't match something by role, the UI is probably inaccessible.
    2. getByLabelText — best for form fields; mirrors how users find inputs by their label.
    3. getByPlaceholderText — placeholder is not a label, only use if that's all there is.
    4. getByText — for non-interactive elements (div, span, p) outside forms.
    5. getByDisplayValue — for filled-in form values.
  2. Semantic queries — HTML5/ARIA selectors, but inconsistent across browsers/screen readers.
    1. getByAltText — for img, area, input.
    2. getByTitle — title is not read consistently and not visible to sighted users.
  3. Test IDs — getByTestId only when you can't match by role or text and it doesn't make sense (e.g. dynamic text). Users can't see them; a testid is a last resort.
By component type
  • Interactive (button, link, tab, switch): getByRole
  • Feedback/labels (alert, status): getByRole('alert'), getByRole('status')
  • Layout/content: getByText
  • Icons/avatars: getByAltText
  • Fallback only: getByTestId

Ultraviolet conventions

  • Tests live in src/components/<Name>/__tests__/*.test.tsx (or *.test.ts for pure utils).
  • Use renderWithTheme from @utils/test to render within the theme provider:
    tsx
    import { renderWithTheme } from '@utils/test'
    import { screen } from '@testing-library/react'
    import { userEvent } from '@testing-library/user-event'
    
    it('submits on click', async () => {
      const onClick = vi.fn()
      renderWithTheme(<Button onClick={onClick}>Submit</Button>)
      await userEvent.click(screen.getByRole('button', { name: /submit/i }))
      expect(onClick).toHaveBeenCalledOnce()
    })
  • Interact with userEvent (click, type, hover, keyboard) — not fireEvent where possible.
  • Use screen (pre-bound to document.body); screen.getByRole is preferred over destructuring from render.
  • Pure functions: assert behavior with expect(fn(input)).toEqual(output), no rendering needed.
a11y.test.tsx vs regular tests

The line is thin, but split files by intent:

  • a11y.test.tsx — accessibility-only concerns: axe violations, keyboard navigation, focus management, ARIA attributes. Query by role to trigger those checks, but assert on a11y outcomes (expect(axe).toHaveNoViolations(), focus landing, etc.).
  • Regular *.test.tsx — behavior: does the component render and respond. getByRole here asserts behavior; labels/descriptions/roles are matched as a side effect of finding the element a user interacts with, not asserted directly.

If a test's real question is "is this accessible?", it's an a11y test. If it's "does this work?", it's a regular test. Same query tools, different intent.

Show full SKILL.md (320 more words)Show less
Prefer semantic matchers over attribute checks

toHaveAttribute tests the implementation (an attribute on an element); jest-dom's semantic matchers test the behavior a user perceives. Reach for them first — if a matcher exists for what you're asserting, use it instead of checking the attribute that happens to produce it:

  • expect(radio).toHaveAccessibleName('Agree') — over toHaveAttribute('aria-label', ...)
  • expect(radio).toHaveAccessibleDescription('Invalid value') — over checking aria-describedby/title wiring
  • expect(button).toBeDisabled() — over toHaveAttribute('disabled')
  • expect(radio).toBeChecked() — over toHaveAttribute('checked') or poking .checked
  • expect(toast).toBeVisible() — over toHaveAttribute('aria-hidden', 'false')

These compute their result from the whole source chain (label, aria-label, aria-labelledby, title, form state, etc.), so they pass when the wiring works and fail when it breaks — even if the break is in a different attribute than the one you'd have checked.

Snapshot policy

A snapshot only locks the initial DOM — it passes until someone clicks "update snapshot", so it never catches a regression. Use one to sanity-check the default render, then prove every behavior (state, props, interaction) with assertions.

  • Good: one asFragment().toMatchSnapshot() for the default render + userEvent / screen.getByRole assertions for every behavior.
  • Bad: a loop of variants each only snapshotting render(<Button variant={v} />).

shouldMatchSnapshot from @utils/test locks markup, not behavior, and is deprecated. It is acceptable only as an initial-DOM lock; otherwise assert what the variant changes.

Rewriting a snapshot-only test
  1. Keep one snapshot of the default render to lock the initial DOM.
  2. For each prop/variant/state, replace the snapshot with assertions on what the user sees and can do: getByRole('button', { name: /submit/i }), expect(el).toHaveAttribute(...), await userEvent.click(...) then expect(onClick).toHaveBeenCalled(), etc.
  3. Delete redundant variant snapshots — assert the behavior those variants enable instead.
  4. If no a11y.test.tsx exists next to the rewritten file, create one with:
    • expectNoViolations(container) across every theme in consoleThemesMap (use it.for([...consoleThemesMap.entries()])), rendering the component with a realistic full set of props.
    • Any component-specific a11y assertions (decorative alt="" images, ARIA wiring, accessible name/description via jest-dom semantic matchers like toHaveAccessibleName / toHaveAccessibleDescription). Tag the describe block with { tags: ['a11y'] }. See existing a11y.test.tsx files (e.g. Radio, Button) for the established pattern.

© scaleway, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/unit-testing of scaleway/ultraviolet.

Open the folder on GitHubat commit 738c080

Compare with similar skills

Unit Testing next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Unit Testing compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Unit Testing this skillscaleway/ultraviolet127—~1.7kAutomated safety check: PassApache-2.0
Storybookpproenca/dot-skills214—~3.6kAutomated safety check: PassMIT
React Testingaffaan-m/ECC274k1 repos~3.3kAutomated safety check: PassMIT
React Testingcitypaul/.dotfiles739—~3.6kAutomated safety check: PassCustom licence
React TestingHoangNguyen0403/agent-skills-standard570—~1.3kAutomated safety check: PassMIT
Hilla TestAI-Unified-Process/marketplace140—~3.9kAutomated safety check: WarnApache-2.0

Similar skills

  • Storybook

    pproenca/dot-skills

    A skill your agent uses whenever creating, configuring, or extending Storybook for a TS/React component library — covers main.ts/preview.ts setup, CSF3 story authoring, args/argTypes/controls…

    214 GitHub stars~3.6k tokensUpdated 1 mo ago
    Frontend & DesignAuto-check passed
  • React Testing

    affaan-m/ECC

    React component testing with React Testing Library, Vitest/Jest, MSW for network mocking, accessibility assertions with axe, and the decision boundary between component tests and Playwright/Cypress…

    274k GitHub starsUsed in 1 repo~3.3k tokens
    Testing & QAAuto-check passed
  • React Testing

    citypaul/.dotfiles

    React component testing patterns including components, hooks, context, and forms.

    739 GitHub stars~3.6k tokensUpdated 4 days ago
    Testing & QAAuto-check passed
  • React Testing

    HoangNguyen0403/agent-skills-standard

    Test React components with RTL and Jest/Vitest. An agent skill from HoangNguyen0403/agent-skills-standard.

    570 GitHub stars~1.3k tokensUpdated yesterday
    Testing & QAAuto-check passed
  • Hilla Test

    AI-Unified-Process/marketplace

    Creates tests for Hilla use cases on both sides of the browser boundary: Vitest + React Testing Library tests for the React/TypeScript view (with the generated endpoint clients mocked) and Spring…

    140 GitHub stars~3.9k tokensUpdated 2 days ago
    Testing & QAAuto-check: warnings
  • Dify Frontend Testing

    langgenius/dify

    Use when writing or changing Vitest or React Testing Library tests under `web/` or `packages/dify-ui/`, or when the user explicitly requests frontend test…

    158k GitHub stars~242 tokensUpdated today
    Testing & QAAuto-check passed

More from scaleway/ultraviolet

  • A11y Audit

    scaleway/ultraviolet

    Audit components for accessibility. An agent skill from scaleway/ultraviolet.

    127 GitHub stars~979 tokensUpdated yesterday
    Auto-check passed
  • A11y Fix

    scaleway/ultraviolet

    Fix accessibility issues documented in a component's A11y.mdx audit file by editing the component source, then refresh the audit artifacts.

    127 GitHub stars~1.3k tokensUpdated yesterday
    Auto-check passed
  • Create PR

    scaleway/ultraviolet

    Create or update a GitHub Pull Request — analyze the diff, draft the description from the repo template, push with gh.

    127 GitHub stars~566 tokensUpdated yesterday
    Auto-check passed

Questions about Unit Testing

What does Unit Testing do?

Write Vitest/Testing Library tests the Ultraviolet way — interact with the rendered DOM like a user, following query priority. Unit Testing is an agent skill from scaleway/ultraviolet. Write Vitest/Testing Library tests the Ultraviolet way — interact with the rendered DOM like a user, following query priority.

When should I use Unit Testing?

Unit Testing fits situations like: updating React component tests; rewriting snapshot-only tests into behavior assertions.

How do I install Unit Testing in Claude Code?

Run `npx skills add scaleway/ultraviolet --skill unit-testing -a claude-code`. Or copy the skill folder (.agents/skills/unit-testing in scaleway/ultraviolet) into .claude/skills/unit-testing in your project. Claude Code loads it when a task matches its description.

How do I install Unit Testing in Codex?

Run `npx skills add scaleway/ultraviolet --skill unit-testing -a codex`. Or copy the skill folder (.agents/skills/unit-testing in scaleway/ultraviolet) into .agents/skills/unit-testing in your project. Codex loads it when a task matches its description.

Can I use Unit Testing in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add scaleway/ultraviolet --skill unit-testing -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/unit-testing, .gemini/skills/unit-testing, .github/skills/unit-testing and .opencode/skills/unit-testing in your project.

What does Unit Testing need to run?

SKILL.md names no scripts, command-line tools or credentials: Unit Testing is instructions for the agent only.

Does Unit Testing access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Unit Testing safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Unit Testing use?

Unit Testing is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Unit Testing use?

About 1.7k tokens (SKILL.md is roughly 6.7k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Unit Testing?

Skills that share tags, products or a category with Unit Testing: Storybook (pproenca/dot-skills, 214 stars), React Testing (affaan-m/ECC, 274k stars), React Testing (citypaul/.dotfiles, 739 stars) and React Testing (HoangNguyen0403/agent-skills-standard, 570 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Unit Testing?

scaleway (a GitHub organization) maintains it in scaleway/ultraviolet, which has 127 GitHub stars. The repository holds 4 skills in this directory. The repository was last updated on October 6, 2026.

Source: scaleway/ultraviolet on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.