$(DDOC $(DDOC_BLANKLINE ) $(DDOC_BLANKLINE ) $(SPEC_S Unit Tests, $(DDOC_BLANKLINE ) $(HEADERNAV_TOC $(HEADERNAV_ITEM attributes_unittest, Attributed Unittests) $(HEADERNAV_ITEM documented-unittests, Documented Unittests) ) $(DDOC_BLANKLINE ) $(GRAMMAR $(GNAME UnitTest): $(D unittest) $(GLINK2 statement, BlockStatement) ) $(P Unit tests are a builtin framework of test cases applied to a module to determine if it is working properly. A D program can be run with unit tests enabled or disabled. ) $(DDOC_BLANKLINE ) $(P Unit tests are a special function defined like:) $(DDOC_BLANKLINE ) $(D_CODE $(D_KEYWORD unittest) { ...test code... } ) $(DDOC_BLANKLINE ) $(P Individual tests are specified in the unit test using $(DDSUBLINK spec/expression, AssertExpression, AssertExpressions). Unlike $(I AssertExpression)s used elsewhere, the assert is not assumed to hold, and upon assert failure the program is still in a defined state. ) $(DDOC_BLANKLINE ) $(P There can be any number of unit test functions in a module, including within struct, union and class declarations. They are executed in lexical order. ) $(DDOC_BLANKLINE ) $(P Unit tests, when enabled, are run after all static initialization is complete and before the $(D main()) function is called. ) $(DDOC_BLANKLINE ) $(P For example, given a class $(D Sum) that is used to add two values, a unit test can be given:) $(DDOC_BLANKLINE ) $(D_CODE $(D_KEYWORD class) Sum { $(D_KEYWORD int) add($(D_KEYWORD int) x, $(D_KEYWORD int) y) { $(D_KEYWORD return) x + y; } $(D_KEYWORD unittest) { Sum sum = $(D_KEYWORD new) Sum; $(D_KEYWORD assert)(sum.add(3,4) == 7); $(D_KEYWORD assert)(sum.add(-2,0) == -2); } } ) $(DDOC_BLANKLINE ) $(P When unit tests are enabled, the $(DDSUBLINK spec/version, PredefinedVersions, version identifier) $(D unittest) is predefined. ) $(DDOC_BLANKLINE ) $(DDOC_BLANKLINE )
nothrow
code. Although this can also be accomplished by attaching these
attributes to $(D myFunc) itself, that would prevent $(D myFunc) from being
instantiated with types $(D T) that have $(D @system) or throwing code in their
$(D opAssign) method, or other methods that $(D myFunc) may call. The above
idiom allows $(D myFunc) to be instantiated with such types, yet at the same
time verify that the $(D @system) and throwing behavior is not introduced by
the code within $(D myFunc) itself.)
$(DDOC_BLANKLINE )
$(IMPLEMENTATION_DEFINED $(OL $(LI If unit tests are not enabled, the implementation is not required to
check the $(GLINK UnitTest) for syntactic or semantic correctness.
This is to reduce the compile time impact of larger unit test sections.
The tokens must still be valid, and the implementation can merely count
$(D {) and $(D }) tokens to find the end of the $(GLINK UnitTest)'s $(GLINK2 statement, BlockStatement).
)
$(LI The presentation of unit test results to the user.)
$(LI The method used to enable or disable the unit tests. Use of a compiler
switch such as $(DDSUBLINK dmd, switch-unittest, $(B -unittest)) to enable
them is suggested.)
$(LI The order in which modules are called to run their unit tests.)
$(LI Whether the program stops on the first unit test failure, or continues running the unit tests.)
)
)
$(DDOC_BLANKLINE )
$(BEST_PRACTICE $(OL $(LI Using unit tests in conjunction with coverage testing
(such as $(DDSUBLINK dmd, switch-cov, $(B -cov)))
is effective.)
$(LI A unit test for a function should appear immediately
following it.)
)
)
$(DDOC_BLANKLINE )
$(DDOC_BLANKLINE )
auto math = new Math; auto result = math.add(2, 2);
assert(add(2, 2) == 4);
assert(add(1, 1) == 2);
/** assert(add(4, 4) == 8); */