Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrapping an expectation inside a function #48

Closed
jonclayden opened this issue Feb 10, 2020 · 7 comments
Closed

Wrapping an expectation inside a function #48

jonclayden opened this issue Feb 10, 2020 · 7 comments
Labels
enhancement New feature or request

Comments

@jonclayden
Copy link

jonclayden commented Feb 10, 2020

I have a package whose tests need updating, so I thought it would be good chance to try porting them over to tinytest and give it a test-drive. Everything looks great, except for the fact that this package generates some relatively complex outputs that I have previously tested with the expect_equal_to_reference expectation which I previously contributed to testthat. It doesn't exist in tinytest, but I assumed I could relatively easily get it working by wrapping existing expectations, viz.

expect_equal_to_reference <- function (expr, file, ...)
{
    if (file.exists(file))
        expect_equivalent(expr, readRDS(file), ...)
    else
        expect_null(saveRDS(expr, file))
}

and then sourcing the file containing this function at the top of each test file. But it doesn't do anything – these expectations seem to be silently ignored.

If I understand the discussion in issue #22 properly, this is probably because of how expectation functions are specially evaluated within the testing loop. But creating a formal extension and registering it with register_tinytest_extension feels like overkill since expect_equivalent basically already does the right thing. But perhaps I'm thinking about it the wrong way. Is there a way to get this sort of "semi-custom" expectation working, or should I approach it differently?

Thanks in advance. I really like tinytest's sleekness!

@markvanderloo markvanderloo added the enhancement New feature or request label Feb 18, 2020
@markvanderloo
Copy link
Owner

Hi Jon,

This is an interesting feature, and I think it has to be implemented in tinytest itself. I will do some tests and let you know.

@markvanderloo
Copy link
Owner

I've added it in 32571b7, version 1.1.0.3

It would be great if you could give it a whirl. Be aware that R CMD check may react differently from testthat, because testthat tests run in pkg/tests, which is a folder that does not get installed while tinytest tests run in pkg/inst/tinytest, and that folder does get installed. So you can't write in there according toR CMD check.

See ?expect_equal_to_reference

@jonclayden
Copy link
Author

Many thanks Mark – this looks good. I don't think the write restrictions will be a problem in practice (for me at least), because I would always regenerate the reference files before building the package, so they would already exist at the time of running R CMD check.

@markvanderloo
Copy link
Owner

Cheers Jon, I'm going to close this now. Feel free to reopen or submit another issue if you find any issues.

@mb706
Copy link

mb706 commented Jan 17, 2021

For anyone looking here because they want to do "Wrapping an expectation inside a function" and wondering if there is some easier way besides getting the function merged into tinytest: The way to do it is to

source("<HELPERFILE.R>", local = TRUE)

at the top of the test file.

(The fact that it doesn't work without local = TRUE, and that register_tinytest_extension is necessary otherwise, makes me wonder if tinytest is making things more complicated than necessary. Why not have the output() reference object be a global singleton that every expect_* call writes into, without the capture() wrapping?)

@MartinBeal
Copy link

MartinBeal commented Aug 6, 2021

For anyone looking here because they want to do "Wrapping an expectation inside a function" and wondering if there is some easier way besides getting the function merged into tinytest: The way to do it is to

source("<HELPERFILE.R>", local = TRUE)

at the top of the test file.

(The fact that it doesn't work without local = TRUE, and that register_tinytest_extension is necessary otherwise, makes me wonder if tinytest is making things more complicated than necessary. Why not have the output() reference object be a global singleton that every expect_* call writes into, without the capture() wrapping?)

Thanks @mb706. Indeed trying to use custom expectation functions for package testing.

Which is the appropriate folder for "<HELPERFILE.R>" ?

@jonclayden
Copy link
Author

@MartinBeal The working directory for package tests will generally be inst/tinytest, so I expect that would be the natural place for helper files. But if your expectation is quite specific to your package, the register_tinytest_extension() route is the officially supported one, and I've found it to be perfectly practical.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants