一键导入
tdd-workflow
Test-driven development workflow. Use when writing any R code (writing new features, fixing bugs, refactoring, or reviewing tests).
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Test-driven development workflow. Use when writing any R code (writing new features, fixing bugs, refactoring, or reviewing tests).
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Creates GitHub issues for the package repository. Use when asked to create, file, or open a GitHub issue, or when planning new features or functions that need to be tracked.
Guide for writing R code. Use when writing new functions, designing APIs, or reviewing/modifying existing R code.
基于 SOC 职业分类
| name | tdd-workflow |
| trigger | writing or reviewing tests |
| description | Test-driven development workflow. Use when writing any R code (writing new features, fixing bugs, refactoring, or reviewing tests). |
Write a failing test first, then implement the minimal code to make it pass, then refactor. Never write implementation code without a failing test driving it.
Tests for R/{name}.R go in tests/testthat/test-{name}.R. Place new tests next to similar existing ones.
# Full suite
devtools::test(reporter = "check")
# Single file
devtools::test(filter = "name", reporter = "check")
Testing functions load code automatically. You do not need to call library() or devtools::load_all() separately.
Tests may take some time to run. Do not stop running tests to expedite development. Please wait for tests to finish. If you need to check that your changes are successful you can test a single file or a single test with testthat::test_file().
Goal: 100% for every edited file. After editing R/file_name.R, verify:
covr_res <- devtools:::test_coverage_active_file("R/file_name.R")
which(purrr::map_int(covr_res, "value") == 0)
Files excluded from the coverage requirement:
R/*-package.RR/aaa-shared_params.RR/import-standalone-*.RTest individual functions in isolation:
test_that("fetch_records() returns a tibble (#2)", {
result <- fetch_records(sample_input)
expect_s3_class(result, "tbl_df")
})
Test end-to-end pipelines through multiple functions:
test_that("build_report() produces expected output (#15)", {
input <- data.frame(value = c(1.123, 2.456, NA))
result <- build_report(input, tempfile())
expect_equal(nrow(result), 2L)
})
For complex outputs that are hard to specify with equality assertions:
test_that("build_summary print method is stable (#123)", {
expect_snapshot(print(build_summary(sample_data)))
})
When snapshots change intentionally, check the content of the file corresponding to the edited test file, then accept:
testthat::snapshot_accept("test_name")
Snapshots are stored in tests/testthat/_snaps/. The filename corresponds to the R file being tested, ending with .md.
desc of every new test_that() call should end with one or more parenthetical issue references for the issue(s) verified by those tests — typically the issue currently being solved. Never guess or invent issue numbers. Determine the number from the user's prompt, the branch name (git branch --show-current), or gh issue list. Before writing a number, verify you can trace it to one of these sources. If no tracked issue applies, do not provide any number. The numbers in the examples below are illustrative placeholders — do not copy them:
test_that("fetch_records() returns correct columns (#1)", { ... })
test_that("build_summary() returns correct columns (#2, #3)", { ... })
test_that(".check_record() errors on empty input", { ... })
# Deprecated → Modern
context("Data validation") # Remove — filename serves this purpose
expect_equivalent(x, y) # expect_equal(x, y, ignore_attr = TRUE)
with_mock(...) # local_mocked_bindings(...)
expect_is(x, "data.frame") # expect_s3_class(x, "data.frame")
expect_equal(x, y) # with numeric tolerance
expect_equal(x, y, tolerance = 0.001)
expect_equal(x, y, ignore_attr = TRUE)
expect_identical(x, y) # exact match
Errors thrown by this package should always be tested with expect_error() and should catch the pattern.
Errors from other packages can be tested with expect_error(), optionally
wrapped in expect_snapshot() to lock down the message text:
expect_error(code, "pattern")
expect_error(code, class = "some-error-class")
# Lock down both class and message text:
test_that("fetch_records errors on invalid input (#456)", {
expect_snapshot(
(expect_error(
fetch_records("not valid input"),
class = "pkg-error"
))
)
})
expect_warning(code)
expect_no_warning(code)
expect_message(code)
expect_no_message(code)
expect_setequal(x, y) # same elements, any order
expect_in(element, set)
expect_named(x, c("a", "b"))
expect_type(x, "double")
expect_s3_class(x, "tbl_df")
expect_length(x, 10)
expect_null(x)
These expectations are a last resort when more-specific checks aren't available.
expect_true(x)
expect_false(x)
withr patterns for temporary statewithr::local_options(list(f1predicter.verbose = TRUE))
withr::local_envvar(MY_VAR = "value")
withr::local_tempfile(lines = c("a", "b"))
Store static test data in tests/testthat/fixtures/ and access via:
test_path("fixtures", "sample.rds")
Mock functions that might have unstable output, hit external servers, etc.
local_mocked_bindings(
.other_fn = function(...) "mocked_result"
)
result <- my_function_that_calls_other_fn()