CMake: How to Unit-Test your own CMake Script Macros/Functions? -


i've written convenience wrappers around standard cmake commands , want unit-test cmake script code ensure functionality.

i've made progress, there 2 things hope with:

  1. is there "official" way of unit-testing own cmake script code? special mode run cmake in? goal "white-box testing" (as possible).
  2. how handle global variables , variable scopes issues? inject global variables test via loading project's cache, configure test cmake file or pushing via -d command line option? simulation/testing of variable scopes (cached vs. non-cached, macros/functions/includes, parameters passed references)?

to start i've looked cmake source code (i'm using cmake version 2.8.10) under /tests , under tests/cmaketests. there huge number of varieties found , looks lot of them specialized on single test case.

so looked available cmake script libraries cmake++ see solution, - when have unit tests - heavily depending on own library functions.

here current solution unit-testing own cmake script code.

by assumption using cmake script processing mode best catch , have mock cmake commands not usable in script mode - far - came following.

the helper functions

utilizing own global properties, have written helper functions store , compare function calls:

function(cmakemocks_clearlists _message_type)     _get_property(_list_names global property mocklists)     if (not "${_list_names}" strequal "")         foreach(_name in items ${_list_names})             _get_property(_list_values global property ${_name})             if (not "${_list_values}" strequal "")                 foreach(_value in items ${_list_values})                     _message(${_message_type} "cmakemocks_clearlists(${_name}): \"${_value}\"")                 endforeach()             endif()             _set_property(global property ${_name} "")         endforeach()     endif() endfunction() 

function(cmakemocks_pushcall _name _str)     _message("cmakemocks_pushcall(${_name}): \"${_str}\"")     _set_property(global append property mocklists "${_name}")     _set_property(global append property ${_name} "${_str}") endfunction()  function(cmakemocks_popcall _name _str)     _get_property(_list global property ${_name})     set(_idx -1)     list(find _list "${_str}" _idx)     if ((not "${_list}" strequal "") , (not ${_idx} equal -1))         _message("cmakemocks_popcall(${_name}): \"${_str}\"")         list(remove_at _list ${_idx})         _set_property(global property ${_name} ${_list})     else()         _message(fatal_error "cmakemocks_popcall(${_name}): no \"${_str}\"")     endif() endfunction() 

function(cmakemocks_expectcall _name _str)     _message("cmakemocks_expectcall(${_name}): \"${_str}\" -> \"${argn}\"")     _set_property(global append property mocklists "${_name}")     string(replace ";" "|" _value_str "${argn}")     _set_property(global append property ${_name} "${_str} <<<${_value_str}>>>") endfunction()  function(cmakemocks_getexpect _name _str _ret)     if(not defined ${_ret})         _message(send_error "cmakemocks_getexpect: ${_ret} given _ret parameter in not defined variable. please specify proper variable name parameter.")     endif()      _message("cmakemocks_getexpect(${_name}): \"${_str}\"")     _get_property(_list_values global property ${_name})      set(_value_str "")      foreach(_value in items ${_list_values})         set(_idx -1)         string(find "${_value}" "${_str}" _idx)         if ((not "${_value}" strequal "") , (not ${_idx} equal -1))             list(remove_item _list_values "${_value}")             _set_property(global property ${_name} ${_list_values})              string(find "${_value}" "<<<" _start)             string(find "${_value}" ">>>" _end)             math(expr _start "${_start} + 3")             math(expr _len "${_end} - ${_start}")             string(substring "${_value}" ${_start} ${_len} _value_str)             string(replace "|" ";" _value_list "${_value_str}")             set(${_ret} "${_value_list}" parent_scope)             break()         endif()     endforeach() endfunction() 

the mockups

by adding mockups like:

macro(add_library)     string(replace ";" " " _str "${argn}")     cmakemocks_pushcall(mocklibraries "${_str}") endmacro()  macro(get_target_property _var)     string(replace ";" " " _str "${argn}")     set(${_var} "[null]")     cmakemocks_getexpect(mockgettargetproperties "${_str}" ${_var}) endmacro() 

the tests

i can write test this:

myunittests.cmake

cmakemocks_expectcall(mockgettargetproperties "mylib type" "static_library") my_add_library(mylib "src/test1.cc") cmakemocks_popcall(mocklibraries "mylib src/test1.cc") ... cmakemocks_clearlists(status) 

and include cmake projects with:

cmakelists.txt

add_test(     name testmycmake      command ${cmake_command} -p "myunittests.cmake" ) 

Popular posts from this blog

c# - ODP.NET Oracle.ManagedDataAccess causes ORA-12537 network session end of file -

matlab - Compression and Decompression of ECG Signal using HUFFMAN ALGORITHM -

utf 8 - split utf-8 string into bytes in python -