Development Workflow
This guide covers the efficient development workflow for R package development.
The Fast Iteration Cycle
IMPORTANT: Follow this workflow to develop efficiently.
During Development (Fast Iteration Cycle)
Run these commands repeatedly while developing:
devtools::document()- Generate documentation from roxygen2 commentsUpdates
man/directoryUpdates
NAMESPACEwith exports and importsTakes seconds to run
devtools::load_all()- Load your package into memoryEquivalent to library(yourpackage) but uses development version
Loads all functions, even unexported ones
Takes seconds to run
devtools::test()- Run all testsRuns testthat test suite
Takes seconds to minutes depending on test count
For single file:
devtools::test_active_file('R/yourfile.R')
This cycle is fast (seconds) and gives you immediate feedback.
Why This Works
# Typical workflow:
devtools::document() # Update docs and namespace
devtools::load_all() # Load updated code
devtools::test() # Verify it works
# Test your function interactively
your_function(test_data)
# Find issue, fix code, repeatThis tight feedback loop lets you:
Catch errors immediately
Test interactively
Iterate quickly on design
Final Validation (Run Once at End)
devtools::check()- Full R CMD check
WARNING: Do NOT run check() during iteration.
Why avoid check() during development?
Takes 1-2 minutes (sometimes longer)
Runs many validations unnecessary during development
Interrupts your flow
Everything it checks is validated by the fast cycle
When to run check()
Only run check() once at the very end:
Before submitting to CRAN
Before creating a release
Before final code review
After all development is complete
check() validates:
Package structure
Documentation completeness
Code quality
Examples run correctly
Tests pass
No NOTEs or WARNINGs
Interactive Development
Testing individual functions
# Load your package
devtools::load_all()
# Test your function
result <- your_function(mtcars, mpg, hp)
result
# Check intermediate values
debug(your_function)
your_function(mtcars, mpg, hp)Using browser() for debugging
your_function <- function(data, ...) {
# Add browser() where you want to pause
browser()
# Rest of function
}
# Run function - it will pause at browser()
your_function(test_data)Common Workflow Patterns
Pattern 1: New Function Development
# 1. Write function in R/your-file.R
# 2. Add roxygen documentation
# 3. Document and load
devtools::document()
devtools::load_all()
# 4. Test interactively
your_function(test_data)
# 5. Write formal tests in tests/testthat/test-your-file.R
# 6. Run tests
devtools::test()
# 7. Fix issues, go to step 3Pattern 2: Fixing a Bug
# 1. Write a failing test that demonstrates the bug
# 2. Run tests to confirm failure
devtools::test()
# 3. Fix the code
# 4. Document and load
devtools::document()
devtools::load_all()
# 5. Verify test now passes
devtools::test()Pattern 3: Updating Documentation
# 1. Update roxygen comments in R code
# 2. Regenerate documentation
devtools::document()
# 3. Preview documentation
?your_function
# 4. Repeat until satisfiedKeyboard Shortcuts (RStudio)
Speed up your workflow with keyboard shortcuts:
Cmd/Ctrl + Shift + D-devtools::document()Cmd/Ctrl + Shift + L-devtools::load_all()Cmd/Ctrl + Shift + T-devtools::test()Cmd/Ctrl + Shift + E-devtools::check()
Best Practices
DO:
Run the fast cycle (document, load, test) frequently
Test interactively in console
Write tests as you develop
Fix issues immediately when found
Use
browser()for complex debugging
DON’T:
Run
check()during development (only at end)Skip writing tests “for later” (write them now)
Ignore warnings from
document()ortest()Make many changes before testing
Commit broken code to git
Troubleshooting
“could not find function”
Problem: Function exists in R code but not loaded
Solution: Run devtools::load_all()
“object not found in namespace”
Problem: Missing @export in roxygen or namespace not updated
Solution:
# Add @export to your roxygen block
devtools::document() # Update namespace
devtools::load_all() # Load updated packageTests fail but function works interactively
Problem: Test environment differs from interactive environment
Solution:
Check test data setup
Verify all required packages loaded in tests
Use
devtools::load_all()before interactive testing
“no visible binding for global variable”
Problem: Using NSE without proper imports
Solution: See package-imports.md for proper namespace usage
Performance Tips
Speed up test runs
# Run only one test file
devtools::test_active_file()
# Run only tests matching a pattern
devtools::test(filter = "your_function")Skip slow tests during development
test_that("slow integration test", {
skip_if_not(interactive(), "Slow test - run manually")
# Expensive test here
})Use testthat snapshots for complex output
test_that("complex output matches", {
expect_snapshot(your_function(data))
})Git Workflow (Source Development)
If you’re contributing to tidymodels packages (recipes, yardstick, etc.), you’ll also need basic git workflow.
Initial Setup
# Clone the repository
git clone https://github.com/tidymodels/recipes.git
cd recipes
# Create a feature branch
git checkout -b feature/add-step-nameDuring Development
# Your fast iteration cycle (unchanged)
devtools::document()
devtools::load_all()
devtools::test()Committing Changes
# Check what changed
git status
git diff
# Add your changes
git add R/step_name.R tests/testthat/test-step_name.R
# Commit with descriptive message
git commit -m "Add step_name() for [brief description]"
# Push to your fork
git push origin feature/add-step-nameBefore Submitting PR
- Run full check:
devtools::check() - Update
NEWS.mdwith your changes - Ensure all tests pass
- Push final commits
Common Git Commands
# See current branch
git branch
# Switch branches
git checkout main
# Update from upstream
git pull origin main
# View commit history
git log --onelineNote: This is a minimal git guide. For complete git documentation, see the official Git documentation or GitHub guides.
Next Steps
Learn testing patterns: package-testing-patterns.md
Set up proper documentation: package-roxygen-documentation.md
Follow best practices: package-best-practices.md