Question

Is there a simple workflow to write tests that store objects as .rds or .rda so that future runs of a test can compare the result of code execution vs. the stored object? This would make it easy to check that functions that return somewhat complex values are still behaving as they should.

For example, something like:

test_obj(res <- lm(y ~ x, data.frame(x=1:3, y=5:7)))

which, if *extdata/test_obj.res.rds* doesn't exist, would create it in *inst/extdata/test_obj.res.rds*, with res from above, but if it does exist, would identical/all.equal etc. the newly generated object with the one recovered from the rds.

I would find such tests super useful, and I am a bit surprised that RUnit/svUnit / testthat don't implement something of the sort (I'm hoping they do, and I just haven't found it).

testthat::make_expectation is close, but I'd prefer to have an automated store/retrieve rds rather than copy paste the text representation to a file, which I think is how you're supposed to use testthat::make_expectation (I guess I could pipe stdout() to a .R file, but even then there is a bit of automation that could facilitate the process).

Was it helpful?

Solution

It only took me three years, but I wrote unitizer to resolve this issue. It is a unit testing framework with an interactive UI that allows you to review test output and store it / reject it with a single keystroke. It also streamlines the update/test/debug cycle by showing you a proper diff of failing tests, and dropping you into those tests evaluation environments for debugging in the interactive UI.

For example, if we have a matrix rotation function (courtesy @MatthewLundberg) we want to test:

# mx-rotate.R

rotate <- function(x) t(apply(x, 2, rev))

And a script with some tests:

# mx-test.R

mx <- matrix(1:9, 3)
rotate(mx)
rotate(rotate(mx))
rotate(rotate(rotate(mx)))

Then:

library(unitizer)
unitize('mx-test.R')

Will kick-off an interactive session that will allow you to review the results of the three rotation calls and accept them as tests if they work as expected.

There is a screencast demo available.

OTHER TIPS

As of 2017, testthat has the feature expect_equal_to_reference, which does exactly what the question asks. I guess Hadley W. figured out a way.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top