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/Unitsfolder of your project, although you can use one or more project subfolders of your choosing.The conventional
tests/Units/CMakeLists.txtshould 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.mlThe NAME "first" and the NAME "second" are just examples.
However, you must include the test entry point
.mlfile named<NAME>/test_<NAME>_ml.mlin each unit test subfolder.You can additionally use any
.cand.mlfiles. 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
_cand a_mltarget, 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.cThat example would create:
A
first_mlSTATIC librarytarget containing the code fortest_first_ml.mlandmore.ml. AnyML_RUNTIMEfromDkSDKTest_AddUnitTest(NAME first ML_RUNTIME ...)would be linked intofirst_ml.A
first_cSTATIC librarytarget containing the code fortestsuite_builtin_types.candtestsuite_capnp_c.c. AnyC_RUNTIMEorC_COMPILEfromDkSDKTest_AddUnitTest(NAME first C_RUNTIME ...)would be linked intofirst_c.A
firstexecutabletarget containing the main entry code from eitherDkSDKTest_AddUnitTest(NAME first STANDARD_MAIN ...)orDkSDKTest_AddUnitTest(NAME first MAIN main_entry.c ...). Thefirst_mlandfirst_clibrary targets would be linked into thefirstexecutable target.
Several implicit libraries are included automatically in each target. The complete list of libraries for each target is:
The
_mltarget (ex.first_ml):Findlib::teztfor writing Tezt based OCaml testsFindlib::lwtandFindlib::lwt.unixfor OCaml cooperative threadingAll the
ML_RUNTIMEfromDkSDKTest_AddUnitTest(ML_RUNTIME ...)
The
_ctarget (ex.first_c) will include:All the
C_COMPILEandC_RUNTIMEfromDkSDKTest_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 testsunless either:the test executable has an incompatible ABI with the build ("host") machine
the
BUILD_TESTINGvariable isOFF
Unix only: The library directories for each
ML_RUNTIMEandC_RUNTIMEdependencies are added to the LD_LIBRARY_PATH (DYLD_FALLBACK_LIBRARY_PATH on macOS) of the test executable. TheC_COMPILEdependencies 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
.opamfiles that have been checked into source code have matching statements indune-project.DkSDKTest_AddUnitTest()ensures thatdune-projecttest packages have correctly modeled dependencies, even if the tests are disabled. Said another way, we can't havedune-projectmutating 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
NAMEwasmessagethen 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_filethat has amain()C entry point.- ML_RUNTIME dependency1 ... dependencyN
Add OCaml runtime dependencies to the
<NAME>_mltarget. 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>_ctarget. 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>_ctarget. 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
dkand adk.cmdscript in the root of the project.The
dkscripts must recognize thedksdk.project.new(creating a new project) and thedksdk.project.get(downloading project dependencies) tasks. TheDkHelloWorld*projects include those tasks.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
cmakebut notctest. The SKIP_MSVC_TESTS_IF_MSVC_UNAVAILABLE flag will let those IDEs still work.Currently the Visual Studio Command Prompt (
vcvarsall.batorVsDevCmd.bat) is detected based on the presence of theVCINSTALLDIRenvironment variable.- VERBOSE
When specified, the new project will invoke
ctestwith--verbose. That means the ctest output is not hidden.
