Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:48:12 +08:00
commit faa6adcecf
10 changed files with 2332 additions and 0 deletions

View File

@@ -0,0 +1,199 @@
# Testing R Packages
Best practices for writing R package tests using testthat version 3+.
## Overview
This skill provides comprehensive guidance on modern R package testing with testthat 3, including:
- **Test structure and organization** - File organization, test hierarchy, and naming conventions
- **Core expectations** - All testthat expectation functions for equality, errors, types, and more
- **Design principles** - Self-sufficient tests, cleanup with withr, and test-first workflows
- **Snapshot testing** - Testing complex output, error messages, and visual diffs
- **Test fixtures** - Constructor functions, static files, and helper organization
- **Mocking** - Replacing external dependencies for reliable testing
- **BDD-style testing** - Using `describe()` and `it()` for behavior-driven development
- **Advanced topics** - Skipping tests, managing secrets, CRAN requirements, and parallel testing
## When This Skill Activates
Claude will use this skill when you:
- Write or modify tests for R packages
- Set up testing infrastructure with testthat
- Debug failing tests
- Organize test files and fixtures
- Create snapshot tests for complex output
- Mock external dependencies
- Follow BDD patterns with describe/it
- Prepare packages for CRAN submission
## What You'll Learn
### Test Structure
Learn the modern testthat 3 workflow:
- Initializing testing with `usethis::use_testthat(3)`
- Organizing tests to mirror package structure
- Using helper and setup files
- Running tests at different scales
### Expectations
Master all core expectations:
- Equality: `expect_equal()`, `expect_identical()`, `expect_all_equal()`
- Errors: `expect_error()`, `expect_no_error()`, `expect_warning()`
- Types: `expect_type()`, `expect_s3_class()`, `expect_r6_class()`
- Structure: `expect_length()`, `expect_shape()`, `expect_named()`
- Sets: `expect_contains()`, `expect_in()`, `expect_disjoint()`
### Design Principles
Follow five key principles:
1. **Self-sufficient tests** - Each test contains all needed setup
2. **Self-contained tests** - Use withr for automatic cleanup
3. **Plan for failure** - Write tests that are easy to debug
4. **Repetition is OK** - Clarity over DRY in tests
5. **devtools::load_all() workflow** - Efficient interactive testing
### Snapshot Testing
Test complex output effectively:
- Capture printed output, messages, and errors
- Use transforms to remove variable elements
- Create platform-specific variants
- Review and accept snapshot changes
### BDD-Style Testing
Write specification-style tests:
- Group related specs with `describe()`
- Define individual specs with `it()`
- Create nested hierarchies
- Mark pending specs without code
- Follow test-first development
## File Organization
The skill uses progressive disclosure with reference files:
```
testing-r-packages/
├── SKILL.md # Core workflows and common patterns
└── references/
├── bdd.md # BDD-style testing with describe/it
├── snapshots.md # Comprehensive snapshot testing
├── mocking.md # Mocking strategies and patterns
├── fixtures.md # Test data management
└── advanced.md # Advanced topics and edge cases
```
Core guidance loads automatically, while reference files load only when needed for specific scenarios.
## Key Features
### Modern testthat 3 Patterns
- Edition system with `Config/testthat/edition: 3`
- Improved snapshot testing
- Better error messages with waldo
- New expectations (`expect_no_error()`, `expect_contains()`, etc.)
- `local_mocked_bindings()` for reliable mocking
- Parallel test execution support
### Comprehensive Coverage
- Basic to advanced testing techniques
- Real-world examples from tidyverse packages
- Common patterns and anti-patterns
- Platform and CRAN considerations
- Integration with withr, waldo, and related packages
### Best Practices
- Test-first development workflows
- Proper fixture management
- Secrets and credentials handling
- File system discipline
- Custom expectations and helpers
## Examples
### Standard Testing
```r
test_that("str_length() counts characters", {
expect_equal(str_length("abc"), 3)
expect_equal(str_length(""), 0)
})
```
### BDD-Style Testing
```r
describe("User authentication", {
describe("login()", {
it("accepts valid credentials", {
result <- login("user@example.com", "password123")
expect_true(result$authenticated)
})
it("rejects invalid credentials", {
expect_error(login("user@example.com", "wrong"), class = "auth_error")
})
})
})
```
### Snapshot Testing
```r
test_that("error messages are helpful", {
expect_snapshot(error = TRUE, {
validate_input(NULL)
validate_input("wrong_type")
})
})
```
### Testing with Fixtures
```r
test_that("processes CSV files", {
csv_path <- test_path("fixtures", "sample.csv")
result <- process_csv(csv_path)
expect_equal(nrow(result), 100)
})
```
## Requirements
- R package with tests initialized via `usethis::use_testthat(3)`
- testthat version 3.0.0 or later
- R 4.1+ for latest testthat features
## Related Skills
- **package-development** - General R package development workflows
- **debugging** - Debugging R code and tests
- **documentation** - Writing package documentation
## Resources
This skill synthesizes guidance from:
- [R Packages: Testing Basics](https://r-pkgs.org/testing-basics.html)
- [R Packages: Testing Design](https://r-pkgs.org/testing-design.html)
- [R Packages: Testing Advanced](https://r-pkgs.org/testing-advanced.html)
- [testthat 3.0.0 release notes](https://tidyverse.org/blog/2020/10/testthat-3-0-0/)
- [testthat 3.1 release notes](https://tidyverse.org/blog/2021/10/testthat-3-1/)
- [testthat 3.2.0 release notes](https://tidyverse.org/blog/2023/10/testthat-3-2-0/)
- [testthat 3.3.0 release notes](https://tidyverse.org/blog/2025/11/testthat-3-3-0/)
- testthat package documentation
## Contributing
Found an issue or have a suggestion? Please [open an issue](https://github.com/posit-dev/skills/issues) or submit a pull request.
## License
This skill is part of the [Posit Claude Skills](https://github.com/posit-dev/skills) repository and is licensed under the MIT License.