write-testthat-tests
について
このスキルは、Rパッケージ関数の包括的なtestthat(エディション3)テストスイートを生成します。テストの構成、期待値の検証、モッキング、スナップショットテストを網羅し、高いコードカバレッジの達成を支援します。新規関数のテスト追加、既存コードのカバレッジ向上、回帰テストの作成、またはテストインフラの構築時にご利用ください。
クイックインストール
Claude Code
推奨npx skills add pjt222/agent-almanac -a claude-code/plugin add https://github.com/pjt222/agent-almanacgit clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/write-testthat-testsこのコマンドをClaude Codeにコピー&ペーストしてスキルをインストールします
ドキュメント
Write testthat Tests
Comprehensive tests for R pkg fns via testthat ed 3.
Use When
- New pkg fns
- Increase coverage for existing
- Regression tests for bug fixes
- Setup test infra for new pkg
In
- Required: R fns to test
- Required: Expected behavior + edge cases
- Optional: Test fixtures|sample data
- Optional: Target coverage % (default: 80%)
Do
Step 1: Setup Test Infra
If not done:
usethis::use_testthat(edition = 3)
Creates tests/testthat.R + tests/testthat/ dir.
Got: tests/testthat.R + tests/testthat/ dir created. DESCRIPTION has Config/testthat/edition: 3.
If err: usethis unavail → manually create tests/testthat.R w/ library(testthat); library(packagename); test_check("packagename") + add tests/testthat/.
Step 2: Test File
usethis::use_test("function_name")
Creates tests/testthat/test-function_name.R w/ template.
Got: Test file at tests/testthat/test-function_name.R w/ placeholder test_that() ready to fill.
If err: usethis::use_test() unavail → manual. Naming: test-<function_name>.R.
Step 3: Basic Tests
test_that("weighted_mean computes correct result", {
expect_equal(weighted_mean(1:3, c(1, 1, 1)), 2)
expect_equal(weighted_mean(c(10, 20), c(1, 3)), 17.5)
})
test_that("weighted_mean handles NA values", {
expect_equal(weighted_mean(c(1, NA, 3), c(1, 1, 1), na.rm = TRUE), 2)
expect_true(is.na(weighted_mean(c(1, NA, 3), c(1, 1, 1), na.rm = FALSE)))
})
test_that("weighted_mean validates input", {
expect_error(weighted_mean("a", 1), "numeric")
expect_error(weighted_mean(1:3, 1:2), "length")
})
Got: Basic tests cover correct out for typical inputs, NA handling, input valid err msgs.
If err: Tests fail immediately → verify fn loaded (devtools::load_all()). Err msgs don't match → regex pattern in expect_error() not exact string.
Step 4: Edge Cases
test_that("weighted_mean handles edge cases", {
# Empty input
expect_error(weighted_mean(numeric(0), numeric(0)))
# Single value
expect_equal(weighted_mean(5, 1), 5)
# Zero weights
expect_true(is.nan(weighted_mean(1:3, c(0, 0, 0))))
# Very large values
expect_equal(weighted_mean(c(1e15, 1e15), c(1, 1)), 1e15)
# Negative weights
expect_error(weighted_mean(1:3, c(-1, 1, 1)))
})
Got: Edge cases covered: empty, single vals, zero weights, extreme, invalid. Each w/ clear expected behavior.
If err: Fn doesn't handle edge case as expected → fix fn or adjust test. Doc intended behavior for ambiguous.
Step 5: Fixtures for Complex
Create tests/testthat/fixtures/ for test data:
# tests/testthat/helper.R (loaded automatically)
create_test_data <- function() {
data.frame(
x = c(1, 2, 3, NA, 5),
group = c("a", "a", "b", "b", "b")
)
}
# In test file
test_that("process_data works with grouped data", {
test_data <- create_test_data()
result <- process_data(test_data)
expect_s3_class(result, "data.frame")
expect_equal(nrow(result), 2)
})
Got: Fixtures provide consistent test data across files. Helpers in tests/testthat/helper.R loaded auto by testthat.
If err: Helpers not found → ensure file helper.R (not helpers.R) + located in tests/testthat/. Restart R sess if needed.
Step 6: Mock External Deps
test_that("fetch_data handles API errors", {
local_mocked_bindings(
api_call = function(...) stop("Connection refused")
)
expect_error(fetch_data("endpoint"), "Connection refused")
})
test_that("fetch_data returns parsed data", {
local_mocked_bindings(
api_call = function(...) list(data = list(value = 42))
)
result <- fetch_data("endpoint")
expect_equal(result$value, 42)
})
Got: External deps (APIs, DBs, net calls) mocked → tests run w/o real connections. Mock returns exercise data processing logic.
If err: local_mocked_bindings() fails → ensure mocked fn accessible in test scope. Other pkgs → use .package arg.
Step 7: Snapshot Tests for Complex Out
test_that("format_report produces expected output", {
expect_snapshot(format_report(test_data))
})
test_that("plot_results creates expected plot", {
expect_snapshot_file(
save_plot(plot_results(test_data), "test-plot.png"),
"expected-plot.png"
)
})
Got: Snapshot files created in tests/testthat/_snaps/. First run creates baseline; subsequent compare.
If err: Snapshots fail after intentional change → update w/ testthat::snapshot_accept(). Cross-platform diffs → variant param to maintain platform-specific.
Step 8: Skip Conditions
test_that("database query works", {
skip_on_cran()
skip_if_not(has_db_connection(), "No database available")
result <- query_db("SELECT 1")
expect_equal(result[[1]], 1)
})
test_that("parallel computation works", {
skip_on_os("windows")
skip_if(parallel::detectCores() < 2, "Need multiple cores")
result <- parallel_compute(1:100)
expect_length(result, 100)
})
Got: Tests requiring special env (net, DB, multi cores) guarded w/ skip. Run locally, skip on CRAN|restricted CI.
If err: Tests fail on CRAN|CI but pass locally → add skip_on_cran(), skip_on_os(), skip_if_not() at top of test_that().
Step 9: Run + Coverage
# Run all tests
devtools::test()
# Run specific test file
devtools::test_active_file() # in RStudio
testthat::test_file("tests/testthat/test-function_name.R")
# Check coverage
covr::package_coverage()
covr::report()
Got: All tests pass devtools::test(). Coverage report shows target met (aim > 80%).
If err: Tests fail → read out for assertion failures. Coverage below target → covr::report() to ID untested paths + add tests.
Check
- All tests pass
devtools::test() - Coverage > target %
- Every exported fn has 1+ test
- Err conditions tested
- Edge cases covered (NA, NULL, empty, boundary)
- No tests depend on external state|order
Traps
- Tests depend on each other: Each
test_that()independent - Hardcoded paths:
testthat::test_path()for fixtures - Float compare:
expect_equal()(tolerance) notexpect_identical() - Test private fns: Test through public API.
:::sparingly. - Snapshot in CI: Platform-sensitive.
variantfor cross-platform. - Forget
skip_on_cran(): Net|DB|long runtime → skip on CRAN
Examples
# Pattern: test file mirrors R/ file
# R/weighted_mean.R -> tests/testthat/test-weighted_mean.R
# Pattern: descriptive test names
test_that("weighted_mean returns NA when na.rm = FALSE and input contains NA", {
result <- weighted_mean(c(1, NA), c(1, 1), na.rm = FALSE)
expect_true(is.na(result))
})
# Pattern: testing warnings
test_that("deprecated_function emits deprecation warning", {
expect_warning(deprecated_function(), "deprecated")
})
→
create-r-package— setup test infra as part of pkg creationwrite-roxygen-docs— doc fns you testsetup-github-actions-ci— auto run tests on pushsubmit-to-cran— CRAN requires tests pass on all platforms
GitHub リポジトリ
関連スキル
evaluating-llms-harness
テストこのClaudeスキルは、lm-evaluation-harnessを実行し、MMLUやGSM8Kなど60以上の標準化学術タスクでLLMをベンチマークします。開発者がモデルの品質を比較し、トレーニングの進捗を追跡し、学術的な結果を報告するために設計されています。このツールはHuggingFaceやvLLMモデルを含む様々なバックエンドをサポートしています。
cloudflare-cron-triggers
テストこのスキルは、cron式を使用してWorkersをスケジュールするためのCloudflare Cron Triggersの実装に関する包括的な知識を提供します。定期的なタスクの設定、メンテナンスジョブ、自動化されたワークフローの構築を網羅し、無効なcron式やタイムゾーン問題といった一般的な課題への対処法も含みます。開発者はこれを使用して、スケジュールされたハンドラーの設定、cronトリガーのテスト、WorkflowsやGreen Computeとの連携を構成できます。
webapp-testing
テストこのClaude Skillは、Playwrightベースのツールキットを提供し、Pythonスクリプトを通じてローカルWebアプリケーションのテストを可能にします。フロントエンドの検証、UIデバッグ、スクリーンショット撮影、ログ表示を実現し、サーバーライフサイクルを管理します。ブラウザ自動化タスクにご利用いただけますが、コンテキストの汚染を避けるため、スクリプトのソースコードを読むのではなく直接実行してください。
finishing-a-development-branch
テストこのスキルは、開発者がテストの合格を確認し、構造化された統合オプションを提示することで、完成した作業を仕上げることを支援します。実装が完了した後のマージ、PR作成、ブランチの整理といったワークフローを案内します。コードが準備できてテスト済みの際に使用し、開発プロセスを体系的に完了させましょう。
