Not all qtest pragmas directly translate into tests; for non-trivial projects, sometimes a little boilerplate code is needed in order to set the tests up properly. The pragmas which do this are collectively called "manipulation pragmas"; they are described in the next section.
The tests should have access to the same values as the code under test; however the generated code for foo.ml does not actually live inside that file. Therefore some effort must occasionally be made to synchronise the code’s environment with the tests’. There are three main usecases where you might want to open modules for tests:
qtest --preamble "open Batteries;;" extract mod1.ml mod2.ml ... modN.mlNote that you could insert arbitrary code using this switch.
(*$< Bar, Baz >*)The modules will be open for every test in the same .ml file, and following the pragma. However, in our example, you will have a duplication of code between the "open" directives of foo.ml, and the open pragma of qtest, like so:
open Bar;; open Baz;; (*$< Bar, Baz >*)It might therefore be more convenient to use the code injection pragma (see next section) for that purpose, so you would write instead:
(*${*) open Bar;; open Baz;; (*$}*)The code between that special markup will simply be duplicated into the tests. The two methods are equivalent, and the second one is recommended, because it reduces the chances of an impedance mismatch between modules open for ‘foo.ml‘ and its tests. Therefore, the global form of the open pragma should preferentially be reserved for cases where you want such a mismatch. For instance, if you have special modules useful for tests but useless for the main code, you can easily open then for the tests alone using the pragma.
let outer x = <something> module Submod = struct let inner y = 2*x (*$T inner inner 2 = 4 *) endThat seems natural enough... but it won’t work, because qtest is not actually aware that the test is "inside" Submod (and making it aware of that would be very problematic). In fact, so long as you use only test pragmas (ie. no manipulation pragma at all), the positions and even the order of the tests – respective to definitions or to each other – are unimportant, because the tests do not actually live in foo.ml. So we need to open Submod manually, using the local form of the open pragma:
module Submod = struct (*$< Submod *) let inner y = 2*x (*$T inner inner 2 = 4 *) end (*$>*)Notice that the <...> have simply been split in two, compared to the global form. The effect of that construct is that Submod will be open for every test between (*$< Submod *) and (*$>*). Of course, you could also forgo that method entirely and do this:
module Submod = struct let inner y = 2*x (*$T & Submod.inner 2 = 4 *) end... but it is impractical and you are forced to use an empty header because qualified names are not acceptable as headers. The first method is therefore strongly recommended.
TODO: ocamldoc comments that define unit tests from the offered examples