最近拜读了Kent Beck大神的《Test-Driven Development By Example》,有了这篇读书笔记。这本书解答了我的很多开发中遇到的困惑,所以决定以后走上TDD的道路。那为什么会学习UnixTest++,其实是因为惠普打印机的Phoenix FW里面曾经有先辈做过类似unit test的事情,称之为Linux Test Harness。Harnes是马鞍的意思,这个名字应该是惠普人自己取的。这个Linux Test Harness就是基于UnixTest++的。目前我用的是最新版,v1.5.1。目录树结构如下:
├── AUTHORS
├── CMakeLists.txt
├── ChangeLog
├── INSTALL
├── LICENSE
├── Makefile.am
├── README.md
├── UnitTest++
├── UnitTest++.pc.in
├── appveyor.yml
├── builds
├── configure.ac
├── docs
├── m4
│ ├── ax_cxx_compile_stdcxx.m4
│ └── ax_cxx_compile_stdcxx_11.m4
└── tests
7 directories, 95 files
重要的文件或文件夹我标成了红色。
- CMakeLists.txt
- UnitTest++是基于CMake的,后面会具体讲CMake,这个文件就类似于CMake的工程文件。CMake基于它生成Makefile或者其他开发平台的工程文件。
- UnitTest++
- UnitTest++是开源项目,这个文件夹就是UnitTest++所有的源码
- tests
- 这个是UnitTest++本身的test case。我们在写自己的test case的时候完全可以参考别人是怎么写的。
这里收集了两篇CMake的文章,CMake使用总结和CMake 入门实战
CMake意为Cross-platform Make,可用于管理C/C++工程。你或许听过好几种 Make 工具,例如 GNU Make ,QT 的 qmake ,微软的 MS nmake,BSD Make(pmake),Makepp,等等。这些 Make 工具遵循着不同的规范和标准,所执行的 Makefile 格式也千差万别。这样就带来了一个严峻的问题:如果软件想跨平台,必须要保证能够在不同平台编译。而如果使用上面的 Make 工具,就得为每一种标准写一次 Makefile ,这将是一件让人抓狂的工作。就是针对这个问题所设计的工具。它首先允许开发者编写一种平台无关的 CMakeList.txt 文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化 Makefile 和工程文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程。从而做到“Write once, run everywhere”。
在 linux 平台下使用 CMake 生成 Makefile 并编译的流程如下:
- 编写 CMake 配置文件
CMakeLists.txt
。 - 执行命令
cmake -G "Unix Makefiles" <PATH>
生成Unix识别的Makefile[^support],<PATH>是 CMakeLists.txt 所在的目录。也可以用ccmake,ccmake 和 cmake 的区别在于前者提供了一个交互式的界面。 - 使用 make 命令进行编译。
以UnitTest++自带的CMakeLists.txt为例:
cmake_minimum_required(VERSION 2.8.1)
project(UnitTest++)
# get the main sources
file(GLOB headers_ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} UnitTest++/*.h)
file(GLOB sources_ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} UnitTest++/*.cpp)
source_group("" FILES ${headers_} ${sources_})
# get platform specific sources
if (WIN32)
add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
set(platformDir_ Win32)
else()
set(platformDir_ Posix)
endif(WIN32)
file(GLOB platformHeaders_ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} UnitTest++/${platformDir_}/*.h)
file(GLOB platformSources_ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} UnitTest++/${platformDir_}/*.cpp)
source_group(${platformDir_} FILES ${platformHeaders_} ${platformSources_})
# create the lib
add_library(UnitTest++ STATIC ${headers_} ${sources_} ${platformHeaders_} ${platformSources_})
# build the test runner
file(GLOB TEST_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} tests/*.cpp tests/*.h)
source_group( "" FILES ${TEST_SRCS})
add_executable(TestUnitTest++ ${TEST_SRCS})
include_directories(.)
if(${UTPP_USE_PLUS_SIGN})
set_target_properties(TestUnitTest++ PROPERTIES OUTPUT_NAME TestUnitTest++)
endif()
target_link_libraries(TestUnitTest++ UnitTest++)
# run unit tests as post build step
add_custom_command(TARGET TestUnitTest++
POST_BUILD COMMAND TestUnitTest++
COMMENT "Running unit tests")
set, file, add_library等等都是命令,具体命令可以参考这个笔记CMake使用总结。
- add_library(UnitTest++…)将UnitTest++代码编译成静态库
- add_executable(TestUnitTest++ …)生成UnitTest++应用文件
- target_link_libraries(TestUnitTest++ UnitTest++)将前面生成的libUnitTest++.a链入TestUnitTest++可执行文件。
- add_custom_command(TARGET TestUnitTest++…)这一行决定了运行make时,额外调用的命令。
CMake使用总结这篇笔记里提到:
按照官方文档的说法,不建议使用file的GLOB指令来收集工程的源文件,原文解释如下
We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.
大意就是,GLOB收集的源文件增加或删除,而CMakeLists.txt没有发生修改时,CMake不能识别这些文件。其实,当CMakeLists.txt使用aux_source_directory和file glob查找工程源文件时,如果添加或删除源文件,都需要重新运行CMake。
cmake 如何编出可以GDB的程序?
cmake -DCMAKE_BUILD_TYPE=Debug CMakeList.txt
Test Case的编写通过UnixTest++本身的宏引入:
SUITE(MyUnitTests)
{
TEST(StarterTest)
{
MonoGraphCpInit(false);
CHECK(true);
}
}
运行make之后的输出为:
Running unit tests
Success: 2 tests passed.
Test time: 7.54 seconds.
[100%] Built target MyTest
TEST宏引入的就是一个test case,SUITE宏引入的是一个测试套件。默认情况下,所有用SUITE或者TEST定义的case都会被运行,看main code。
int main(int, const char *[])
{
return UnitTest::RunAllTests();
}
因为我们有UnitTest++的源码,其实想怎么测都可以。经过学习,如果想调用指定case的main code可以如下编写:
UnitTest::TestReporterStdout reporter;
UnitTest::TestRunner runner(reporter);
return runner.RunTestsIf(UnitTest::Test::GetTestList(), "MyUnitTests", UnitTest::True(), 0);
这段code调用了名字叫MyUnitTests的SUITE中所有case。
Phoenix FW里面的Linux Test Harness是基于UnixTest++的。可以参考components/GCP/JsonDataModel/linux_test_harness/Makefile
。其中用到的UnixTest++是v1.4的,并没有用到cmake来构建。而是自己构建的Makefile来编译。运用最新的cmake来搭建Unit Test环境感觉更简单,而且竟然还能有平台移植性,虽然目前对我们没用,不过还是很赞的。将UnixTest++编译到可用还是挺简单的,但是要整合Phoenix code有那么一点麻烦。先讲一下我们的使用场景,测试Mono Graphic Panel Driver。再将具体搭建的思路和一些小tips。
这里有一篇相关笔记Pheonix_Display。我其实想做的是在Mono Graphic Panel Driver中添加一个Recovery Thread。先看下源码架构:
[benzhou@plslx111 phx]$ ls components/bsp/control_panel/
abc buttonLed ccpi clcd inc monoGraph obj pub src
monoGraph
中的代码会调用到abc文件夹下的代码。所以linux_test_harness
就放在这个文件夹下。并且abc
和monoGraph
中的代码需要被链接到我们的测试程序中。
cmake_minimum_required(VERSION 2.8.1)
project(MyTest)
set(CMAKE_C_COMPILER "g++")
# enable gdb
set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
set(PHX_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../")
include_directories(..)
include_directories(stubs)
include_directories(${PHX_DIR}components/bsp/control_panel/monoGraph/pub/)
include_directories(${PHX_DIR}components/bsp/control_panel/monoGraph/inc/)
include_directories(${PHX_DIR}components/bsp/control_panel/abc/pub/)
include_directories(${PHX_DIR}components/bsp/control_panel/abc/inc/)
include_directories(${PHX_DIR}components/bsp/control_panel/pub/)
include_directories(${PHX_DIR}components/bsp/control_panel/inc/)
include_directories(${PHX_DIR}components/primboot/pub/)
# get Phoenix code
#file(GLOB PHX_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ../../../src/*.cpp ../../../src/*.c)
aux_source_directory(${PHX_DIR}/components/bsp/control_panel/abc/src PHX_ABC)
aux_source_directory(${PHX_DIR}/components/bsp/control_panel/monoGraph/src PHX_MONO)
list(APPEND PHX_SRCS
${PHX_ABC}
${PHX_MONO}
)
add_library (PhxFunctions STATIC ${PHX_SRCS})
# get the Phoenix stub sources
aux_source_directory(${PHX_DIR}/components/bsp/control_panel/linux_test_harness/mytests/stubs PHX_STUBS)
add_library (StubFunctions STATIC ${PHX_STUBS})
# get the main sources
aux_source_directory(${PHX_DIR}/components/bsp/control_panel/linux_test_harness/mytests TEST_SRCS)
add_executable(MyTest ${TEST_SRCS})
target_link_libraries(MyTest
pthread
UnitTest++
PhxFunctions
StubFunctions
)
# run unit tests as post build step
add_custom_command(TARGET MyTest
POST_BUILD COMMAND MyTest
COMMENT "Running unit tests"
)
除了UnitTest++框架本身的库libUnitTest++.a和链入了一个pthread库以外,我们还定义了另外两个库PhxFunctions和StubFunctions。
- PhxFunctions是我们想测试的code,即
abc
和monoGraph
文件夹 - StubFunctions是为了编译通过,定义的一些存根函数
主要需要注意的是怎么定义这些存根文件和函数。根据我的经验和TDD思想(不要为了明天设计),应该注意:
- 如果有找不到的头文件,在stubs文件夹里加一个空文件
- 如果有找不到的类声明,从FW找到类定义拷贝过来
- 如果有找不到定义的函数的链接错误,就在stub.cpp中定义空函数。
- 如果将来发现需要调用真实的FW函数,就需要将那个函数所在的源码文件编译成库链接进来。
%23UnitTest++%u7B80%u4ECB%0A@%28%u5B66%u4E60%u7B14%u8BB0%29%5BTDD%2C%20Programming%2C%20unittest%5D%0A%0A%5BTOC%5D%0A%0A%u6700%u8FD1%u62DC%u8BFB%u4E86Kent%20Beck%u5927%u795E%u7684%u300ATest-Driven%20Development%20By%20Example%u300B%uFF0C%u6709%u4E86%u8FD9%u7BC7%5B%u8BFB%u4E66%u7B14%u8BB0%5D%28https%3A//www.evernote.com/shard/s24/nl/697376807/209575d9-d1bc-4aa6-8a79-3d50bfe3d377/%29%u3002%u8FD9%u672C%u4E66%u89E3%u7B54%u4E86%u6211%u7684%u5F88%u591A%u5F00%u53D1%u4E2D%u9047%u5230%u7684%u56F0%u60D1%uFF0C%u6240%u4EE5%u51B3%u5B9A%u4EE5%u540E%u8D70%u4E0ATDD%u7684%u9053%u8DEF%u3002%u90A3%u4E3A%u4EC0%u4E48%u4F1A%u5B66%u4E60UnixTest++%uFF0C%u5176%u5B9E%u662F%u56E0%u4E3A%u60E0%u666E%u6253%u5370%u673A%u7684Phoenix%20FW%u91CC%u9762%u66FE%u7ECF%u6709%u5148%u8F88%u505A%u8FC7%u7C7B%u4F3Cunit%20test%u7684%u4E8B%u60C5%uFF0C%u79F0%u4E4B%u4E3ALinux%20Test%20Harness%u3002Harnes%u662F%u9A6C%u978D%u7684%u610F%u601D%uFF0C%u8FD9%u4E2A%u540D%u5B57%u5E94%u8BE5%u662F%u60E0%u666E%u4EBA%u81EA%u5DF1%u53D6%u7684%u3002%u8FD9%u4E2ALinux%20Test%20Harness%u5C31%u662F%u57FA%u4E8E%5BUnixTest++%5D%28https%3A//github.com/unittest-cpp/unittest-cpp%29%u7684%u3002%u76EE%u524D%u6211%u7528%u7684%u662F%u6700%u65B0%u7248%uFF0Cv1.5.1%u3002%u76EE%u5F55%u6811%u7ED3%u6784%u5982%u4E0B%uFF1A%0A%u251C%u2500%u2500%20AUTHORS%0A%u251C%u2500%u2500%20%3Cfont%20color%3D%22IndianRed%22%3ECMakeLists.txt%3C/font%3E%0A%u251C%u2500%u2500%20ChangeLog%0A%u251C%u2500%u2500%20INSTALL%0A%u251C%u2500%u2500%20LICENSE%0A%u251C%u2500%u2500%20Makefile.am%0A%u251C%u2500%u2500%20README.md%0A%u251C%u2500%u2500%20%3Cfont%20color%3D%22IndianRed%22%3EUnitTest++%3C/font%3E%0A%u251C%u2500%u2500%20UnitTest++.pc.in%0A%u251C%u2500%u2500%20appveyor.yml%0A%u251C%u2500%u2500%20builds%0A%u251C%u2500%u2500%20configure.ac%0A%u251C%u2500%u2500%20docs%0A%u251C%u2500%u2500%20m4%0A%u2502%20%20%20%u251C%u2500%u2500%20ax_cxx_compile_stdcxx.m4%0A%u2502%20%20%20%u2514%u2500%u2500%20ax_cxx_compile_stdcxx_11.m4%0A%u2514%u2500%u2500%20%3Cfont%20color%3D%22IndianRed%22%3Etests%3C/font%3E%0A%0A7%20directories%2C%2095%20files%0A%u91CD%u8981%u7684%u6587%u4EF6%u6216%u6587%u4EF6%u5939%u6211%u6807%u6210%u4E86%u7EA2%u8272%u3002%0A-%20CMakeLists.txt%0A%09-%20UnitTest++%u662F%u57FA%u4E8ECMake%u7684%uFF0C%u540E%u9762%u4F1A%u5177%u4F53%u8BB2CMake%uFF0C%u8FD9%u4E2A%u6587%u4EF6%u5C31%u7C7B%u4F3C%u4E8ECMake%u7684%u5DE5%u7A0B%u6587%u4EF6%u3002CMake%u57FA%u4E8E%u5B83%u751F%u6210Makefile%u6216%u8005%u5176%u4ED6%u5F00%u53D1%u5E73%u53F0%u7684%u5DE5%u7A0B%u6587%u4EF6%u3002%0A-%20UnitTest++%0A%09-%20UnitTest++%u662F%u5F00%u6E90%u9879%u76EE%uFF0C%u8FD9%u4E2A%u6587%u4EF6%u5939%u5C31%u662FUnitTest++%u6240%u6709%u7684%u6E90%u7801%0A-%20tests%0A%09-%20%u8FD9%u4E2A%u662FUnitTest++%u672C%u8EAB%u7684test%20case%u3002%u6211%u4EEC%u5728%u5199%u81EA%u5DF1%u7684test%20case%u7684%u65F6%u5019%u5B8C%u5168%u53EF%u4EE5%u53C2%u8003%u522B%u4EBA%u662F%u600E%u4E48%u5199%u7684%u3002%0A%0A%23%23CMake%0A%u8FD9%u91CC%u6536%u96C6%u4E86%u4E24%u7BC7CMake%u7684%u6587%u7AE0%uFF0C%5BCMake%u4F7F%u7528%u603B%u7ED3%5D%28https%3A//www.evernote.com/shard/s24/nl/697376807/d90d734c-12e4-4664-a0d5-af887f4b8b10/%29%u548C%5BCMake%20%u5165%u95E8%u5B9E%u6218%5D%28https%3A//www.evernote.com/shard/s24/nl/697376807/50e6782c-3acc-42a7-b582-43fe4a381fc8/%29%0ACMake%u610F%u4E3ACross-platform%20Make%uFF0C%u53EF%u7528%u4E8E%u7BA1%u7406C/C++%u5DE5%u7A0B%u3002%u4F60%u6216%u8BB8%u542C%u8FC7%u597D%u51E0%u79CD%20Make%20%u5DE5%u5177%uFF0C%u4F8B%u5982%20GNU%20Make%20%uFF0CQT%20%u7684%20qmake%20%uFF0C%u5FAE%u8F6F%u7684%20MS%20nmake%uFF0CBSD%20Make%uFF08pmake%uFF09%uFF0CMakepp%uFF0C%u7B49%u7B49%u3002%u8FD9%u4E9B%20Make%20%u5DE5%u5177%u9075%u5FAA%u7740%u4E0D%u540C%u7684%u89C4%u8303%u548C%u6807%u51C6%uFF0C%u6240%u6267%u884C%u7684%20Makefile%20%u683C%u5F0F%u4E5F%u5343%u5DEE%u4E07%u522B%u3002%u8FD9%u6837%u5C31%u5E26%u6765%u4E86%u4E00%u4E2A%u4E25%u5CFB%u7684%u95EE%u9898%uFF1A%u5982%u679C%u8F6F%u4EF6%u60F3%u8DE8%u5E73%u53F0%uFF0C%u5FC5%u987B%u8981%u4FDD%u8BC1%u80FD%u591F%u5728%u4E0D%u540C%u5E73%u53F0%u7F16%u8BD1%u3002%u800C%u5982%u679C%u4F7F%u7528%u4E0A%u9762%u7684%20Make%20%u5DE5%u5177%uFF0C%u5C31%u5F97%u4E3A%u6BCF%u4E00%u79CD%u6807%u51C6%u5199%u4E00%u6B21%20Makefile%20%uFF0C%u8FD9%u5C06%u662F%u4E00%u4EF6%u8BA9%u4EBA%u6293%u72C2%u7684%u5DE5%u4F5C%u3002%u5C31%u662F%u9488%u5BF9%u8FD9%u4E2A%u95EE%u9898%u6240%u8BBE%u8BA1%u7684%u5DE5%u5177%u3002%u5B83%u9996%u5148%u5141%u8BB8%u5F00%u53D1%u8005%u7F16%u5199%u4E00%u79CD%u5E73%u53F0%u65E0%u5173%u7684%20CMakeList.txt%20%u6587%u4EF6%u6765%u5B9A%u5236%u6574%u4E2A%u7F16%u8BD1%u6D41%u7A0B%uFF0C%u7136%u540E%u518D%u6839%u636E%u76EE%u6807%u7528%u6237%u7684%u5E73%u53F0%u8FDB%u4E00%u6B65%u751F%u6210%u6240%u9700%u7684%u672C%u5730%u5316%20Makefile%20%u548C%u5DE5%u7A0B%u6587%u4EF6%uFF0C%u5982%20Unix%20%u7684%20Makefile%20%u6216%20Windows%20%u7684%20Visual%20Studio%20%u5DE5%u7A0B%u3002%u4ECE%u800C%u505A%u5230%u201CWrite%20once%2C%20run%20everywhere%u201D%u3002%0A%09%u5728%20linux%20%u5E73%u53F0%u4E0B%u4F7F%u7528%20CMake%20%u751F%u6210%20Makefile%20%u5E76%u7F16%u8BD1%u7684%u6D41%u7A0B%u5982%u4E0B%uFF1A%0A1.%20%u7F16%u5199%20CMake%20%u914D%u7F6E%u6587%u4EF6%20%60CMakeLists.txt%60%20%u3002%0A2.%20%u6267%u884C%u547D%u4EE4%60cmake%20-G%20%22Unix%20Makefiles%22%20%3CPATH%3E%60%u751F%u6210Unix%u8BC6%u522B%u7684Makefile%5B%5Esupport%5D%uFF0C%26lt%3BPATH%26gt%3B%u662F%20CMakeLists.txt%20%u6240%u5728%u7684%u76EE%u5F55%u3002%u4E5F%u53EF%u4EE5%u7528ccmake%uFF0Cccmake%20%u548C%20cmake%20%u7684%u533A%u522B%u5728%u4E8E%u524D%u8005%u63D0%u4F9B%u4E86%u4E00%u4E2A%u4EA4%u4E92%u5F0F%u7684%u754C%u9762%u3002%0A3.%20%u4F7F%u7528%20make%20%u547D%u4EE4%u8FDB%u884C%u7F16%u8BD1%u3002%0A%u4EE5UnitTest++%u81EA%u5E26%u7684CMakeLists.txt%u4E3A%u4F8B%uFF1A%0A%60%60%60cmake%0Acmake_minimum_required%28VERSION%202.8.1%29%0Aproject%28UnitTest++%29%0A%0A%23%20get%20the%20main%20sources%0Afile%28GLOB%20headers_%20RELATIVE%20%24%7BCMAKE_CURRENT_SOURCE_DIR%7D%20UnitTest++/*.h%29%0Afile%28GLOB%20sources_%20RELATIVE%20%24%7BCMAKE_CURRENT_SOURCE_DIR%7D%20UnitTest++/*.cpp%29%0Asource_group%28%22%22%20FILES%20%24%7Bheaders_%7D%20%24%7Bsources_%7D%29%0A%0A%23%20get%20platform%20specific%20sources%0Aif%20%28WIN32%29%0A%20%20%20%20add_definitions%28-D_CRT_SECURE_NO_DEPRECATE%29%0A%20%20%20%20set%28platformDir_%20Win32%29%0Aelse%28%29%0A%20%20%20%20set%28platformDir_%20Posix%29%0Aendif%28WIN32%29%0A%0Afile%28GLOB%20platformHeaders_%20RELATIVE%20%24%7BCMAKE_CURRENT_SOURCE_DIR%7D%20UnitTest++/%24%7BplatformDir_%7D/*.h%29%0Afile%28GLOB%20platformSources_%20RELATIVE%20%24%7BCMAKE_CURRENT_SOURCE_DIR%7D%20UnitTest++/%24%7BplatformDir_%7D/*.cpp%29%0Asource_group%28%24%7BplatformDir_%7D%20FILES%20%24%7BplatformHeaders_%7D%20%24%7BplatformSources_%7D%29%0A%0A%23%20create%20the%20lib%0Aadd_library%28UnitTest++%20STATIC%20%24%7Bheaders_%7D%20%24%7Bsources_%7D%20%24%7BplatformHeaders_%7D%20%24%7BplatformSources_%7D%29%0A%0A%23%20build%20the%20test%20runner%0Afile%28GLOB%20TEST_SRCS%20RELATIVE%20%24%7BCMAKE_CURRENT_SOURCE_DIR%7D%20tests/*.cpp%20tests/*.h%29%0Asource_group%28%20%22%22%20FILES%20%24%7BTEST_SRCS%7D%29%0Aadd_executable%28TestUnitTest++%20%24%7BTEST_SRCS%7D%29%0Ainclude_directories%28.%29%0A%0Aif%28%24%7BUTPP_USE_PLUS_SIGN%7D%29%0A%20%20%20%20set_target_properties%28TestUnitTest++%20PROPERTIES%20OUTPUT_NAME%20TestUnitTest++%29%0Aendif%28%29%0A%0Atarget_link_libraries%28TestUnitTest++%20UnitTest++%29%0A%0A%23%20run%20unit%20tests%20as%20post%20build%20step%0Aadd_custom_command%28TARGET%20TestUnitTest++%0A%20%20%20%20POST_BUILD%20COMMAND%20TestUnitTest++%0A%20%20%20%20COMMENT%20%22Running%20unit%20tests%22%29%0A%60%60%60%0Aset%2C%20file%2C%20add_library%u7B49%u7B49%u90FD%u662F%u547D%u4EE4%uFF0C%u5177%u4F53%u547D%u4EE4%u53EF%u4EE5%u53C2%u8003%u8FD9%u4E2A%u7B14%u8BB0%5BCMake%u4F7F%u7528%u603B%u7ED3%5D%28https%3A//www.evernote.com/shard/s24/nl/697376807/d90d734c-12e4-4664-a0d5-af887f4b8b10/%29%u3002%0A-%20add_library%28UnitTest++...%29%u5C06UnitTest++%u4EE3%u7801%u7F16%u8BD1%u6210%u9759%u6001%u5E93%0A-%20add_executable%28TestUnitTest++%20...%29%u751F%u6210UnitTest++%u5E94%u7528%u6587%u4EF6%0A-%20target_link_libraries%28TestUnitTest++%20UnitTest++%29%u5C06%u524D%u9762%u751F%u6210%u7684libUnitTest++.a%u94FE%u5165TestUnitTest++%u53EF%u6267%u884C%u6587%u4EF6%u3002%0A-%20add_custom_command%28TARGET%20TestUnitTest++...%29%u8FD9%u4E00%u884C%u51B3%u5B9A%u4E86%u8FD0%u884Cmake%u65F6%uFF0C%u989D%u5916%u8C03%u7528%u7684%u547D%u4EE4%u3002%0A%0A%5BCMake%u4F7F%u7528%u603B%u7ED3%5D%28https%3A//www.evernote.com/shard/s24/nl/697376807/d90d734c-12e4-4664-a0d5-af887f4b8b10/%29%u8FD9%u7BC7%u7B14%u8BB0%u91CC%u63D0%u5230%uFF1A%0A%3E%u6309%u7167%u5B98%u65B9%u6587%u6863%u7684%u8BF4%u6CD5%uFF0C%u4E0D%u5EFA%u8BAE%u4F7F%u7528file%u7684GLOB%u6307%u4EE4%u6765%u6536%u96C6%u5DE5%u7A0B%u7684%u6E90%u6587%u4EF6%uFF0C%u539F%u6587%u89E3%u91CA%u5982%u4E0B%0A%3Cfont%20color%3D%22Blue%22%3EWe%20do%20not%20recommend%20using%20GLOB%20to%20collect%20a%20list%20of%20source%20files%20from%20your%20source%20tree.%20If%20no%20CMakeLists.txt%20file%20changes%20when%20a%20source%20is%20added%20or%20removed%20then%20the%20generated%20build%20system%20cannot%20know%20when%20to%20ask%20CMake%20to%20regenerate.%3C/font%3E%0A%u5927%u610F%u5C31%u662F%uFF0CGLOB%u6536%u96C6%u7684%u6E90%u6587%u4EF6%u589E%u52A0%u6216%u5220%u9664%uFF0C%u800CCMakeLists.txt%u6CA1%u6709%u53D1%u751F%u4FEE%u6539%u65F6%uFF0CCMake%u4E0D%u80FD%u8BC6%u522B%u8FD9%u4E9B%u6587%u4EF6%u3002%u5176%u5B9E%uFF0C%u5F53CMakeLists.txt%u4F7F%u7528aux_source_directory%u548Cfile%20glob%u67E5%u627E%u5DE5%u7A0B%u6E90%u6587%u4EF6%u65F6%uFF0C%3Cb%3E%3Cfont%20color%3D%22IndianRed%22%3E%u5982%u679C%u6DFB%u52A0%u6216%u5220%u9664%u6E90%u6587%u4EF6%uFF0C%u90FD%u9700%u8981%u91CD%u65B0%u8FD0%u884CCMake%3C/font%3E%3C/b%3E%u3002%0A%0Acmake%20%u5982%u4F55%u7F16%u51FA%u53EF%u4EE5GDB%u7684%u7A0B%u5E8F%uFF1F%0A%3E%60cmake%20-DCMAKE_BUILD_TYPE%3DDebug%20CMakeList.txt%60%0A%23%23Implement%20Test%20Cases%0ATest%20Case%u7684%u7F16%u5199%u901A%u8FC7UnixTest++%u672C%u8EAB%u7684%u5B8F%u5F15%u5165%uFF1A%0A%60%60%60cpp%0A%20%20%20%20SUITE%28MyUnitTests%29%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20TEST%28StarterTest%29%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20MonoGraphCpInit%28false%29%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20CHECK%28true%29%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%60%60%60%0A%u8FD0%u884Cmake%u4E4B%u540E%u7684%u8F93%u51FA%u4E3A%uFF1A%0A%3ERunning%20unit%20tests%0ASuccess%3A%202%20tests%20passed.%0ATest%20time%3A%207.54%20seconds.%0A%5B100%25%5D%20Built%20target%20MyTest%0A%0ATEST%u5B8F%u5F15%u5165%u7684%u5C31%u662F%u4E00%u4E2Atest%20case%uFF0CSUITE%u5B8F%u5F15%u5165%u7684%u662F%u4E00%u4E2A%u6D4B%u8BD5%u5957%u4EF6%u3002%u9ED8%u8BA4%u60C5%u51B5%u4E0B%uFF0C%u6240%u6709%u7528SUITE%u6216%u8005TEST%u5B9A%u4E49%u7684case%u90FD%u4F1A%u88AB%u8FD0%u884C%uFF0C%u770Bmain%20code%u3002%0A%60%60%60cpp%0Aint%20main%28int%2C%20const%20char%20*%5B%5D%29%0A%7B%0A%20%20%20return%20UnitTest%3A%3ARunAllTests%28%29%3B%0A%7D%0A%60%60%60%0A%u56E0%u4E3A%u6211%u4EEC%u6709UnitTest++%u7684%u6E90%u7801%uFF0C%u5176%u5B9E%u60F3%u600E%u4E48%u6D4B%u90FD%u53EF%u4EE5%u3002%u7ECF%u8FC7%u5B66%u4E60%uFF0C%u5982%u679C%u60F3%u8C03%u7528%u6307%u5B9Acase%u7684main%20code%u53EF%u4EE5%u5982%u4E0B%u7F16%u5199%uFF1A%0A%60%60%60cpp%0A%20%20%20UnitTest%3A%3ATestReporterStdout%20reporter%3B%0A%20%20%20UnitTest%3A%3ATestRunner%20runner%28reporter%29%3B%0A%20%20%20return%20runner.RunTestsIf%28UnitTest%3A%3ATest%3A%3AGetTestList%28%29%2C%20%22MyUnitTests%22%2C%20UnitTest%3A%3ATrue%28%29%2C%200%29%3B%0A%60%60%60%0A%u8FD9%u6BB5code%u8C03%u7528%u4E86%u540D%u5B57%u53EBMyUnitTests%u7684SUITE%u4E2D%u6240%u6709case%u3002%0A%0A%23%23Linux%20Test%20Harness%0APhoenix%20FW%u91CC%u9762%u7684Linux%20Test%20Harness%u662F%u57FA%u4E8EUnixTest++%u7684%u3002%u53EF%u4EE5%u53C2%u8003%60components/GCP/JsonDataModel/linux_test_harness/Makefile%60%u3002%u5176%u4E2D%u7528%u5230%u7684UnixTest++%u662Fv1.4%u7684%uFF0C%u5E76%u6CA1%u6709%u7528%u5230cmake%u6765%u6784%u5EFA%u3002%u800C%u662F%u81EA%u5DF1%u6784%u5EFA%u7684Makefile%u6765%u7F16%u8BD1%u3002%u8FD0%u7528%u6700%u65B0%u7684cmake%u6765%u642D%u5EFAUnit%20Test%u73AF%u5883%u611F%u89C9%u66F4%u7B80%u5355%uFF0C%u800C%u4E14%u7ADF%u7136%u8FD8%u80FD%u6709%u5E73%u53F0%u79FB%u690D%u6027%uFF0C%u867D%u7136%u76EE%u524D%u5BF9%u6211%u4EEC%u6CA1%u7528%uFF0C%u4E0D%u8FC7%u8FD8%u662F%u5F88%u8D5E%u7684%u3002%u5C06UnixTest++%u7F16%u8BD1%u5230%u53EF%u7528%u8FD8%u662F%u633A%u7B80%u5355%u7684%uFF0C%u4F46%u662F%u8981%u6574%u5408Phoenix%20code%u6709%u90A3%u4E48%u4E00%u70B9%u9EBB%u70E6%u3002%u5148%u8BB2%u4E00%u4E0B%u6211%u4EEC%u7684%u4F7F%u7528%u573A%u666F%uFF0C%u6D4B%u8BD5Mono%20Graphic%20Panel%20Driver%u3002%u518D%u5C06%u5177%u4F53%u642D%u5EFA%u7684%u601D%u8DEF%u548C%u4E00%u4E9B%u5C0Ftips%u3002%0A%0A%23%23%23Mono%20Graphic%20Panel%20Driver%0A%u8FD9%u91CC%u6709%u4E00%u7BC7%u76F8%u5173%u7B14%u8BB0%5BPheonix_Display%5D%28https%3A//www.evernote.com/shard/s24/nl/2724128/9cf701b0-e736-43d5-9411-923afacf2344%29%u3002%u6211%u5176%u5B9E%u60F3%u505A%u7684%u662F%u5728Mono%20Graphic%20Panel%20Driver%u4E2D%u6DFB%u52A0%u4E00%u4E2ARecovery%20Thread%u3002%u5148%u770B%u4E0B%u6E90%u7801%u67B6%u6784%uFF1A%0A%3E%5Bbenzhou@plslx111%20phx%5D%24%20ls%20components/bsp/control_panel/%0Aabc%20%20buttonLed%20%20ccpi%20%20clcd%20%20inc%20%20%3Cfont%20color%3D%22IndianRed%22%3EmonoGraph%3C/font%3E%20%20obj%20%20pub%20%20src%0A%0A%60monoGraph%60%u4E2D%u7684%u4EE3%u7801%u4F1A%u8C03%u7528%u5230abc%u6587%u4EF6%u5939%u4E0B%u7684%u4EE3%u7801%u3002%u6240%u4EE5%60linux_test_harness%60%u5C31%u653E%u5728%u8FD9%u4E2A%u6587%u4EF6%u5939%u4E0B%u3002%u5E76%u4E14%60abc%60%u548C%60monoGraph%60%u4E2D%u7684%u4EE3%u7801%u9700%u8981%u88AB%u94FE%u63A5%u5230%u6211%u4EEC%u7684%u6D4B%u8BD5%u7A0B%u5E8F%u4E2D%u3002%0A%0A%23%23%23%u6D4B%u8BD5%u67B6%u6784%0A%u6700%u540E%u6211%u4EEC%u7684%60CMakeLists.txt%60%u5982%u4E0B%uFF1A%0A%60%60%60cmake%0Acmake_minimum_required%28VERSION%202.8.1%29%0Aproject%28MyTest%29%0A%0Aset%28CMAKE_C_COMPILER%20%22g++%22%29%0A%0A%23%20enable%20gdb%0Aset%28CMAKE_BUILD_TYPE%20%22Debug%22%29%0Aset%28CMAKE_CXX_FLAGS_DEBUG%20%22%24ENV%7BCXXFLAGS%7D%20-O0%20-Wall%20-g%20-ggdb%22%29%0Aset%28CMAKE_CXX_FLAGS_RELEASE%20%22%24ENV%7BCXXFLAGS%7D%20-O3%20-Wall%22%29%0A%0Aset%28PHX_DIR%20%22%24%7BCMAKE_CURRENT_SOURCE_DIR%7D/../../../../../%22%29%0A%0Ainclude_directories%28..%29%0Ainclude_directories%28stubs%29%0Ainclude_directories%28%24%7BPHX_DIR%7Dcomponents/bsp/control_panel/monoGraph/pub/%29%0Ainclude_directories%28%24%7BPHX_DIR%7Dcomponents/bsp/control_panel/monoGraph/inc/%29%0Ainclude_directories%28%24%7BPHX_DIR%7Dcomponents/bsp/control_panel/abc/pub/%29%0Ainclude_directories%28%24%7BPHX_DIR%7Dcomponents/bsp/control_panel/abc/inc/%29%0Ainclude_directories%28%24%7BPHX_DIR%7Dcomponents/bsp/control_panel/pub/%29%0Ainclude_directories%28%24%7BPHX_DIR%7Dcomponents/bsp/control_panel/inc/%29%0Ainclude_directories%28%24%7BPHX_DIR%7Dcomponents/primboot/pub/%29%0A%0A%23%20get%20Phoenix%20code%0A%23file%28GLOB%20PHX_SRCS%20RELATIVE%20%24%7BCMAKE_CURRENT_SOURCE_DIR%7D%20../../../src/*.cpp%20../../../src/*.c%29%0Aaux_source_directory%28%24%7BPHX_DIR%7D/components/bsp/control_panel/abc/src%20PHX_ABC%29%0Aaux_source_directory%28%24%7BPHX_DIR%7D/components/bsp/control_panel/monoGraph/src%20PHX_MONO%29%0Alist%28APPEND%20PHX_SRCS%0A%20%20%20%20%24%7BPHX_ABC%7D%0A%20%20%20%20%24%7BPHX_MONO%7D%0A%29%0Aadd_library%20%28PhxFunctions%20STATIC%20%24%7BPHX_SRCS%7D%29%0A%0A%23%20get%20the%20Phoenix%20stub%20sources%0Aaux_source_directory%28%24%7BPHX_DIR%7D/components/bsp/control_panel/linux_test_harness/mytests/stubs%20PHX_STUBS%29%0Aadd_library%20%28StubFunctions%20STATIC%20%24%7BPHX_STUBS%7D%29%0A%0A%23%20get%20the%20main%20sources%0Aaux_source_directory%28%24%7BPHX_DIR%7D/components/bsp/control_panel/linux_test_harness/mytests%20TEST_SRCS%29%0A%0Aadd_executable%28MyTest%20%24%7BTEST_SRCS%7D%29%0A%0Atarget_link_libraries%28MyTest%0A%20%20%20%20pthread%0A%20%20%20%20UnitTest++%0A%20%20%20%20PhxFunctions%0A%20%20%20%20StubFunctions%0A%29%0A%0A%23%20run%20unit%20tests%20as%20post%20build%20step%0Aadd_custom_command%28TARGET%20MyTest%0A%20%20%20%20POST_BUILD%20COMMAND%20MyTest%0A%20%20%20%20COMMENT%20%22Running%20unit%20tests%22%0A%29%0A%60%60%60%0A%u9664%u4E86UnitTest++%u6846%u67B6%u672C%u8EAB%u7684%u5E93libUnitTest++.a%u548C%u94FE%u5165%u4E86%u4E00%u4E2Apthread%u5E93%u4EE5%u5916%uFF0C%u6211%u4EEC%u8FD8%u5B9A%u4E49%u4E86%u53E6%u5916%u4E24%u4E2A%u5E93PhxFunctions%u548CStubFunctions%u3002%0A-%20PhxFunctions%u662F%u6211%u4EEC%u60F3%u6D4B%u8BD5%u7684code%uFF0C%u5373%60abc%60%u548C%60monoGraph%60%u6587%u4EF6%u5939%0A-%20StubFunctions%u662F%u4E3A%u4E86%u7F16%u8BD1%u901A%u8FC7%uFF0C%u5B9A%u4E49%u7684%u4E00%u4E9B%u5B58%u6839%u51FD%u6570%0A%0A%u4E3B%u8981%u9700%u8981%u6CE8%u610F%u7684%u662F%u600E%u4E48%u5B9A%u4E49%u8FD9%u4E9B%u5B58%u6839%u6587%u4EF6%u548C%u51FD%u6570%u3002%u6839%u636E%u6211%u7684%u7ECF%u9A8C%u548CTDD%u601D%u60F3%28%u4E0D%u8981%u4E3A%u4E86%u660E%u5929%u8BBE%u8BA1%29%uFF0C%u5E94%u8BE5%u6CE8%u610F%uFF1A%0A-%20%u5982%u679C%u6709%u627E%u4E0D%u5230%u7684%u5934%u6587%u4EF6%uFF0C%u5728stubs%u6587%u4EF6%u5939%u91CC%u52A0%u4E00%u4E2A%u7A7A%u6587%u4EF6%0A-%20%u5982%u679C%u6709%u627E%u4E0D%u5230%u7684%u7C7B%u58F0%u660E%uFF0C%u4ECEFW%u627E%u5230%u7C7B%u5B9A%u4E49%u62F7%u8D1D%u8FC7%u6765%0A-%20%u5982%u679C%u6709%u627E%u4E0D%u5230%u5B9A%u4E49%u7684%u51FD%u6570%u7684%u94FE%u63A5%u9519%u8BEF%uFF0C%u5C31%u5728stub.cpp%u4E2D%u5B9A%u4E49%u7A7A%u51FD%u6570%u3002%0A-%20%u5982%u679C%u5C06%u6765%u53D1%u73B0%u9700%u8981%u8C03%u7528%u771F%u5B9E%u7684FW%u51FD%u6570%uFF0C%u5C31%u9700%u8981%u5C06%u90A3%u4E2A%u51FD%u6570%u6240%u5728%u7684%u6E90%u7801%u6587%u4EF6%u7F16%u8BD1%u6210%u5E93%u94FE%u63A5%u8FDB%u6765%u3002