Disclaimer

The content of this blog is my personal opinion only. Although I am an employee - currently of Nvidia, in the past of other companies such as Iagination Technologies, MIPS, Intellectual Ventures, Intel, AMD, Motorola, and Gould - I reveal this only so that the reader may account for any possible bias I may have towards my employer's products. The statements I make here in no way represent my employer's position, nor am I authorized to speak on behalf of my employer. In fact, this posting may not even represent my personal opinion, since occasionally I play devil's advocate.

See http://docs.google.com/View?id=dcxddbtr_23cg5thdfj for photo credits.

Saturday, January 28, 2012

Project structure: code, tests, external depndencies

Say you have a project foo, which I will call .../foo, to emphasize that there is probably a project directory somewhere in the namespace.
.../foo
Where do you put the tests?  It's nice to put them in .../foo/tests, so that when you checkout the project, you get the tests as well:
.../foo/tests
    by which I mean
    .../foo
        .../foo/tests
    or
    ...
       foo
          tests
    but  emphasizing the full context via .../ and .../foo/

It's also good to minimize the external dependencies of .../foo.

But what if the tests have more external dependencies than the non-test part of the project.  Should you increase the external dependencies of the non-test part just to have the tests?

Conversely, should you make it harder to write the tests by forbidding external dependencies in them?  Tests are hard enough to write, and they often depend on extra libraries that the source code per se does not?

More specifically, should you get stuff that has increased external dependencies if you check out .../foo and .../foo/tests comes along for the ride?

If you don't want the extra dependencies in .../foo/tests to come along with .../foo, you might structure them as separate modules, possibly separate in the file space:

.../foo+tests
    .../foo
    .../tests


This works, but it creates extra levels of such "meta-modules": .../foo+tests, .../foo+interactive_tests, .../foo+debugging_tools+tests, etc.

You might structure it as a series of optional modules, all within a single metamodule:

.../foo+stuff
    .../foo
    .../tests
    .../stress-tests

or, rather


.../foo+stuff
    .../foo+stuff/foo
    .../foo+stuff/tests
    .../foo+stuff/stress-tests

and so on.

It's still annoying to have an extra level of indirection, but the purity of the bodily fluids of .../foo is maintained.
Now, of course, it is highly likely that you will have some tests within foo and some that are assoviated with foo, but that foo won't let in:

.../foo+stuff
    .../foo+stuff/foo
        .../foo+stuff/foo/tests
    .../foo+stuff/tests
    .../foo+stuff/stress-tests
This can be confusing, but apart from changing names it may be unavoidable: if a country has immigration control country, you often get refugee camps on the border.  The country may ignore them, but the UNHCR does not.

Some systems allow this "stuff" to be overlays within foo:

.../foo
    .../foo/tests -- optional
    .../foo/stress-tests  -- optional


No comments: