courieR is transparent about how it is tested. This document describes the test suite, how to run it on your machine (or as an automated agent), and the current verification status across platforms.
The package is fully AI-implemented and human-directed. Both human and agent testers are listed in the status table below.
Tests live in tests/testthat/ and are organised into
three layers:
| Layer | Files | What it covers |
|---|---|---|
| Unit | test-inventory.R, test-manifest.R,
test-ship.R, test-copy-packages.R,
test-estimate.R, and ~12 more |
Pure R logic — comparison, plan building, log parsing, route filtering, rate calibration |
| Integration | test-find_routes.R, test-migrate.R,
test-wrap.R |
Spawns real R subprocesses; needs at least one R installation;
guarded with skip_on_cran() |
| End-to-end (E2E) | test-e2e-ship.R, test-app-refresh.R |
Drives the full Shiny dashboard in a headless Chrome browser;
requires two R installations, a Chrome binary, and
COURIER_E2E=true |
# From an R session in the package root
devtools::test()
# Or from the shell
R CMD check --no-manual .All unit tests and CRAN-safe integration tests run without any
environment variables. Tests that spawn subprocesses or modify libraries
are guarded with skip_on_cran() and will run locally but
not on CRAN.
The E2E tests drive the full dashboard UI with a real Chrome browser
through shinytest2 and chromote. They
require:
shinytest2 and chromote R packagesR CMD INSTALL .)# 1. Install working-tree version (required — app subprocess does library(courieR))
R CMD INSTALL .
# 2. Set environment variables
export COURIER_E2E=true
export COURIER_E2E_SRC=/path/to/source/Rscript # e.g. /opt/R/4.4.3/bin/Rscript
export COURIER_E2E_TGT=/path/to/target/Rscript # e.g. /opt/R/4.5.2/bin/Rscript
export COURIER_E2E_TGT_LIB=/path/to/target/library # writable target library dir
# 3. Run
Rscript -e "testthat::test_file('tests/testthat/test-e2e-ship.R')"The E2E test:
broman), selects offline mode, ships itmanifest() in a clean
subprocess) that the package was installed into the target library with
a valid layout and is loadable from target RRun hub() and work through the checklist below. The E2E
test covers the same paths automatically, but manual testing catches
visual regressions and UX issues that browser automation misses.
library(courieR)
# Startup message shows version, hub(), ?ship, and the vignette link
report_issue("test error message")
# Should open a pre-filled GitHub issue in the browser
find_routes()
# Should find all R installations on the machine
vignette("get-started", package = "courieR")
# Should open the HTML user guideLast updated: 2026-06-13.
| Platform | Tester | Unit tests | Integration | E2E browser | Manual UI |
|---|---|---|---|---|---|
| Windows 11 (OneDrive + Defender) | Human — Lennon Li | ✅ | ✅ | ⬜ | ✅ |
| Linux — WSL2 Ubuntu 24.04, R 4.6.0 | Agent — Claude Code (Ming) | ✅ | ✅ | ✅ | ✅ partial |
| macOS — Mac mini, Apple Silicon, R 4.6.0 | Agent — Claude Code | ✅ | ✅ | ⬜ | ⬜ |
Legend: ✅ pass · ❌ fail · ⚠️ pass with caveats · ⬜ not yet run
find_routes() timeout from 3 s to 30 s. Cold-started R on
OneDrive-synced drives regularly exceeded 3 s, causing installations to
flicker in and out between scans.chromote. These
have not been run on Windows;
skip_if_not_installed("chromote") protects the test
suite.R CMD check --no-manual passes (inconsolata.sty is
absent; --no-manual skips the PDF reference manual)./usr/bin/R).
Per-version libraries live under
~/R/x86_64-pc-linux-gnu-library/<version>/..copy_plan() nesting bug fix
end-to-end: package installed with a valid layout and loadable from
target R.R CMD check --as-cran --no-manual produces 0 errors, 0
warnings, 0 notes.Results — 2026-06-13, Mac mini (Apple Silicon), R 4.6.0
devtools::test(): FAIL 0 | WARN 0 | SKIP 16 | PASS
180
devtools::check(manual = FALSE, vignettes = FALSE): 0
errors | 0 warnings | 1 note
The 1 note is the ::: call to
.build_issue_url() inside
mod_error_reporter.R. This is intentional — the function is
package-internal and called only from the embedded Shiny app, not from
user code.
macOS-specific quirks discovered
/var → /private/var
symlink. withr::local_tempdir() returns paths
under /var/folders/..., but find_routes()
normalises paths via fs::path_real(), resolving them to
/private/var/folders/.... The test
"find_routes detects installs whose probe takes longer than 3s"
was failing because fake %in% res$rscript_path compared the
unresolved path against the resolved one. Fixed by wrapping
fake in fs::path_real() in the test
assertion.
CRAN framework R_HOME overwrite.
The official CRAN macOS framework wrapper scripts
(Resources/bin/R) hardcode R_HOME_DIR to the
symlink /Library/Frameworks/R.framework/Resources, which
always points to the current active version. Running any
version-specific wrapper therefore redirects R_HOME to
whichever version is set as Current. Multi-version
integration tests must use rig-managed binaries or the
exec/R binary directly; the standard framework wrappers are
unreliable for version isolation. The test suite skips multi-install
integration tests automatically when only one distinct library is
detected.
For future macOS agent runs
Follow the steps below in order.
Environment setup
# Check what R installations are present
ls /Library/Frameworks/R.framework/Versions/
ls ~/Library/Frameworks/R.framework/Versions/ # user-local installs
ls /opt/homebrew/bin/R* 2>/dev/null # Homebrew
~/.local/share/rig/bin/rig list 2>/dev/null # rig-managed
# Verify at least two R installations exist. If only one is present,
# install a second via rig:
curl -Ls https://rig.r-lib.org/macos.sh | bash
rig install 4.4 # example second versionInstall Chrome if not present (needed for E2E)
Run unit + integration tests
Expected: 0 failures. Tests that require two R installations skip automatically if only one is found.
Run E2E tests
R CMD INSTALL .
export COURIER_E2E=true
# Set to actual paths from `rig list` output
export COURIER_E2E_SRC=/Library/Frameworks/R.framework/Versions/4.4/Resources/bin/Rscript
export COURIER_E2E_TGT=/Library/Frameworks/R.framework/Versions/4.5/Resources/bin/Rscript
export COURIER_E2E_TGT_LIB=~/Library/R/x86_64/4.5/library # adjust arch/version
Rscript -e "testthat::test_file('tests/testthat/test-e2e-ship.R')"Run manual checklist
Work through the manual checklist above. Pay particular attention to
find_routes() detecting Homebrew and framework R separately
— macOS has the most detection sources of any platform.
Report results
Update this table in a PR or open an issue with the
testing label. Include:
tests/testthat/test-<topic>.Rskip_on_cran() for anything that spawns a
subprocess or modifies a librarytest-e2e-ship.R (or a new
test-e2e-<feature>.R) and must check
Sys.getenv("COURIER_E2E") == "true" before runningR CMD check --no-manual must stay at 0 errors / 0
warnings before merging