title: How can we test functions that aren't exposed when building R packages?
body: <p>I'm currently developing a <a href="https://github.com/briandk/granova/commits/dev" rel="noreferrer">graphical analysis package</a> for R. We're trying to use principles from both <a href="https://rads.stackoverflow.com/amzn/click/com/0132350882" rel="noreferrer" rel="nofollow noreferrer">Clean Code</a> and <a href="https://github.com/hadley/devtools/wiki/Testing" rel="noreferrer">Test-Driven Development</a> (TDD). But, we've run into a conceptual problem.</p>
  <h3>How can you test unexposed functions?</h3>
  <p>Consider the following simplified example. <code>Outer()</code> is a function we're building in our <a href="https://github.com/briandk/granova/commits/dev" rel="noreferrer">package</a>, and we expose it to users by listing it in the <a href="https://github.com/briandk/granova/blob/dev/NAMESPACE" rel="noreferrer"><code>NAMESPACE</code></a> file. <code>Inner()</code> is a short (~5 line) utility function:</p>
  <pre><code>Outer &lt;- function(...) {
  
    Inner &lt;- function(...) {
      return(x)
    }
  
    return( Inner() )
  }
  </code></pre>
  <p>Most of the user-exposed functions in our <a href="https://github.com/briandk/granova/commits/dev" rel="noreferrer">package</a> are collections of short, single-behavior <code>Inner()</code> style functions that lie under the umbrella of a single <code>Outer()</code> function the user can call. <a href="https://github.com/briandk/granova/blob/dev/R/granova.ds.ggplot.R" rel="noreferrer"><code>Granova.ds.ggplot()</code></a> is one example. Such a modular design is strongly advocated by <a href="https://rads.stackoverflow.com/amzn/click/com/0132350882" rel="noreferrer" rel="nofollow noreferrer">Clean Code</a>, and we're quite happy with the results. But we don't know how to build unit tests for it, since the functions we want to test aren't accessible outside the scope of the <code>Granova.ds.ggplot()</code> function given how we designed it.</p>
  <p>Several ideas/solutions occurred to us:</p>
  <ol>
  <li>Tests should only have access to public APIs. Since functions like <code>Inner()</code> are by design not public (they're not exported in <code>NAMESPACE</code>) we shouldn't even be trying to test them.</li>
  <li>Hadley Wickham's <code>testthat</code> <a href="https://github.com/hadley/devtools/wiki/Testing" rel="noreferrer">package wiki</a> says it supports testing of &quot;non-exported functions&quot; using an <code>R CMD check</code> workflow.</li>
  <li>If all else fails, we could somehow manually break our <code>Outer()</code> functions for testing purposes</li>
  </ol>
  <h3>None of these solutions has worked so far</h3>
  <p>Solution 1 seems like a cop-out. We believe that especially in R, it's sensible to have a top-level function that calls various short, single-responsibility utility methods. Not being able to test such methods seems silly, and like the type of thing there's a solution for but we just haven't found yet.</p>
  <p>Solution 2 might work, but we haven't gotten it to work so far. If you try cloning <a href="https://github.com/briandk/granova/commits/dev" rel="noreferrer">our repository</a>, then sourcing <code>inst/dev.R</code> I believe you'll find in the test output that it cannot find the function <code>InitializeGgplot()</code>, even though <a href="https://github.com/briandk/granova/blob/dev/R/granova.1w.ggplot.R" rel="noreferrer">said function</a> is defined in lines 613-615 of <a href="https://github.com/briandk/granova/blob/dev/R/granova.1w.ggplot.R" rel="noreferrer"><code>granova.1w.ggplot()</code></a>. Similarly, running <code>R CMD check</code> at the terminal doesn't seem to execute any of our tests at all. It does take a great deal of time and throw insulting errors at us, though :-(</p>
  <p>Solution 3 is in a sense pragmatic, but counter to the aim of always moving toward a goal state of the project. It doesn't make sense to us.</p>
  <h3>What would be the ideal solution</h3>
  <p>Ideally, we're looking for a way to leverage a package like <code>testthat</code> to rapidly provide feedback as we code, and to allow us to test functions like <code>Inner()</code> that exist <em>within</em> functions like <code>Outer()</code>. Even better would be a way to do it without resorting to <code>R CMD check</code>, which due to the 3-d complexity of some of our functions takes almost a full minute to run each time.</p>
  <p>So, what are we missing? Should TDD practices allow for testing Outer/Inner style setups in R? If they do, how can we do so in developing our package? Any feedback is welcome, and I'll try to respond to anything that's unclear.</p>
  <p>Thanks!</p>