Part 1
Good habit: each logical unit of work gets its own branch and PR.
This creates:
tests/testthat/ - directory for test filestests/testthat.R - script to run all teststestthat to Suggests in DESCRIPTIONTests for R/{name}.R go in tests/testthat/test-{name}.R
Creates tests/testthat/test-cpue.R linked to R/cpue.R
test_that() block = one behaviourexpect_*() calls per block are fineexpect_equal(): exact equality (with a tolerance for numeric)expect_identical(): exact equalityexpect_lt(), expect_gt(), etc.: comparisonsexpect_length(): checks length of outputexpect_type(): checks the type of the outputexpect_true(), expect_false(): checks if condition is TRUE/FALSEexpect_message(): checks if code produces a messageSpecific expectations give better failure messages - you see what failed, not just that it failed.
Edge cases often reveal assumptions baked into your code.
Tests that share setup code can become repetitive.
What if the setup logic is complex or used in many tests?
Solution: helper files and setup files
Creates tests/testthat/helper.R - loaded before every test run.
Does not contain test code itself, but defines functions that can be used in tests.
setup.R runs once before all tests - good for expensive fixtures.
verbose parameterUpdate R/cpue.R:
expect_messageSnapshot testing captures output and compares against a saved reference.
expect_snapshot() over expect_error()/expect_warning() because it captures the full output for reviewvdiffr package)testthat writes the snapshot to tests/testthat/_snaps/:
# cpue errors when input is not numeric
Code
cpue("five", 10)
Error
non-numeric argument to binary operator
Commit the snapshot file - it becomes your reference.
After modifying output, tests fail. Review and accept:
We’ll dive deeper into snapshot workflows in Part 2.
Commit your snapshot tests - including the _snaps/ files testthat created.
| What | How | Shortcut |
|---|---|---|
| Single test | Ctrl+Enter on test_that() block |
- |
| Active file | devtools::test_active_file() |
Ctrl/Cmd+T |
| Whole package | devtools::test() |
Shift+Ctrl/Cmd+T |
Add tests for biomass_index(). Aim for at least one snapshot test.
Things to test:
expect_snapshot(error = TRUE))test_that("biomass_index calculates correctly", {
expect_equal(biomass_index(cpue = 10, area_swept = 5), 50)
expect_equal(biomass_index(cpue = 20, area_swept = 2.5), 50)
})
test_that("biomass_index handles vectors", {
expect_equal(
biomass_index(c(10, 20, 30), c(5, 5, 5)),
c(50, 100, 150)
)
})
test_that("biomass_index throws error on invalid input", {
expect_snapshot(biomass_index("ten", 5), error = TRUE)
expect_snapshot(biomass_index(10, "five"), error = TRUE)
})Commit your biomass_index() tests and any new snapshot files.
Once all tests pass and check() is clean: