DkSDKTest¶
- DkSDKTest_AddUnitTest¶
DkSDKTest_AddUnitTest( NAME name STANDARD_MAIN | MAIN somewhere/main.c ML_RUNTIME ... [C_RUNTIME ...] [ARGS ...] )
Usage¶
Conventionally you will place your unit tests in the
tests/Units
folder of your project, although you can use one or more project subfolders of your choosing.The conventional
tests/Units/CMakeLists.txt
should contain:include(DkSDKTest)
# Use the TESTS flag to get access to your test dependencies DkSDKProject_AddPackage(AUTO_OPAM_PACKAGE TESTS)
# Use one or more unit test commands DkSDKTest_AddUnitTest(NAME first STANDARD_MAIN ...) DkSDKTest_AddUnitTest(NAME second STANDARD_MAIN ...)
Then place each unit test in a subfolder according to the following directory structure:
tests/Units ├── CMakeLists.txt <-- Contains DkSDKTest_AddUnitTest() commands ├── first <-- Corresponds to DkSDKTest_AddUnitTest(NAME first ...) │ ├── test_first_ml.ml │ ├── testsuite_builtin_types.c │ └── testsuite_capnp_c.c └── second <-- Corresponds to DkSDKTest_AddUnitTest(NAME second ...) └── test_second_ml.ml
The NAME "first" and the NAME "second" are just examples.
However, you must include the test entry point
.ml
file named<NAME>/test_<NAME>_ml.ml
in each unit test subfolder.You can additionally use any
.c
and.ml
files. Those additional files do not need to be specified in the CMakeLists.txt because they are automatically discovered.Compilation And Linking¶
The unit test C code and unit test OCaml code are compiled separately into a
_c
and a_ml
target, respectively. Then the two targets are linked together into a single test executable.Let's use the following "first" unit test as an example:
tests/Units ├── CMakeLists.txt <-- Has DkSDKTest_AddUnitTest(NAME first ...) └── first ├── test_first_ml.ml ├── more.ml ├── testsuite_builtin_types.c └── testsuite_capnp_c.c
That example would create:
A
first_ml
STATIC library
target containing the code fortest_first_ml.ml
andmore.ml
. AnyML_RUNTIME
fromDkSDKTest_AddUnitTest(NAME first ML_RUNTIME ...)
would be linked intofirst_ml
.A
first_c
STATIC library
target containing the code fortestsuite_builtin_types.c
andtestsuite_capnp_c.c
. AnyC_RUNTIME
orC_COMPILE
fromDkSDKTest_AddUnitTest(NAME first C_RUNTIME ...)
would be linked intofirst_c
.A
first
executable
target containing the main entry code from eitherDkSDKTest_AddUnitTest(NAME first STANDARD_MAIN ...)
orDkSDKTest_AddUnitTest(NAME first MAIN main_entry.c ...)
. Thefirst_ml
andfirst_c
library targets would be linked into thefirst
executable target.
Several implicit libraries are included automatically in each target. The complete list of libraries for each target is:
The
_ml
target (ex.first_ml
):Findlib::tezt
for writing Tezt based OCaml testsFindlib::lwt
andFindlib::lwt.unix
for OCaml cooperative threadingAll the
ML_RUNTIME
fromDkSDKTest_AddUnitTest(ML_RUNTIME ...)
The
_c
target (ex.first_c
) will include:All the
C_COMPILE
andC_RUNTIME
fromDkSDKTest_AddUnitTest(C_RUNTIME ...)
The executable target (ex.
first
) will include:
CTest¶
The test executables described in DkSDKTest_AddUnitTest() Compilation And Linking are automatically added as
CTest tests
unless either:the test executable has an incompatible ABI with the build ("host") machine
the
BUILD_TESTING
variable isOFF
Unix only: The library directories for each
ML_RUNTIME
andC_RUNTIME
dependencies are added to the LD_LIBRARY_PATH (DYLD_FALLBACK_LIBRARY_PATH on macOS) of the test executable. TheC_COMPILE
dependencies are not added to the PATH.But since the test executables will always be compiled and generated you achieve:
Cross-compiling of your libraries is exercised and tested.
(Advanced) The Dune build tool requires that any
.opam
files that have been checked into source code have matching statements indune-project
.DkSDKTest_AddUnitTest()
ensures thatdune-project
test packages have correctly modeled dependencies, even if the tests are disabled. Said another way, we can't havedune-project
mutating simply because tests are not enabled in one invocation while they are enabled in another invocation.
Options¶
- NAME
The name of the unit test.
The files for the unit test must be in a subfolder with the same name, and there must be an entry point
<NAME>/test_<NAME>_ml.ml
.For example, if
NAME
wasmessage
then the following is the minimal directory structure:tests/Units <-- The conventional directory to place unit tests ├── CMakeLists.txt <-- Has DkSDKTest_AddUnitTest(NAME message ...) └── message └── test_message_ml.ml
- STANDARD_MAIN
A minimal
main()
C entry point will be generated for your unit test executable that runs your OCaml code and then exits.- MAIN c_file
Use your own C code in
c_file
that has amain()
C entry point.- ML_RUNTIME dependency1 ... dependencyN
Add OCaml runtime dependencies to the
<NAME>_ml
target. See the above DkSDKTest_AddUnitTest() Compilation And Linking and DkSDKTest_AddUnitTest() CTest sections for complete details.- ARGS arg1 ... argN
Arguments passed to the test executable
- C_COMPILE dependency1 ... dependencyN
Add C compile dependencies to the
<NAME>_c
target. These dependencies do not influence the runtime library path (LD_LIBRARY_PATH) for CTest. See the above DkSDKTest_AddUnitTest() Compilation And Linking and DkSDKTest_AddUnitTest() CTest sections for complete details.- C_RUNTIME dependency1 ... dependencyN
Add C runtime dependencies to the
<NAME>_c
target. See the above DkSDKTest_AddUnitTest() Compilation And Linking and DkSDKTest_AddUnitTest() CTest sections for complete details.
- DkSDKTest_AddDkSDKProjectNewTest¶
Tests the command
./dk dksdk.project.new
.DkSDKTest_AddDkSDKProjectNewTest( TEMPLATE_PROJECT_DIR dir NEW_PROJECT_NAME name [SKIP_MSVC_TESTS_IF_MSVC_UNAVAILABLE] )
Template Project Requirements¶
The project must contain a
dk
and adk.cmd
script in the root of the project.The
dk
scripts must recognize thedksdk.project.new
task. TheDkHelloWorld*
projects include that task.There must be a
ci/git-clone.sh
POSIX script that accepts the following options:- -V
The
Major.Minor
version of DkSDK- -p
The location of the CMake executable
and accepts the following environment variables:
- GIT_URL_<underscored(name)>
All FETCHCONTENT_SOURCE_DIR_<name> CMake variables are set as
file://<path from FETCHCONTENT>/.git
if the content is a git repository.
Options¶
- TEMPLATE_PROJECT_DIR
The directory of the template project.
Defaults to
PROJECT_SOURCE_DIR
.- NEW_PROJECT_NAME
The name of the project that will be generated.
Defaults to
TestProject
.- SKIP_MSVC_TESTS_IF_MSVC_UNAVAILABLE
If specified and the host is Windows, then will skip tests that require MSVC if a Visual Studio Command Prompt has not been used to launch the test.
Often an IDE like CLion will only pass MSVC environment variables to
cmake
but notctest
. The SKIP_MSVC_TESTS_IF_MSVC_UNAVAILABLE flag will let those IDEs still work.Currently the Visual Studio Command Prompt (
vcvarsall.bat
orVsDevCmd.bat
) is detected based on the presence of theVCINSTALLDIR
environment variable.- VERBOSE
When specified, the new project will invoke
ctest
with--verbose
. That means the ctest output is not hidden.