200 lines
6.1 KiB
Markdown
200 lines
6.1 KiB
Markdown
# 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.
|