我正在尝试为 R 中的包函数编写测试。
\n\n假设我们有一个函数,只需x使用以下命令将字符串写入磁盘writeLines():
exporting_function <- function(x, file) {\n\n writeLines(x, con = file)\n\n invisible(NULL)\n}\nRun Code Online (Sandbox Code Playgroud)\n\n测试它的一种方法是检查文件是否存在。通常,它一开始不应该存在,但在运行导出函数之后它应该存在。另外,您可能想测试文件大小是否大于 0:
\n\nlibrary(testthat)\n\ntest_that("file is written to disk", {\n file = \'output.txt\'\n expect_false(file.exists(file))\n\n exporting_function("This is a test",\n file = file)\n\n\n expect_true(file.exists(file))\n\n expect_gt(file.info(\'output.txt\')$size, 0)\n})\nRun Code Online (Sandbox Code Playgroud)\n\n这是一个很好的测试方法吗?在CRAN 存储库政策中,它指出Packages should not write in the user\xe2\x80\x99s home filespace (including clipboards), nor anywhere else on the file system apart from the R session\xe2\x80\x99s temporary directory. 这个测试会违反这个限制吗?
有一个expect_output_file函数。从文档和示例中,我不确定这是否是测试该功能的更合适的期望。它需要一个object参数,该参数应该是 …
我正在使用 GitHub Actions 进行 R CMD 检查(请参阅https://github.com/r-lib/actions)。
我想snapshot_file在testthat这种脚本中使用:
save_png <- function(code, width = 1000, height = 600) {
path <- tempfile(fileext = ".png")
grDevices::png(path, width = width, height = height)
on.exit(dev.off())
code
path
}
set.seed(123)
df <- data.frame(y=rnorm(20),x=rnorm(20))
test_that("graphs are correct", {
expect_snapshot_file(path = save_png(plot(df$y,df$x)), name = "plot1.png")
}
Run Code Online (Sandbox Code Playgroud)
目前,错误将始终是:
Adding new file snapshot "_snaps/gets-test1-example/plot1.png"。或者,如果我上传在我的笔记本电脑上生成的绘图,我会收到一个错误,它们是不同的(非常轻微)......
因为我知道快照测试很脆弱,所以我想到了两个选择:
我想运行包内部测试testthat::test_package('httr')在包的特定版本上运行包内部测试。有没有办法安装具有特定版本的 R 包(例如来自 CRAN)及其测试?
我知道有
install.packages("httr", INSTALL_opts = "--install-tests")
安装给定软件包的测试(没有任何选项来指定特定的软件包版本)。
并且有
devtools::install_version("httr", version = "1.4.1")或renv::install("httr@1.4.1")
要安装软件包的特定版本(无法指定例如 INSTALL_opts)。
我没有看到任何方法可以将软件包版本的规范与--install-tests选项结合起来。任何帮助,将不胜感激!
注意:包“httr”在这里仅用作占位符。
R 的testthat包有许多用于运行测试的函数:https://testthat.r-lib.org/reference/index.html#run-tests。但是,您可以过滤测试的最粗略级别似乎是在文件级别,因为有一个test_file()函数没有任何过滤参数,并且test_dir()有一个过滤参数,但它仅用于按文件名过滤。
然而,我经常只想运行一个测试,因为它是新的,或者因为我知道它与我刚刚所做的更改相关。
有没有办法在 R 控制台或 RStudio 中运行单个testthat测试?如果没有,是否有其他推荐的解决方案来解决这个问题,例如将每个测试放在它自己的文件中(尽管这看起来很痛苦)?
How can I automatically generate test cases in RUnit?
For example, let's say I have a simple sum() function:
sum <- function(x, y) {
return (x + y)
}
Run Code Online (Sandbox Code Playgroud)
I would like to test this function on a series of different test cases:
test_cases <- c( c(2, 2, 4),
c(3, 3, 6),
c(0, 0, 0),
c(-1, 2, 1)
)
Run Code Online (Sandbox Code Playgroud)
The first two elements of each vector are x and y, and the third is the expected output of the sum(x,y) …
我正在尝试在我的软件包中添加一些测试,以确保在进行更改时保持原样.我这样做有些困难.
我想测试我的包的主要功能,可以粗略地描述为插补方法.因此,如果我给第二列有一些的n x 2矩阵,它应该返回第一列中的第一列并且是相同的(因为它完全被观察到),第二列应该被估算,因此第二列中没有.YNAZYZNAZ
显然,该函数还有其他几个输入,但我测试的主要结构是
context("Test output")
test_that("First column equal", {
set.seed(100)
Y <- matrix(rnorm(200), 100, 2)
Y[seq(1, 100, by = 3), 2] <- NA
out <- my_fun(Y)
expect_equal(Y[, 1], out[, 1])
})
Run Code Online (Sandbox Code Playgroud)
我的问题是这不起作用.它在我运行时有效devtools::test(),但在运行时无效devtools::check().我尝试使用expect_equal_to_reference()(因为我真正想要测试的是比这个例子更大,更强制),但它也会抛出错误,尽管在控制台中运行代码并与保存的.rds文件进行比较表明它们是相同的.
我发现哈德利的这句话(在测试中):
有时,当使用devtools :: test()以交互方式运行时,测试可能会出现问题,但在进行R CMD检查时会失败.这通常表明您对测试环境做出了错误的假设,而且通常很难弄清楚.
这不是好兆头,但我该怎么办?有任何想法吗?
这是我得到的错误(test_file是包含上述代码的文件的名称):
checking tests ...
** running tests for arch 'i386' ... ERROR
Running the tests in 'tests/testthat.R' failed.
Last …Run Code Online (Sandbox Code Playgroud) 我的包中的这个测试与devtools::test(). 在线 Travis 构建也进展顺利。
test_that("Package style", {
lintr::expect_lint_free()
})
Run Code Online (Sandbox Code Playgroud)
然而,devtools::check()它失败了。错误信息是
invalid 'path' argument
Backtrace:
1. lintr::expect_lint_free()
2. lintr::lint_package(...)
3. base::normalizePath(path, mustWork = FALSE)
4. base::path.expand(path)
Run Code Online (Sandbox Code Playgroud)
我在 Windows 上运行 R 版本 3.6.3 (2020-02-29)、testthat 2.3.2 和 lintr 2.0.1。
我认为问题是 lintr 不知道要 lintr 哪个文件。
有人可以向我指出这个问题的解决方案是什么吗?
(这个问题也是在Github上问这里)
将 R 升级到 4.0.2 后,测试似乎失败了,因为sortin的算法发生了testthat变化。以下内容显示,这base::sort()和browser()是R中4.0.2罚款(见这个问题,为什么增加这个检查。):
y <- c("Schaffhausen", "Schwyz", "Seespital", "SRZ")
print(sort(y))
# [1] "Schaffhausen" "Schwyz" "Seespital" "SRZ"
browser()
print(sort(y))
# [1] "Schaffhausen" "Schwyz" "Seespital" "SRZ"
Run Code Online (Sandbox Code Playgroud)
但是如果你创建一个包,调用它testsort,使用添加测试环境usethis::use_testthat()并在其中添加一个文件“test-sort.R”/testsort/tests/testthat/
test_that("test sort", {
xx <- c("Schaffhausen", "Schwyz", "Seespital", "SRZ")
print("")
# bowser()
print(sort(xx))
expect_equal(sort(xx), c("Schaffhausen", "Schwyz", "Seespital", "SRZ"))
})
Run Code Online (Sandbox Code Playgroud)
你得到
==> devtools::test()
Loading testsort
Testing testsort
v | OK F W S | Context
/ …Run Code Online (Sandbox Code Playgroud) 我正在尝试为我的闪亮应用程序开发单元测试,该应用程序是使用golem框架和shinyv1.5.0 制作的。
Golem 附带了一个推荐的测试文件,其中涵盖了非常基本的 UI 测试。然而,我更关心测试所有模块的服务器端。因此,就像您对常规 R 包中的每个函数进行测试一样,我想在我闪亮的应用程序中测试每个模块。
\n我知道有一个testModule功能正在开发中,但它没有包含在最新的闪亮 CRAN 版本中(这正是我正在使用的版本)。只有一个testServer函数,但我发现的所有示例似乎都在测试文件中定义了模块服务器端。当模块是包的一部分时,我找不到模块测试的示例。
所以我想做的基本上是一个位于内部的测试tests/testthat/test-my_module.R,看起来像这样:
\ntest_that("The module receives its input", {\n shiny::testServer(\n app = mypackage::my_module_server,\n args = list(),\n session = MockShinySession$new(), {\n session$setInputs(some_input = 100)\n expect_equal(output$some_output, 50)\n })\n})\nRun Code Online (Sandbox Code Playgroud)\n但是,这会引发错误:
\nError in UseMethod("as.shiny.appobj", x) : \n m\xc3\xa9todo n\xc3\xa3o aplic\xc3\xa1vel para 'as.shiny.appobj' aplicado a um objeto de classe "function"\nRun Code Online (Sandbox Code Playgroud)\n这基本上表明指定的方法在应用于函数类对象时不起作用。
\n我在这里错过了什么吗?
\n希望能讨论一下在将闪亮的应用程序开发为包时如何进行测试。
\n根据我的理解,放在里面的任何东西都test_that()应该被分隔开,这意味着如果我在 中加载一个包test_that(),它的函数和方法不应该在其他test_that()调用中可用。
在下面的示例中,有 3 个(空)测试:
\nas.matrix.get_predicted在命名空间中不可用。insight在第二个中,我加载提供了方法的包as.matrix.get_predicted。根据我的理解,此方法应该仅在本次调用中可用test_that()。library(testthat)\n\ntest_that("foo 1", {\n print("as.matrix.get_predicted" %in% methods(as.matrix))\n})\n#> [1] FALSE\n#> \xe2\x94\x80\xe2\x94\x80 Skip (???): foo 1 \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n#> Reason: empty test\n\ntest_that("foo 2", {\n invisible(insight::get_parameters)\n})\n#> \xe2\x94\x80\xe2\x94\x80 Skip (???): foo 2 \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n#> Reason: empty test\n\ntest_that("foo 3", {\n print("as.matrix.get_predicted" %in% methods(as.matrix))\n})\n#> [1] TRUE\n#> \xe2\x94\x80\xe2\x94\x80 Skip (???): foo 3 \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n#> Reason: empty test\nRun Code Online (Sandbox Code Playgroud)\n这是为什么?有一些解决方法吗?
\n编辑:我正在寻找特定于 的解决方案 …