beanumber / etl

R package to facilitate ETL operations
127 stars 21 forks source link

find_schema breaks in unit tests #50

Open wmay opened 5 years ago

wmay commented 5 years ago

find_schema looks in package_root/sql to find sql source files. But when running unit tests the files are in package_root/inst/sql. This makes it impossible (as far as I can tell) for an etl extension package to include etl_init in unit tests if it includes sql files.

devtools and testthat quietly replace system.file with a modified version to keep it working in most unit tests. But those packages can only replace system.file in the package being tested. So if a package imports find_schema from etl, in a unit test when find_schema calls system.file it doesn't add the extra inst folder.

I don't know if the devtools people provide a way to fix this. Maybe find_schema could check to see if package_root/sql exists, and if not then try package_root/inst/sql?

You should be able to reproduce this issue with the following steps:

  1. Create a package that extends etl.
  2. Include a sql file.
  3. Use testthat and try to test find_schema with something like the example below.
test_that("find_schema works", {
  pkgname = etl("pkgname")
  schema_path = etl::find_schema(pkgname)
  expect_equal(is.null(schema_path), FALSE)
})
beanumber commented 5 years ago

Does testthat::test_path() solve this problem?

beanumber commented 5 years ago

And is this only a problem if you are testing a package that is not installed, but for which you have the source code?

wmay commented 5 years ago

testthat::test_path doesn't look like it addresses the inst folder issue.

It is a problem even if the package is installed, because find.package searches the loaded namespaces before the library paths, so during testing it always returns the path to the source code instead of the installed package path. When running unit tests devtools / testthat use the source code rather than the installed package.