R/docs.R

#' Write testthat tests for your examples, using roxygen tags
#'
#' The doctest package lets you test the code in your "Examples"
#' section in .Rd files. It uses the roxygen2 and testthat packages.
#' For more information, see [@doctest] and [@expect].
#'
#' ```{r child = "man/rmd/example.Rmd"}
#' ```
#'
#' ```{r child = "man/rmd/usage.Rmd"}
#' ```
#'
#' Doctest is `r lifecycle::badge("experimental")`.
#'
"_PACKAGE"

## usethis namespace: start
## usethis namespace: end
NULL


#' Start a doctest
#'
#' `@doctest` starts a doctest: a code example that also contains one or more
#' [testthat][testthat::testthat-package] expectations.
#'
#' @details
#' Use `@doctest` where you would usually use `@examples`. Then add
#' [@expect] and [@expectRaw] tags beneath it to create expectations.
#'
#' By default, a test labelled "Example: <object name>" is created. You
#' can put a different label after `@doctest`:
#'
#'     #' @doctest Positive numbers
#'     #'
#'     #' x <- 1
#'     #' @expect equal(x)
#'     #' abs(x)
#'     #'
#'     #' @doctest Negative numbers
#'     #' x <- -1
#'     #' @expect equal(-x)
#'     #' abs(x)
#'
#' You can have more than one `@doctest` tag in a roxygen block. Each doctest
#' will create a new test, but they will all be merged into a single Rd example.
#' Each doctest must contain an independent unit of code. For example, this
#' won't work:
#'
#'     #' @doctest Test x
#'     #' @expect equal(2)
#'     #' x <- 1 + 1
#'     #'
#'     #' @doctest Keep testing x
#'     #' @expect equal(4)
#'     #' x^2
#'     #' # Test will error, because `x` has not been defined here
#'
#' A test will only be written if the `@doctest` section has at least one
#' [@expect] or [@expectRaw] in it. This lets you change `@examples` to
#' `@doctest` in your code, without generating unexpected tests.
#'
#' @name doctest-tag
#' @aliases @doctest
NULL


#' Create an expectation
#'
#' `@expect` creates an expectation for your example code.
#'
#' @details
#' Use `@expect` to create a [testthat][testthat::testthat-package] expectation.
#'
#'     #' @doctest
#'     #'
#'     #' @expect equals(4)
#'     #' 2 + 2
#'     #'
#'     #' f <- function () warning("Watch out")
#'     #' @expect warning()
#'     #' f()
#'
#' The next expression will be inserted as the first
#' argument to the `expect_*` call.
#'
#' Don't include the `expect_` prefix.
#'
#' If you want to include the expression in a different
#' place or places, use a dot `.`:
#'
#'     @expect equals(., rev(.))
#'     c("T", "E", "N", "E", "T")
#'
#' The `@expect` tag and code must fit on a single line.
#'
#' @name expect-tag
#' @aliases @expect
#' @family expectations
NULL


#' Create a snapshot test
#'
#' `@snap` creates a
#' [snapshot test](https://testthat.r-lib.org/articles/snapshotting.html)
#' for your example. It is shorthand for `@expect snapshot()`.
#'
#' @details
#' Often, examples show complex output to the user. If this output changes,
#' you want to check that it still "looks right". Snapshot tests help by
#' failing when the output changes, and allowing you to review and approve
#' the new output.
#'
#'     #' @doctest
#'     #'
#'     #' @snap
#'     #' summary(lm(Petal.Width ~ Species, data = iris))
#'
#' @name snap-tag
#' @aliases @snap
#' @family expectations
NULL


#' Add a line of code to the test
#'
#' `@testRaw` adds an arbitrary line of code to your test, without including it
#' in the .Rd example.
#'
#' @details
#' `@testRaw` adds an arbitrary line of code to your test:
#'
#'     #' @doctest
#'     #' @testRaw skip_on_cran("Takes too long")
#'     #' @expect equal(6765)
#'     #' fibonacci(20)
#'
#' Unless your doctest has at least one [@expect] or [@expectRaw] tag, no test
#' will be created. So use those tags, not `@testRaw`, to add expectations.
#'
#' Remember that the main purpose of examples is to document your package for
#' your users. If your code is getting too different from your example, consider
#' splitting it off into a proper test file. To do this, rename the
#' file in `tests/testthat`, and deleting the `Generated by doctest` comment.
#'
#' @name testRaw-tag
#' @aliases @testRaw
NULL


#' Create an expectation as-is
#'
#' `@expectRaw` creates an expectation for your example code, without adding
#' the next expression as the subject.
#'
#' @details
#' `@expectRaw` creates a [testthat][testthat::testthat-package] expectation.
#' Unlike [@expect], it doesn't insert the subsequent expression as the first
#' argument.
#'
#'     #' @doctest
#'     #'
#'     #' x <- 2 + 2
#'     #' @expectRaw equals(x, 4)
#'     #'
#'     #' f <- function () warning("Watch out")
#'     #' @expectRaw warning(f())
#'
#' Don't include the `expect_` prefix.
#'
#' The `@expectRaw` tag and code must fit on a single line.
#'
#' @name expectRaw-tag
#' @aliases @expectRaw
#' @family expectations
NULL


#' Exclude example code from a test
#'
#' `@omit` excludes example code from a test until the next tag.
#' Use `@resume` to restart including code without creating an expectation.
#'
#' @details
#' Use `@omit` to avoid redundant or noisy code:
#'
#'     #' @doctest
#'     #'
#'     #' @expect equal(0)
#'     #' sin(0)
#'     #'
#'     #' @omit
#'     #' curve(sin(x), 0, 2 * pi)
#'     #'
#'     #' @expect equal(1)
#'     #' cos(0)
#'
#' `@omit` is separate from `\donttest` and `\dontrun` tags in Rd files. This
#' allows you to test code that would cause an error if run by R CMD CHECK. If
#' you also want R CMD CHECK to skip your code, you should use `\donttest{}`
#' separately (see
#' [writing R extensions](https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Writing-R-documentation-files)).
#'
#' Remember that the main purpose of examples is to document your package for
#' your users. If your code is getting too different from your example, consider
#' splitting it off into a proper test file. You can do this by renaming it and
#' deleting the `Generated by doctest` comment.
#'
#' @name omit-tag
#' @aliases resume-tag @omit @resume
NULL


#' Add an example from a file
#'
#' `@doctestExample path/to/file.R` is a drop-in replacement for
#' `@example path/to/file.R`. It doesn't add the contents of `file.R` to
#' the test.
#'
#' @details
#' If you have complex examples you may want to store them separately.
#' Roxygen2 uses the `@example` tag for this. `@doctestExample` does the
#' same: it adds the contents of its file to the resulting example.
#' Suppose `man/R/example-code.R` contains the line:
#'
#'     2 + 2
#'
#' Then the following roxygen:
#'
#'     #' @doctest
#'     #'
#'     #' @expect equal(2)
#'     #' 1 + 1
#'     #' @doctestExample man/R/example-code.R
#'
#' will generate an example like:
#'
#'     1 + 1
#'     2 + 2
#'
#' At present, `@doctestExample` doesn't add any code to the tests.
#'
#' `@doctestExample` was added after doctest 0.2.0.
#'
#' @name doctestExample-tag
#' @aliases @doctestExample
NULL

Try the doctest package in your browser

Any scripts or data that you put into this service are public.

doctest documentation built on May 29, 2024, 7:09 a.m.