| Title: | A Simple Package for Testing R Packages |
|---|---|
| Description: | A minimal, dependency-free testing framework for R packages. Write tests as simple R expressions that return TRUE, using assert() for assertions (with informative error messages on failure), has_error() / has_warning() / has_message() for testing conditions, and test_pkg() to run all tests with full access to internal (non-exported) package functions. Snapshot testing via Markdown files is also supported. |
| Authors: | Yihui Xie [aut, cre] (ORCID: <https://orcid.org/0000-0003-0645-5666>, URL: https://yihui.org), Tomas Kalibera [ctb], Steven Mortimer [ctb] |
| Maintainer: | Yihui Xie <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 1.0.1 |
| Built: | 2026-05-23 00:04:37 UTC |
| Source: | https://github.com/yihui/testit |
Test that one or more conditions are TRUE. If any condition fails, an error
is raised with the fact message, making it easy to identify which test
failed and why. This is the primary function for writing tests with
testit.
The infix operator %==% is a shortcut for identical() that
provides helpful diagnostics on failure. x %==% y returns TRUE if x
and y are identical, and FALSE otherwise. When used inside assert(),
a failing %==% comparison will display both values via str() so you can
see exactly what differed.
assert(fact, ...) x %==% yassert(fact, ...) x %==% y
fact |
A character string describing what is being tested. This message
is shown when an assertion fails, so make it descriptive (e.g., |
... |
An R expression wrapped in |
x, y
|
Two R objects to be compared for identity. |
The recommended usage is to pass a single expression wrapped in {} as the
second argument. Inside {}, any statement-level sub-expression wrapped
in parentheses () is treated as a test condition – its value is checked
and must be TRUE. Parentheses used for grouping within a larger expression
(e.g., (a + b) * c) are not checked. Sub-expressions without parentheses
are ordinary R code (e.g., variable assignments or setup steps) and are never
checked.
() tests work inside if, for, while, and repeat bodies. Internally,
assert() walks the expression tree and transforms statement-level () into
checks before evaluating the entire block in one frame (so on.exit() works
as expected).
Invisible NULL if all conditions pass. If any condition fails, an
error is signaled that includes the fact message and the expression that
failed. For %==%, TRUE or FALSE.
Key differences from stopifnot():
assert() shows your custom fact message on failure, making errors
easier to diagnose.
logical(0) (empty logical) is treated as a failure, not a pass.
All conditions are evaluated even if earlier ones fail; all failures are reported together in a single error message.
library(testit) assert('T is bad for TRUE, and so is F for FALSE', { T = FALSE; F = TRUE (T != TRUE) # note the parentheses (F != FALSE) }) assert('A Poisson random number is non-negative', { x = rpois(1, 10) (x >= 0) (x > -1) }) # () works inside control structures too assert('conditional test', { if (requireNamespace('base', quietly = TRUE)) (1 + 1 == 2) })library(testit) assert('T is bad for TRUE, and so is F for FALSE', { T = FALSE; F = TRUE (T != TRUE) # note the parentheses (F != FALSE) }) assert('A Poisson random number is non-negative', { x = rpois(1, 10) (x >= 0) (x > -1) }) # () works inside control structures too assert('conditional test', { if (requireNamespace('base', quietly = TRUE)) (1 + 1 == 2) })
Check if evaluating an expression produces a message, warning, or error.
These functions are designed to be used inside assert() to verify that code
signals the expected conditions. Optionally, you can match against the
condition's text to ensure the right message/warning/error was signaled.
has_message(expr, message = NULL, ...) has_warning(expr, message = NULL, ...) has_error(expr, message = NULL, ...)has_message(expr, message = NULL, ...) has_warning(expr, message = NULL, ...) has_error(expr, message = NULL, ...)
expr |
An R expression to evaluate. |
message |
An optional string to match against the condition text. Uses
fixed (literal) matching by default. If provided, the function returns
|
... |
Additional arguments passed to |
TRUE if the condition was signaled (and the message matched, if
provided), FALSE otherwise.
has_message(message('hello')) has_message(1 + 1) has_message(message('hello world'), 'hello') has_warning(1 + 1) has_warning(1:2 + 1:3) has_warning(1:2 + 1:3, 'longer object length') has_error(2 - 3) has_error(1 + 'a') has_error(stop('err'), 'err') has_error(stop('error occurred'), 'error')has_message(message('hello')) has_message(1 + 1) has_message(message('hello world'), 'hello') has_warning(1 + 1) has_warning(1:2 + 1:3) has_warning(1:2 + 1:3, 'longer object length') has_error(2 - 3) has_error(1 + 'a') has_error(stop('err'), 'err') has_error(stop('error occurred'), 'error')
Discover and execute test files (test-*.R and test-*.md) for a package.
Tests are run inside the package namespace, so you can call internal
(non-exported) functions directly without the ::: operator.
test_pkg(package = pkg_name(), dir = NULL, filter = NULL, update = NA)test_pkg(package = pkg_name(), dir = NULL, filter = NULL, update = NA)
package |
The package name. By default, it is detected from the
|
dir |
The directory containing test files. If |
filter |
An optional regular expression to select a subset of test
files. Only files whose names match the pattern will be run. For example,
|
update |
Controls snapshot file behavior:
|
Test files are looked up in the testit/ or tests/testit/ directory by
default. Files must be named test-*.R for regular tests or test-*.md for
snapshot tests. Other files in the directory are ignored (but you can
source() them from your tests if needed).
Helper files named helper*.R (e.g., helper.R, helper-utils.R) are
sourced before any test file runs. Objects defined in helpers are available
to all tests.
Each test file runs in a clean environment (previous test objects are removed), and the working directory is set to the directory containing the test file.
See https://pkg.yihui.org/testit/#sec:snapshot-testing for more details about snapshot testing.
Invisible NULL. If any tests fail, a single error is thrown at the
end with all failure messages combined.
You must call library(testit) before test_pkg(). Test scripts use
assert() and other testit functions without the testit:: prefix, so
the package needs to be on the search path. Without library(testit), you
will get "could not find function" errors.
All test scripts must be encoded in UTF-8 if they contain multibyte characters.
When filter or update are not explicitly provided, test_pkg() checks
commandArgs(TRUE) for command-line arguments: --filter=PATTERN sets the
filter, and --update sets update = TRUE. This allows you to pass these
options via Rscript tests/*.R --filter=PATTERN --update without modifying
individual test_pkg() calls.
## Not run: library(testit) test_pkg('testit') ## End(Not run)## Not run: library(testit) test_pkg('testit') ## End(Not run)