write-testthat-tests
정보
이 Claude Skill은 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-testsClaude Code에서 이 명령을 복사하여 붙여넣어 스킬을 설치하세요
문서
撰寫 testthat 測試
用 testthat edition 3 為 R 套件函式建立全面測試。
適用時機
- 為新套件函式加測試
- 為既有代碼提升測試覆蓋率
- 為錯誤修復撰寫回歸測試
- 為新套件建立測試基礎設施
輸入
- 必要:欲測試之 R 函式
- 必要:預期行為與邊緣情況
- 選擇性:測試夾具或樣本資料
- 選擇性:目標覆蓋率百分比(預設 80%)
步驟
步驟一:設置測試基礎設施
若尚未完成:
usethis::use_testthat(edition = 3)
此建立 tests/testthat.R 與 tests/testthat/ 目錄。
預期: tests/testthat.R 與 tests/testthat/ 目錄已建立。DESCRIPTION 設有 Config/testthat/edition: 3。
失敗時: 若 usethis 不可用,手動建立 tests/testthat.R,內含 library(testthat); library(packagename); test_check("packagename"),並加 tests/testthat/ 目錄。
步驟二:建立測試文件
usethis::use_test("function_name")
此建立 tests/testthat/test-function_name.R,含範本。
預期: 測試文件建於 tests/testthat/test-function_name.R,含可填入之占位 test_that() 區塊。
失敗時: 若 usethis::use_test() 不可用,手動建文件。遵循命名慣例 test-<function_name>.R。
步驟三:撰寫基本測試
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")
})
預期: 基本測試涵蓋典型輸入之正確輸出、NA 處理行為與輸入驗證錯誤訊息。
失敗時: 若測試立即失敗,驗證函式已載入(devtools::load_all())。若錯誤訊息不匹配,於 expect_error() 中用正則模式而非確切字串。
步驟四:測試邊緣情況
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)))
})
預期: 邊緣情況皆涵蓋:空輸入、單值、零權重、極端值與無效輸入。每邊緣情況有清晰之預期行為。
失敗時: 若函式未如預期處理邊緣情況,決定修函式或調測試。對含糊情況記錄預期行為。
步驟五:複雜測試用夾具
於 tests/testthat/fixtures/ 建立測試資料:
# 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)
})
預期: 夾具於多個測試文件提供一致之測試資料。tests/testthat/helper.R 中之輔助函式由 testthat 自動載入。
失敗時: 若找不到輔助函式,確保文件名為 helper.R(非 helpers.R)且位於 tests/testthat/。若需,重啟 R 會話。
步驟六:模擬外部依賴
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)
})
預期: 外部依賴(API、資料庫、網路呼叫)得模擬,使測試無真實連線即可運行。模擬之返回值鍛鍊函式之資料處理邏輯。
失敗時: 若 local_mocked_bindings() 失敗,確保被模擬之函式於測試範圍可存取。對其他套件中之函式,用 .package 引數。
步驟七:複雜輸出之快照測試
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"
)
})
預期: 快照文件建於 tests/testthat/_snaps/。首次運行建立基線;後續運行對其比較。
失敗時: 若有意變更後快照失敗,以 testthat::snapshot_accept() 更新之。對跨平台差異,用 variant 參數維持平台特定快照。
步驟八:用 skip 條件
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)
})
預期: 需特殊環境(網路、資料庫、多核)之測試適當以 skip 條件守護。這些測試本地運行,但於 CRAN 或受限 CI 環境中跳過。
失敗時: 若測試於 CRAN 或 CI 失敗但本地通過,於 test_that() 區塊頂端加適當之 skip_on_cran()、skip_on_os() 或 skip_if_not() 守護。
步驟九:跑測試並檢查覆蓋率
# 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()
預期: 所有測試以 devtools::test() 通過。覆蓋率報告顯示目標百分比已達(目標 >80%)。
失敗時: 若測試失敗,讀測試輸出以察具體斷言失敗。若覆蓋率低於目標,用 covr::report() 辨識未測試之代碼路徑並為之加測試。
驗證
- 所有測試以
devtools::test()通過 - 覆蓋率超過目標百分比
- 每匯出函式至少有一測試
- 錯誤條件已測試
- 邊緣情況已涵蓋(NA、NULL、空、邊界值)
- 無測試依賴外部狀態或執行順序
常見陷阱
- 測試彼此依賴:各
test_that()區塊須獨立 - 硬編碼文件路徑:對測試夾具用
testthat::test_path() - 浮點比較:用
expect_equal()(有容差)非expect_identical() - 測試私人函式:盡可能透過公共 API 測試。
:::慎用 - CI 中之快照測試:快照對平台敏感。對跨平台用
variant參數 - 忘
skip_on_cran():需網路、資料庫或長運行之測試須於 CRAN 跳過
範例
# 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— 將測試基礎設施作為套件建立之一部分write-roxygen-docs— 文檔化所測試之函式setup-github-actions-ci— 推送時自動跑測試submit-to-cran— CRAN 要求測試於所有平台通過
GitHub 저장소
연관 스킬
evaluating-llms-harness
테스팅이 Claude Skill은 MMLU, GSM8K를 포함한 60개 이상의 표준화된 학술 과제에서 LLM 성능을 벤치마크하기 위해 lm-evaluation-harness를 실행합니다. 개발자들이 모델 품질을 비교하고, 학습 진행 상황을 추적하거나 학술 결과를 보고할 수 있도록 설계되었습니다. 이 도구는 HuggingFace와 vLLM 모델을 포함한 다양한 백엔드를 지원합니다.
cloudflare-cron-triggers
테스팅이 스킬은 cron 표현식을 사용하여 Worker를 스케줄링하기 위한 Cloudflare Cron Triggers 구현에 관한 포괄적인 지식을 제공합니다. 주기적 작업, 유지보수 작업, 자동화된 워크플로우 설정 방법을 다루며, 잘못된 cron 표현식이나 시간대 문제 같은 일반적인 이슈들을 해결하는 방법을 포함합니다. 개발자들은 이를 통해 스케줄된 핸들러 구성, cron 트리거 테스트, Workflows 및 Green Compute와의 연동 작업을 수행할 수 있습니다.
webapp-testing
테스팅이 Claude Skill은 Python 스크립트를 통해 로컬 웹 애플리케이션을 테스트하기 위한 Playwright 기반 툴킷을 제공합니다. 프론트엔드 검증, UI 디버깅, 스크린샷 캡처, 로그 확인 기능을 지원하며 서버 라이프사이클을 관리합니다. 브라우저 자동화 작업에 사용하되 컨텍스트 오염을 방지하기 위해 소스 코드를 읽지 않고 스크립트를 직접 실행하세요.
finishing-a-development-branch
테스팅이 스킬은 테스트 통과를 확인한 후 체계적인 통합 옵션을 제시하여 개발자가 완성된 작업을 마무리하도록 돕습니다. 구현이 완료된 후 머지, PR 생성, 브랜치 정리와 같은 워크플로우를 안내합니다. 코드가 준비되고 테스트가 완료되었을 때 개발 프로세스를 체계적으로 마무리하기 위해 사용하세요.
