consensus on using separate *_test packages

Nate Finch nate.finch at canonical.com
Fri Sep 12 18:16:55 UTC 2014


In the thread Eric pointed to, Brad Fitzpatrick (one of the core Go
developers) says they prefer to keep tests in the same package unless
forced to have them in a different package to avoid circular dependencies.
 I like that.

I have always thought that export_test was an anti-pattern that should only
be used as a last resort.  The main problem I have with export_test is that
it makes your tests lie.  Your tests call foo.Create, but package foo
doesn't actually export Create, it has a non-exported create method, that
happens to get exported in the export_test file.  This makes your tests
more confusing than if you just called "create" from an internal test.
 That's even aside from the point of the busywork it creates from having to
write the file in the first place.

One argument for export_test is that it gives you a canonical place to go
look for all the internal stuff that is getting used in tests... but I
don't actually think that's very valuable.  I'm not actually sure why it
would be important to see what internal functions are getting exported for
use during tests.  And in theory, if you're writing extensive unit tests,
almost all the internal methods would get exported there... so it becomes
just a huge boilerplate file for no good reason.  If you really want to see
what functions are getting exercised during tests, use code coverage, it's
built into the go tool.

I agree with Gustavo's point that tests can be good examples of how to use
a package.  And, in fact, Go supports example functions
<https://godoc.org/github.com/natefinch/godocgo/sub#hdr-Examples> that are
run like tests, but also get displayed in generated docs.  These example
tests can exist in the package_test package to make them very accurate
representations of how to use the package.

Most tests that are written to test the functionality of a package are not
actually good examples of how to use the package.  Most tests are just
isolating one part of the logic and testing that.  No one using the package
for its intended purpose would ever do that.  This is doubly true of unit
tests, where you may just be testing the input and output of a single
internal function.

I think our current trend of doing most tests in an external package has
significantly contributed to the poor quality of our tests.  Because we're
running from outside the package, we generally only have access to the
exported API of the package, so we try to "make it work" by mocking out
large portions of the code in order to be able to call the external
function, rather than writing real unit tests that just test one small
portion of the internal functionality of the package.

-Nate
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ubuntu.com/archives/juju-dev/attachments/20140912/19776041/attachment-0001.html>


More information about the Juju-dev mailing list