Hello, I'm writing unit tests using testthat for a package that we want to submit to CRAN. Because of some aspect of how testthat works (which is beyond my ken), I have only been able to get my tests to work by using global assignment (<<-) to create some objects on which the tests are then run. However, per CRAN policy: "Packages should not modify the global environment (user?s workspace)." Does anyone know whether this policy applies to all code within the package, including unit tests? Or does it apply just to the code and functions in /R? Or to all code that is executed as part of checking the package (i.e., code that is never run can use <<-)? James
[R-pkg-devel] Is using global assignment in package tests allowed?
18 messages · Jeff Newmiller, Ivan Krylov, James Pustejovsky +5 more
I don't know the answer to your question, but "beyond my ken" doesn't sound like a very convincing reason. Mucking with any environment that isn't yours is asking for trouble... the behavior you depend on today may come into conflict with the code you are coordinating with when you least expect it. Is your code in a public version control repo?
On January 27, 2022 6:55:49 AM PST, James Pustejovsky <jepusto at gmail.com> wrote:
Hello, I'm writing unit tests using testthat for a package that we want to submit to CRAN. Because of some aspect of how testthat works (which is beyond my ken), I have only been able to get my tests to work by using global assignment (<<-) to create some objects on which the tests are then run. However, per CRAN policy: "Packages should not modify the global environment (user?s workspace)." Does anyone know whether this policy applies to all code within the package, including unit tests? Or does it apply just to the code and functions in /R? Or to all code that is executed as part of checking the package (i.e., code that is never run can use <<-)? James [[alternative HTML version deleted]]
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
Sent from my phone. Please excuse my brevity.
On Thu, 27 Jan 2022 08:55:49 -0600
James Pustejovsky <jepusto at gmail.com> wrote:
Because of some aspect of how testthat works (which is beyond my ken), I have only been able to get my tests to work by using global assignment (<<-) to create some objects on which the tests are then run.
What are you trying to achieve? Perhaps there's a better way to do that. I think that you can ask testthat-specific questions at <https://community.rstudio.com/> if they turn out to be too far from base R.
Does anyone know whether this policy applies to all code within the package, including unit tests? Or does it apply just to the code and functions in /R?
I'm not a CRAN member, but I think that the spirit of the rule only covers the user-accessible code, and tests aren't typically run in the same R session where the user objects live. For the same reason, I think that it's acceptable to test internal interfaces you don't want to export by calling them by means of package:::function.
Best regards, Ivan
Thanks for your perspective. Re: "beyond my ken" I'm just being honest. My operating assumption was that the unit testing code is run in its own process and therefore that using global assignment would be okay (i.e., not mucking with someone else's environment). But perhaps I'm being naive. The package is on Github here: https://github.com/meghapsimatrix/wildmeta/ The tests that use global assignment are: https://github.com/meghapsimatrix/wildmeta/blob/main/tests/testthat/test-rma-mv-methods.R https://github.com/meghapsimatrix/wildmeta/blob/main/tests/testthat/test-missing-value-handling.R On Thu, Jan 27, 2022 at 9:20 AM Jeff Newmiller <jdnewmil at dcn.davis.ca.us> wrote:
I don't know the answer to your question, but "beyond my ken" doesn't sound like a very convincing reason. Mucking with any environment that isn't yours is asking for trouble... the behavior you depend on today may come into conflict with the code you are coordinating with when you least expect it. Is your code in a public version control repo? On January 27, 2022 6:55:49 AM PST, James Pustejovsky <jepusto at gmail.com> wrote:
Hello, I'm writing unit tests using testthat for a package that we want to submit to CRAN. Because of some aspect of how testthat works (which is beyond my ken), I have only been able to get my tests to work by using global assignment (<<-) to create some objects on which the tests are then run. However, per CRAN policy: "Packages should not modify the global environment (user?s workspace)." Does anyone know whether this policy applies to all code within the package, including unit tests? Or does it apply just to the code and functions in /R? Or to all code that is executed as part of checking the package (i.e.,
code
that is never run can use <<-)?
James
[[alternative HTML version deleted]]
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
-- Sent from my phone. Please excuse my brevity.
On 27 January 2022 at 07:20, Jeff Newmiller wrote:
| I don't know the answer to your question, but "beyond my ken" doesn't sound like a very convincing reason. Mucking with any environment that isn't yours is asking for trouble... the behavior you depend on today may come into conflict with the code you are coordinating with when you least expect it. Right on. Yes a number of packages (of mine and other people) use a different approach to maintain 'global state' without ... using 'global variables' (== bad). The trick is something like `pkgenv <- new.env()` in R/zzz.R and to then also set an option or two you need in .onLoad as eg `pkgenv[["prefence"]] <- "foo"` which you can later test for, alter, ... at will. All without running afould of what `R CMD check --as-cran` may hate, all the while maintaining your logic flow. Dirk
https://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
But I am not using global variables at all in the package code (in /R)---only for unit testing. Is this distinction relevant? Or do I need to avoid global assignment even in the unit tests?
On Thu, Jan 27, 2022 at 9:40 AM Dirk Eddelbuettel <edd at debian.org> wrote:
On 27 January 2022 at 07:20, Jeff Newmiller wrote: | I don't know the answer to your question, but "beyond my ken" doesn't sound like a very convincing reason. Mucking with any environment that isn't yours is asking for trouble... the behavior you depend on today may come into conflict with the code you are coordinating with when you least expect it. Right on. Yes a number of packages (of mine and other people) use a different approach to maintain 'global state' without ... using 'global variables' (== bad). The trick is something like `pkgenv <- new.env()` in R/zzz.R and to then also set an option or two you need in .onLoad as eg `pkgenv[["prefence"]] <- "foo"` which you can later test for, alter, ... at will. All without running afould of what `R CMD check --as-cran` may hate, all the while maintaining your logic flow. Dirk -- https://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
On 27/01/2022 10:56 a.m., James Pustejovsky wrote:
But I am not using global variables at all in the package code (in /R)---only for unit testing. Is this distinction relevant? Or do I need to avoid global assignment even in the unit tests?
CRAN may let you do what you are doing, but as Dirk and Jeff said, it could come back to bite you later. For example, you may create a variable named foo containing extremely valuable data, and then run your test. (Tests can be run outside of R CMD check.) If your test stomps on foo, you'll lose all that data. It's worth using some trick like Dirk's to avoid this possibility. Duncan Murdoch
On Thu, Jan 27, 2022 at 9:40 AM Dirk Eddelbuettel <edd at debian.org> wrote:
On 27 January 2022 at 07:20, Jeff Newmiller wrote: | I don't know the answer to your question, but "beyond my ken" doesn't sound like a very convincing reason. Mucking with any environment that isn't yours is asking for trouble... the behavior you depend on today may come into conflict with the code you are coordinating with when you least expect it. Right on. Yes a number of packages (of mine and other people) use a different approach to maintain 'global state' without ... using 'global variables' (== bad). The trick is something like `pkgenv <- new.env()` in R/zzz.R and to then also set an option or two you need in .onLoad as eg `pkgenv[["prefence"]] <- "foo"` which you can later test for, alter, ... at will. All without running afould of what `R CMD check --as-cran` may hate, all the while maintaining your logic flow. Dirk -- https://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
[[alternative HTML version deleted]]
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
I will chime in briefly. I have spent hours trying to understand the scoping behaviour of testthat, mostly without success. I have lots of examples where I have tests that fail *only* when running devtools::check(), but not when running test_that in an interactive session, or in the same code run via source() or in an R batch session. So I am quite sympathetic to "beyond my ken". I agree that it's best to understand everything so that you can know when you might run into trouble in the future, but I have sometimes reconciled myself to giving up when it seemed I was spending much more time debugging my tests than debugging the actual package code ... For what it's worth, I have found that running <<- in these contexts doesn't seem to bother CRAN at all -- possibly because it's the *tests* that are potentially modifying the global environment, not the package itself. If you think about it, a prohibition on modifying the global environment in tests would mean that a plain old test file that assigned variables as part of testing flow would change the environment.
On 1/27/22 10:56 AM, James Pustejovsky wrote:
But I am not using global variables at all in the package code (in /R)---only for unit testing. Is this distinction relevant? Or do I need to avoid global assignment even in the unit tests? On Thu, Jan 27, 2022 at 9:40 AM Dirk Eddelbuettel <edd at debian.org> wrote:
On 27 January 2022 at 07:20, Jeff Newmiller wrote: | I don't know the answer to your question, but "beyond my ken" doesn't sound like a very convincing reason. Mucking with any environment that isn't yours is asking for trouble... the behavior you depend on today may come into conflict with the code you are coordinating with when you least expect it. Right on. Yes a number of packages (of mine and other people) use a different approach to maintain 'global state' without ... using 'global variables' (== bad). The trick is something like `pkgenv <- new.env()` in R/zzz.R and to then also set an option or two you need in .onLoad as eg `pkgenv[["prefence"]] <- "foo"` which you can later test for, alter, ... at will. All without running afould of what `R CMD check --as-cran` may hate, all the while maintaining your logic flow. Dirk -- https://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
[[alternative HTML version deleted]]
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
Dr. Benjamin Bolker Professor, Mathematics & Statistics and Biology, McMaster University Director, School of Computational Science and Engineering (Acting) Graduate chair, Mathematics & Statistics
I suppose, but this seems like kind of a far-fetched possibility if you're following any sort of reasonable scripting/development practices. Why in the world would someone be working with extremely valuable data and then decide to run all my package's unit tests interactively in the same session? In any case, it sounds like I should either just skip these unit tests or try to figure out what the heck is causing my namespace problems with testthat. On Thu, Jan 27, 2022 at 10:11 AM Duncan Murdoch <murdoch.duncan at gmail.com> wrote:
On 27/01/2022 10:56 a.m., James Pustejovsky wrote:
But I am not using global variables at all in the package code (in /R)---only for unit testing. Is this distinction relevant? Or do I need
to
avoid global assignment even in the unit tests?
CRAN may let you do what you are doing, but as Dirk and Jeff said, it could come back to bite you later. For example, you may create a variable named foo containing extremely valuable data, and then run your test. (Tests can be run outside of R CMD check.) If your test stomps on foo, you'll lose all that data. It's worth using some trick like Dirk's to avoid this possibility. Duncan Murdoch
On Thu, Jan 27, 2022 at 9:40 AM Dirk Eddelbuettel <edd at debian.org>
wrote:
On 27 January 2022 at 07:20, Jeff Newmiller wrote: | I don't know the answer to your question, but "beyond my ken" doesn't sound like a very convincing reason. Mucking with any environment that isn't yours is asking for trouble... the behavior you depend on today
may
come into conflict with the code you are coordinating with when you
least
expect it. Right on. Yes a number of packages (of mine and other people) use a different approach to maintain 'global state' without ... using 'global variables' (==
bad).
The trick is something like `pkgenv <- new.env()` in R/zzz.R and to then also set an option or two you need in .onLoad as eg `pkgenv[["prefence"]] <- "foo"` which you can later test for, alter, ... at will. All without running afould of what `R CMD check --as-cran` may hate, all the while maintaining your logic flow. Dirk -- https://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
[[alternative HTML version deleted]]
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
On 27/01/2022 16:56, James Pustejovsky wrote:
But I am not using global variables at all in the package code (in /R)---only for unit testing.
The response of Dirk can be seen as: create myenv in your package but use it in your tests instead of globalenv. This way you must be safe. Serguei.
Is this distinction relevant? Or do I need to avoid global assignment even in the unit tests? On Thu, Jan 27, 2022 at 9:40 AM Dirk Eddelbuettel <edd at debian.org> wrote:
On 27 January 2022 at 07:20, Jeff Newmiller wrote: | I don't know the answer to your question, but "beyond my ken" doesn't sound like a very convincing reason. Mucking with any environment that isn't yours is asking for trouble... the behavior you depend on today may come into conflict with the code you are coordinating with when you least expect it. Right on. Yes a number of packages (of mine and other people) use a different approach to maintain 'global state' without ... using 'global variables' (== bad). The trick is something like `pkgenv <- new.env()` in R/zzz.R and to then also set an option or two you need in .onLoad as eg `pkgenv[["prefence"]] <- "foo"` which you can later test for, alter, ... at will. All without running afould of what `R CMD check --as-cran` may hate, all the while maintaining your logic flow. Dirk -- https://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
[[alternative HTML version deleted]]
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
I believe, in base R, package tests scripts are run sequentially in clean sessions via R CMD BATCH. Test scripts can load packages, load data, etc, but the state is lost from script to script. Not sure about testthat tests / rstudio run tests button, because iirc it recursively loads other scripts from a shim within a single job. If I had to choose between writing a normal function, or a complicated function that works with testthat scoping, I'd opt for the normal one.
On Thu, Jan 27, 2022 at 8:25 AM James Pustejovsky <jepusto at gmail.com> wrote:
I suppose, but this seems like kind of a far-fetched possibility if you're following any sort of reasonable scripting/development practices. Why in the world would someone be working with extremely valuable data and then decide to run all my package's unit tests interactively in the same session? In any case, it sounds like I should either just skip these unit tests or try to figure out what the heck is causing my namespace problems with testthat. On Thu, Jan 27, 2022 at 10:11 AM Duncan Murdoch <murdoch.duncan at gmail.com> wrote:
On 27/01/2022 10:56 a.m., James Pustejovsky wrote:
But I am not using global variables at all in the package code (in /R)---only for unit testing. Is this distinction relevant? Or do I need
to
avoid global assignment even in the unit tests?
CRAN may let you do what you are doing, but as Dirk and Jeff said, it could come back to bite you later. For example, you may create a variable named foo containing extremely valuable data, and then run your test. (Tests can be run outside of R CMD check.) If your test stomps on foo, you'll lose all that data. It's worth using some trick like Dirk's to avoid this possibility. Duncan Murdoch
On Thu, Jan 27, 2022 at 9:40 AM Dirk Eddelbuettel <edd at debian.org>
wrote:
On 27 January 2022 at 07:20, Jeff Newmiller wrote: | I don't know the answer to your question, but "beyond my ken"
doesn't
sound like a very convincing reason. Mucking with any environment that isn't yours is asking for trouble... the behavior you depend on today
may
come into conflict with the code you are coordinating with when you
least
expect it. Right on. Yes a number of packages (of mine and other people) use a different approach to maintain 'global state' without ... using 'global variables' (==
bad).
The trick is something like `pkgenv <- new.env()` in R/zzz.R and to
then
also set an option or two you need in .onLoad as eg `pkgenv[["prefence"]]
<-
"foo"` which you can later test for, alter, ... at will. All without running afould of what `R CMD check --as-cran` may hate,
all
the while maintaining your logic flow. Dirk -- https://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
[[alternative HTML version deleted]]
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
[[alternative HTML version deleted]]
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
On 27 January 2022 at 11:18, Ben Bolker wrote:
| I have spent hours trying to understand the scoping behaviour of | testthat, mostly without success. It may bear repeating that use of a test runner package is NOT required by CRAN Repo Policy, Writing R Extensions, or any other official text. If any one of these candidate packages is too complicated, or confusing, or lengthens your test setup, or [your reason here] then consider not using it. Choice is a good thing, and we have a free option of using one or none of the different available testing packages. Dirk
https://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
On 27/01/2022 11:24 a.m., James Pustejovsky wrote:
I suppose, but this seems like kind of a far-fetched possibility if you're following any sort of reasonable scripting/development practices. Why in the world would someone be working with extremely valuable data and then decide to run all my package's unit tests interactively in the same session?
Perhaps "extremely" was an exaggeration, but it's not that far-fetched for someone to notice a problem in your package and want to make a change and test it. Your first test stomps on oswald2013, V, mod_A, mod_B, mod_C1, and about 20 other variables. That seems kind of excessive to me. Duncan Murdoch
In any case, it sounds like I should either just skip these unit tests
or try to figure out what the heck is causing my namespace problems with
testthat.
On Thu, Jan 27, 2022 at 10:11 AM Duncan Murdoch
<murdoch.duncan at gmail.com <mailto:murdoch.duncan at gmail.com>> wrote:
On 27/01/2022 10:56 a.m., James Pustejovsky wrote:
> But I am not using global variables at all in the package code (in
> /R)---only for unit testing. Is this distinction relevant? Or do
I need to
> avoid global assignment even in the unit tests?
CRAN may let you do what you are doing, but as Dirk and Jeff said, it
could come back to bite you later.? For example, you may create a
variable named foo containing extremely valuable data, and then run
your
test.? (Tests can be run outside of R CMD check.)? If your test stomps
on foo, you'll lose all that data.
It's worth using some trick like Dirk's to avoid this possibility.
Duncan Murdoch
>
> On Thu, Jan 27, 2022 at 9:40 AM Dirk Eddelbuettel <edd at debian.org
<mailto:edd at debian.org>> wrote:
>
>>
>> On 27 January 2022 at 07:20, Jeff Newmiller wrote:
>> | I don't know the answer to your question, but "beyond my ken"
doesn't
>> sound like a very convincing reason. Mucking with any
environment that
>> isn't yours is asking for trouble... the behavior you depend on
today may
>> come into conflict with the code you are coordinating with when
you least
>> expect it.
>>
>> Right on.
>>
>> Yes a number of packages (of mine and other people) use a different
>> approach
>> to maintain 'global state' without ... using 'global variables'
(== bad).
>>
>> The trick is something like `pkgenv <- new.env()` in R/zzz.R and
to then
>> also
>> set an option or two you need in .onLoad as eg
`pkgenv[["prefence"]] <-
>> "foo"`
>> which you can later test for, alter, ... at will.
>>
>> All without running afould of what `R CMD check --as-cran` may
hate, all
>> the
>> while maintaining your logic flow.
>>
>> Dirk
>>
>> --
>> https://dirk.eddelbuettel.com <https://dirk.eddelbuettel.com> |
@eddelbuettel | edd at debian.org <mailto:edd at debian.org>
>>
>
>? ? ? ?[[alternative HTML version deleted]]
>
> ______________________________________________
> R-package-devel at r-project.org
<mailto:R-package-devel at r-project.org> mailing list
Yes, that's a good point. Thanks for the reminder.
On Thu, Jan 27, 2022 at 10:52 AM Dirk Eddelbuettel <edd at debian.org> wrote:
On 27 January 2022 at 11:18, Ben Bolker wrote: | I have spent hours trying to understand the scoping behaviour of | testthat, mostly without success. It may bear repeating that use of a test runner package is NOT required by CRAN Repo Policy, Writing R Extensions, or any other official text. If any one of these candidate packages is too complicated, or confusing, or lengthens your test setup, or [your reason here] then consider not using it. Choice is a good thing, and we have a free option of using one or none of the different available testing packages. Dirk -- https://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
On 27/01/2022 11:18 a.m., Ben Bolker wrote:
I will chime in briefly.
I have spent hours trying to understand the scoping behaviour of
testthat, mostly without success. I have lots of examples where I have
tests that fail *only* when running devtools::check(), but not when
running test_that in an interactive session, or in the same code run via
source() or in an R batch session. So I am quite sympathetic to "beyond
my ken".
I agree that it's best to understand everything so that you can know
when you might run into trouble in the future, but I have sometimes
reconciled myself to giving up when it seemed I was spending much more
time debugging my tests than debugging the actual package code ...
For what it's worth, I have found that running <<- in these contexts
doesn't seem to bother CRAN at all -- possibly because it's the *tests*
that are potentially modifying the global environment, not the package
itself.
If you think about it, a prohibition on modifying the global
environment in tests would mean that a plain old test file that assigned
variables as part of testing flow would change the environment.
Yes, tests should be able to create variables, but they shouldn't go
overboard. A test like
x <- 1
stopifnot(x == 1)
will wipe out x, but that's probably not such a big deal. On the other
hand, a test like
c <<- function(...) stop('do not do this!')
testthat::expect_error(c(1))
is probably not a good idea.
Duncan Murdoch
On 1/27/22 10:56 AM, James Pustejovsky wrote:
But I am not using global variables at all in the package code (in /R)---only for unit testing. Is this distinction relevant? Or do I need to avoid global assignment even in the unit tests? On Thu, Jan 27, 2022 at 9:40 AM Dirk Eddelbuettel <edd at debian.org> wrote:
On 27 January 2022 at 07:20, Jeff Newmiller wrote: | I don't know the answer to your question, but "beyond my ken" doesn't sound like a very convincing reason. Mucking with any environment that isn't yours is asking for trouble... the behavior you depend on today may come into conflict with the code you are coordinating with when you least expect it. Right on. Yes a number of packages (of mine and other people) use a different approach to maintain 'global state' without ... using 'global variables' (== bad). The trick is something like `pkgenv <- new.env()` in R/zzz.R and to then also set an option or two you need in .onLoad as eg `pkgenv[["prefence"]] <- "foo"` which you can later test for, alter, ... at will. All without running afould of what `R CMD check --as-cran` may hate, all the while maintaining your logic flow. Dirk -- https://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
[[alternative HTML version deleted]]
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
On 1/27/22 12:07 PM, Duncan Murdoch wrote:
On 27/01/2022 11:18 a.m., Ben Bolker wrote:
??? I will chime in briefly. ??? I have spent hours trying to understand the scoping behaviour of testthat, mostly without success. I have lots of examples where I have tests that fail *only* when running devtools::check(), but not when running test_that in an interactive session, or in the same code run via source() or in an R batch session.? So I am quite sympathetic to "beyond my ken". ??? I agree that it's best to understand everything so that you can know when you might run into trouble in the future, but I have sometimes reconciled myself to giving up when it seemed I was spending much more time debugging my tests than debugging the actual package code ... ??? For what it's worth, I have found that running <<- in these contexts doesn't seem to bother CRAN at all -- possibly because it's the *tests* that are potentially modifying the global environment, not the package itself. ??? If you think about it, a prohibition on modifying the global environment in tests would mean that a plain old test file that assigned variables as part of testing flow would change the environment.
Yes, tests should be able to create variables, but they shouldn't go
overboard.? A test like
?? x <- 1
?? stopifnot(x == 1)
will wipe out x, but that's probably not such a big deal.? On the other
hand, a test like
?? c <<- function(...) stop('do not do this!')
?? testthat::expect_error(c(1))
is probably not a good idea.
Duncan Murdoch
Fair enough.
As to Dirk's comments about not being required to use a particular
test platform, I'll just say: inertia/sunk costs. I will definitely
consider using tinytest, or something else, in future projects ... (I do
like some of the extra features offered by testing platforms over the
base-R/vanilla "source() everything in the tests/ directory" approach.)
cheers
Ben Bolker
On 1/27/22 10:56 AM, James Pustejovsky wrote:
But I am not using global variables at all in the package code (in /R)---only for unit testing. Is this distinction relevant? Or do I need to avoid global assignment even in the unit tests? On Thu, Jan 27, 2022 at 9:40 AM Dirk Eddelbuettel <edd at debian.org> wrote:
On 27 January 2022 at 07:20, Jeff Newmiller wrote: | I don't know the answer to your question, but "beyond my ken" doesn't sound like a very convincing reason. Mucking with any environment that isn't yours is asking for trouble... the behavior you depend on today may come into conflict with the code you are coordinating with when you least expect it. Right on. Yes a number of packages (of mine and other people) use a different approach to maintain 'global state' without ... using 'global variables' (== bad). The trick is something like `pkgenv <- new.env()` in R/zzz.R and to then also set an option or two you need in .onLoad as eg `pkgenv[["prefence"]] <- "foo"` which you can later test for, alter, ... at will. All without running afould of what `R CMD check --as-cran` may hate, all the while maintaining your logic flow. Dirk -- https://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
????[[alternative HTML version deleted]]
______________________________________________ R-package-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel
Dr. Benjamin Bolker Professor, Mathematics & Statistics and Biology, McMaster University Director, School of Computational Science and Engineering (Acting) Graduate chair, Mathematics & Statistics
On 27/01/2022 12:11 p.m., Ben Bolker wrote:
On 1/27/22 12:07 PM, Duncan Murdoch wrote:
On 27/01/2022 11:18 a.m., Ben Bolker wrote:
??? I will chime in briefly. ??? I have spent hours trying to understand the scoping behaviour of testthat, mostly without success. I have lots of examples where I have tests that fail *only* when running devtools::check(), but not when running test_that in an interactive session, or in the same code run via source() or in an R batch session.? So I am quite sympathetic to "beyond my ken". ??? I agree that it's best to understand everything so that you can know when you might run into trouble in the future, but I have sometimes reconciled myself to giving up when it seemed I was spending much more time debugging my tests than debugging the actual package code ... ??? For what it's worth, I have found that running <<- in these contexts doesn't seem to bother CRAN at all -- possibly because it's the *tests* that are potentially modifying the global environment, not the package itself. ??? If you think about it, a prohibition on modifying the global environment in tests would mean that a plain old test file that assigned variables as part of testing flow would change the environment.
Yes, tests should be able to create variables, but they shouldn't go
overboard.? A test like
?? x <- 1
?? stopifnot(x == 1)
will wipe out x, but that's probably not such a big deal.? On the other
hand, a test like
?? c <<- function(...) stop('do not do this!')
?? testthat::expect_error(c(1))
is probably not a good idea.
Duncan Murdoch
Fair enough.
As to Dirk's comments about not being required to use a particular
test platform, I'll just say: inertia/sunk costs. I will definitely
consider using tinytest, or something else, in future projects ... (I do
like some of the extra features offered by testing platforms over the
base-R/vanilla "source() everything in the tests/ directory" approach.)
Rather than just complaining, I'll try to offer some constructive advice. The answer I just posted to this 9 year old question on StackOverflow probably won't help the original author, but maybe it's helpful to others: https://stackoverflow.com/q/70702130/2554330 . Though I don't use testthat enough to know if it will actually work. Duncan Murdoch
On 27 January 2022 at 12:11, Ben Bolker wrote:
| I will definitely consider using tinytest, or something else, in future projects ... Every tinytest test file is a regular R script. That is the core feature. No metaphysics, astrology, or tarot reading needed know what is happening. Dirk
https://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org