본문으로 건너뛰기
cccskills
무료GitHub에 공개

rust-tests

Write cargo tests. A test name is a sentence, the body is setup, mock, test and verify blocks separated by blank lines with no comments, and shared setup lives in a named test-support module rather than in each test. Covers naming, the block shape, where a test file goes, async and time, workspaces, and running one crate or one filter. Use when adding or changing any #[test] or #[tokio::test], or when Rust coverage has to come up. Triggers - "write a rust test", "cargo test", "test this crate", "cover this handler".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md5.7 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Rust tests

Same three rules as the TypeScript side: the name is the sentence, the body is blocks separated by blank lines, and there are no comments. The differences are where a test lives and what setup it is allowed to do.

#[test]
fn refuses_to_scan_without_credentials() {
    let state = test_state();
    let progress = Progress::default();

    let err = scan(&state, &progress.record(), &never_cancelled()).unwrap_err();

    assert!(matches!(err, ScanError::NoApiKey));
    assert_eq!(progress.seen(), vec![]);
}

The four blocks

A body is up to four blocks, always in this order, one blank line between them:

BlockHolds
setupFixtures, state, the world the behaviour needs
mockFakes and the responses they are primed with
testThe one call under test
verifyThe assertions
  • A blank line only ever separates two blocks. Never one inside a block, never two in a row.
  • An empty block is absent, not blank. Most tests have three, because a test-support helper builds the world and there is nothing left to fake.
  • No comment names a block. The order is the label.
  • Every assertion in verify. An assert! in the setup block is a precondition, and one worth checking is its own test.
  • let bindings that only feed the call belong in setup, not squeezed into the test line. One statement under test, readable on its own.

Rust makes the mock block rarer than TypeScript does: a trait with a small fake implementation is setup, not mocking, and it lives above the tests with a name.

Naming

The function name is the sentence, in the present tense, describing behaviour:

fn refuses_to_scan_without_credentials()   // good
fn marks_a_missing_file_absent()           // good

fn test_scan()                             // names the function under test
fn scan_works()                            // says nothing
fn test_scan_returns_err_when_key_is_none() // describes the code, not the rule

Drop the test_ prefix. #[test] already says it.

Size and setup

One situation, one action, one assertion. Shared setup belongs in a named test-support module, not repeated in each test. Find the one the crate already has before writing a second: test_support, common, tests/common/mod.rs and fixtures are all conventional names, and a crate usually has exactly one.

use crate::test_support::{seed_fixture, test_state};

When a test needs a fake collaborator, give it a name and keep it above the tests, not inline:

#[derive(Default)]
struct Progress(RefCell<Vec<(usize, usize)>>);

A test that runs long is two tests, or a fixture that wants a name, or a function that needs too many collaborators to say anything.

No comments

No banner, no note above a case, no paragraph explaining what the module pins. The name carries the behaviour and the blank lines carry the phases. A comment survives only for a genuinely non-obvious fixture value, stating why that value and not another.

// SAFETY: still applies inside unsafe, in tests as everywhere else.

Assert behaviour

  • assert!(matches!(err, ScanError::NoApiKey)) beats asserting on a formatted string: the message is prose and prose changes.
  • Assert the observable result, not the number of times a collaborator was called, unless the count is the behaviour.
  • unwrap() and expect() are fine in a test. A panic is a failure and that is the point.
  • Never weaken an assertion to make a suite green.

Where it goes

  • Unit tests live beside the code in a #[cfg(test)] mod tests, with access to the module's private items. This is where most tests belong.
  • Integration tests live in the crate's tests/ directory and see only the public API, which is what makes them worth having: a test that cannot reach a private helper proves the public surface is usable.
  • Some projects keep API integration tests beside the handlers behind a file-name prefix instead, so the test moves with the route it covers. Follow the tree.
  • A workspace member is tested by name. In a repo whose members are separate workspaces rather than one, --workspace from the root does not reach them, so check whether the project ships a script that iterates them.

Async and time

  • #[tokio::test] for anything awaiting. Keep the runtime default unless the test needs otherwise.
  • Never sleep to synchronise. Wait on the thing itself: a channel, a notify, a join handle. A sleep is a flake with a timer on it.
  • Pass time in rather than reading the clock, so the test does not depend on when it runs.

Running one

cargo test -p <crate>              # one crate
cargo test --workspace <filter>    # one test name, everywhere
cargo test -p <crate> -- --nocapture

Run from the workspace root that owns the crate. Where the repo holds more than one workspace, cd to the right one first.

Before the PR

cargo clippy --workspace --all-targets && cargo test --workspace

Then whatever the project's manifest scripts run for members outside that workspace, because --workspace does not reach them.

Where the file goes on disk, and what its suffix means, belong to the naming skill.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

One file, one job, and short enough to hold in your head. Covers the size policy (hard-split over 300 lines, split 200 to 300 at a seam, aim for 150), what a natural seam is and where to cut, the exemptions, the dependency rules that decide where the split lands, and the signals that a file is already two files. Use before adding to a file that is already long, when naming a new file, when a function has nowhere obvious to live, or when a review says a file is doing too much. Triggers - "this file is too long", "where should this go", "split this file", "is this file too big", "one responsibility".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

kromatv/kroma602026년 10월 19일 업데이트

naming

무료

What things get called. A file is named after its export in the project's case convention, a suffix is a resolution instruction rather than decoration, an index file only re-exports, and some symbol names are always wrong (utils, helpers, V2, Enhanced, New). Covers learning a tree's local vocabulary before adding to it, test and platform-variant naming, and the per-language conventions. Use when creating a file or directory, naming a test file, adding a platform variant, or when a name has to change. Triggers - "what should I call this file", "where does this file go", "naming convention", "kebab or camel", "name this test".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

kromatv/kroma602026년 10월 19일 업데이트

Spawn the comment hunter, fix accepted findings, and offer encodings for claimed constraints.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

kromatv/kroma602026년 10월 19일 업데이트

Write a short release note people finish reading. Picks the few changes a user will notice from the pull requests since the last release, names each by what the reader can now do, keeps to a length budget, writes every language from the intent instead of translating, and traces every line to a PR. Use when cutting a release, or filling a GitHub Release body, a store "what's new", a package changelog or an in-app what's new screen. Triggers - "write the release notes", "release notes for 0.4.0", "what's new", "changelog for this release", "notes de version".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

kromatv/kroma602026년 10월 19일 업데이트

Rust best practices. Use when reading or editing any .rs file, designing a crate's public API, choosing an error type, splitting a workspace, or writing async code on tokio. Triggers - "rust best practices", "is this idiomatic", "should this be a newtype", "anyhow or thiserror", "why does the borrow checker", "review this Rust".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

kromatv/kroma602026년 10월 19일 업데이트

Security guidance and vulnerability review for codebases, APIs, services, CLI tools, libraries, and daemons. Use for security questions, focused reviews, vulnerability research, security audits, or pen tests. Run the complete workflow only for explicit codebase audit or pen-test requests, full/comprehensive/end-to-end reviews, or requested report artifacts.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

kromatv/kroma602026년 10월 19일 업데이트

kromatv의 스킬 모두 보기

이 스킬의 문제 신고