2

Actual question

Seems like devtools::test() does not make sure that package dependencies as stated in a package's DESCRIPTION file are loaded prior to running the unit tests. How can I change that?

Details

I'm writing a package (B) that imports another one of my packages (A).

When I try to run my unit tests via devtools::test(), or, to be more precise via the shortcut SHFT + CRTL + T in RStudio, certain tests fail as the imported package seems to be disregarded/not loaded and thus a certain function (isPackageInstalled) can't be found.

Trying to load the imported package A manually before running devtools::test() didn't help either. I guess that's due to the fact that devtools (or testthat) "simulates" a fresh workspace state? Running the unit tests "one by one" works just fine after manually loading package A beforehand, though.

I thought that devtools would look up package dependencies in the DESCRIPTION file of B and thus load them as would be the case when running require("B"), but apparently not.

Here's my DESCRIPTION file:

Package: B
Type: Package
Title: What the package does (short line)
Version: 0.1.0.1
Date: 2014-08-05
Author: Who wrote it
Maintainer: Who to complain to <yourfault@somewhere.net>
Description: More about what it does (maybe more than one line)
License: What license is it under?
Imports: A

Here's the code I ran:

devtools::load_all()  # or SHFT + CTRL + L in RStudio
devtools::test()      # or SHFT + CTRL + T in RStudio

That's what RStudio's build pane gave me:

==> devtools::test()

Loading required package: testthat
Testing B
Loading B
Creating a new generic function for 'signalCondition' in package 'B'
package : 1
package : ......


1. Error: getPackageDescription ------------------------------------------------
could not find function "isPackageInstalled"
1: expect_is(res <- getPackageDescription(), expected) at test-getPackageDescription.r:13
2: expect_that(object, is_a(class), info, label)
3: condition(object)
4: paste0(class(x), collapse = ", ")
5: getPackageDescription()
6: getPackageDescription() at Q:\home\wsp\rapp2\B/R/getPackageDescription.r:37
7: getPackageDescription(from = from, fields = fields, drop = drop, encoding = encoding, 
       ...) at Q:\home\wsp\rapp2\B/R/getPackageDescription.r:154
8: getPackageDescription(from = from, fields = fields, drop = drop, encoding = encoding, 
       ...) at Q:\home\wsp\rapp2\B/R/getPackageDescription.r:37

Am I missing something here?

Screenshot of build tools dialogue:

enter image description here

Rappster
  • 12,762
  • 7
  • 71
  • 120
  • Is the import also included in your NAMESPACE file? Also: clean up that description file :p – Dason Aug 19 '14 at 14:04
  • Aha! Good point. While still at dev-mode, what's the best way to have `devtools` "build" the NAMESPACE file? Should I run `devtools::build()` everytime before running my unit tests? And with respect to the DESCRIPTION file: sure, I'm just hacking away at this point ;-) – Rappster Aug 19 '14 at 14:07
  • Wait, now I'm confused. I checked the `NAMESPACE` file **after** building the package with `devtools::build()`, but the only thing in there is `exportPattern("^[[:alpha:]]+")`. I thought that either one of `devtools` or `roxygen2` takes care of populating the `NAMESPACE` file? Also: I thought maybe it's not working due to the fact that I only had a copy of `DESCRIPTION` in `./tests/testthat`, but no copy of `NAMESPACE`. But after making sure both copies are there, my unit tests still fail. – Rappster Aug 19 '14 at 14:10
  • 1
    Do you have anything in you roxygen code that tells roxygen that you import a package? ie do you have an `@imports` or `@importsFrom` comment in your roxygen code? If you want roxygen2 to take care of the namespace file you need to tell it what you're importing somewhere in your roxygen comments. Different note: Are you saying you put a copy of your description file in ./tests/testthat? Why? – Dason Aug 19 '14 at 14:25
  • 1
    Configure your options at `Build \ Configure build tools... \ Build tools` then check the option to `Generate documentation with Roxygen`. Make sure you enable NAMESPACE build with roxygen. – Andrie Aug 19 '14 at 14:28
  • Ad 1): no, didn't do that yet. I thought stating a "global" dependency in the `DESCRIPTION` file would be enough (even though or more fine-tuned dependency management might indeed make sense). Ad 2) the package is about an alternative way of doing what `utils::packageDependency()` does but when you want to read the `DEPENDENCY` info based on a file path. So I need it for the actual unit tests (e.g. when using the equivalent of the `fields` argument of `utils::packageDependency()`. So my bad: this indeed has nothing to do with the tests failing. – Rappster Aug 19 '14 at 14:29
  • @Andrie: didn't find that setting (see screenshot above). Also: what would I need to do when not using RStudio. Running `roxygenize()` prior to unit testing? – Rappster Aug 19 '14 at 14:34
  • 1
    Duh... forgot to explicitly install `roxygen2`. Sorry guys. – Rappster Aug 19 '14 at 14:38
  • The answer to the question though is just "Make sure the imports are also listed in the NAMESPACE file". How you go about doing that (via roxygen2 or manually) is up to you. – Dason Aug 19 '14 at 14:39
  • 1
    Okay, got it. But just to make sure: there's no "built-in shortcut method" of `devtools` (or `roxygen2`) that would simply make sure that `Depends` and `Imports` entries in `DESCRIPTION` are transferred to `NAMESPACE`, right? – Rappster Aug 19 '14 at 14:42

1 Answers1

0

The usual approach would be to use roxygen2 to automatically generate your NAMESPACE file from special comments in your source code, but maintain your DESCRIPTION file manually. There's no special stuff that I'm aware of to keep them in sync, but R CMD CHECK will tell you if there's something missing/extra in your DESCRIPTION.

Ken Williams
  • 22,756
  • 10
  • 85
  • 147