[Rd] Testthat and global environments in R packages on CRAN

Duncan Murdoch murdoch.duncan at gmail.com
Sun Feb 8 21:46:32 CET 2015

On 08/02/2015 12:16 PM, Måns Magnusson wrote:
> Hi!
> The problem is that the test environment inherits from the global
> environment.
> See https://github.com/hadley/testthat/blob/master/R/test-files.r
> The students labs are simply an R script file. Say that they have an
> assignment to calculate sqrt(2) and store it in variable a. In the same
> session they should be able to test the script file when they are done
> (using a function mark_my_file() in the package). This function will
> call the testthat tests. 
> Say that I have two unit tests. One tests if an object called 'a' exists
> in the file and the second one tests if 'a' is sqrt(2) and return
> messages to the students pointing them in the right direction (ie 'a' is
> missing or is wrong).
> The problem is the if the student have an other object 'a' in the global
> environment but do not create 'a' in their R script file. In this case
> testthat test will follow the search path and find the object in the
> global environment and return the wrong (or none) error message due to
> the global environment.
> The only way around this problem is to temporarily store the global
> environment, clean it and run the tests, and the reload the old global
> environment. But this solution will not be publishable on CRAN.
> I hope this can clarify the problem.

But you don't need to use test_env():  it's the default for a number of
other functions, but your function could replace them with something else.

For example, if you want an environment that is like the global
environment but empty, simply create a new one, whose parent is the
parent of globalenv().  For example:

fakeglobal <- new.env(parent = parent.env(globalenv()))

source("studentfile.R", local = fakeglobal)

test_file("yourtests.R", local = fakeglobal)

If the student code (or yours) needs to load packages, this code won't
see them, but there are workarounds for that too.  The main thing is
that the student results will be in fakeglobal, and nothing else will be.

Duncan Murdoch

> Kind regards
> Måns
> Skickat från min iPhone
> 8 feb 2015 kl. 16:46 skrev Duncan Murdoch <murdoch.duncan at gmail.com
> <mailto:murdoch.duncan at gmail.com>>:
>> On 08/02/2015 8:22 AM, Måns Magnusson wrote:
>>> Hi!
>>> Im currently developing an R package to automatically give students
>>> feedback on programming assignments in R. I use the testthat package
>>> as an
>>> engine for the unit testing and do a wrapper to make the automatic
>>> marking
>>> easy for the students.
>>> One function (called mark_my_file() ) will mark the students lab file
>>> using
>>> testthat tests and a new (simple) reporter. The problem is that I need to
>>> do the marking of the lab with an empty global environment (due to the
>>> testthat package).
>>> So my first thought was to:
>>> 1) store the global environement in the temporary directory as an
>>> .Rdata-file
>>> 2) clean the global environment
>>> 3) run the tests
>>> 4) clean the global environment (from the student lab file)
>>> 5) reload the old global environment
>>> But the problem is that it is not possible to publish packages on
>>> CRAN that
>>> modifies the global environment.
>>> Is there anyone that have any solutions/ideas to this problem?
>>> The package can be found here:
>>> https://github.com/MansMeg/markmyassignment
>> I don't think that testthat requires you to use the global environment.
>> Could you give some example code to show where you think you need it?
>> Someone could probably come up with a different formulation.
>> Duncan Murdoch

More information about the R-devel mailing list