# todo 列表 - [ ] clang-format - [ ] c++ 整合 # 軟體安裝 略 # 基本的環境搭建 ## 最基本的 vscode 插件 只需要安裝如下兩個插件即可 c/c++ 擴展是為了最基本的代碼提示和調試支持 cmake language support 是為了提示 CMa ...
todo 列表
軟體安裝
略
基本的環境搭建
最基本的 vscode 插件
只需要安裝如下兩個插件即可
c/c++ 擴展是為了最基本的代碼提示和調試支持
cmake language support 是為了提示 CMakeLists.txt 腳本
有可能安裝了 cmake language support 還是沒有代碼提示, 註意配置 cmake 路徑
代碼
main.cpp
#include <stdio.h>
int main()
{
printf("\nhello world\n\n");
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.24)
project(hello_ubuntu CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_executable(${PROJECT_NAME} main.cpp)
任務配置
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build-debug",
"type": "shell",
"command": "cmake -S . -B cmake-build-debug -DCMAKE_BUILD_TYPE=Debug && cmake --build cmake-build-debug",
"dependsOn": [
"configure"
]
},
{
"label": "build-release",
"type": "shell",
"command": "cmake -S . -B cmake-build-release -DCMAKE_BUILD_TYPE=Release && cmake --build cmake-build-release",
"dependsOn": [
"configure"
]
},
{
"label": "clean",
"type": "shell",
"command": "rm -rf build && rm -rf cmake-build-debug && rm -rf cmake-build-release"
},
{
"label": "rebuild",
"type": "shell",
"dependsOn": [
"clean",
"build-debug",
"build-release"
]
},
{
"label": "run",
"type": "shell",
"command": "./cmake-build-release/hello_ubuntu",
"dependsOn": [
"build-release"
]
}
]
}
此時可以通過終端
菜單的運行任務
來運行
改進任務的運行方式
安裝如下插件
Task Buttons 插件
.vscode
文件夾添加.settings.json
,並添加如下內容
{
"VsCodeTaskButtons.showCounter": true,
"VsCodeTaskButtons.tasks": [
{
"label": "$(notebook-delete-cell) clean",
"task": "clean"
},
{
"label": "$(debug-configure) rebuild",
"task": "rebuild"
},
{
"label": "$(notebook-execute) run",
"task": "run"
}
]
}
然後狀態欄就會出現對應的按鈕, 直接點擊任務對應的按鈕即可運行任務. 圖標從 這裡 獲取
Task Explorer 插件
此插件將提供了一個任務面板, 安裝之後 查看
->打開試圖
搜索Task Explorer
即可打開此面板, 拖到自己喜歡的位置然後直接點擊對應任務右側的按鈕即可運行任務. 任務太多的話, 可以將任務加入 Favorites
列表, 把其他的收起來就可以了
快捷鍵
參考: https://blog.csdn.net/qq_45859188/article/details/124529266
debug
參考 這裡, 直接在 .vscode
文件夾下添加 launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "test-debug",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceRoot}/cmake-build-debug/hello_ubuntu",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "rebuild"
}
]
}
打一個斷點, 然後直接 F5
註意: 有時候 vscode 的 debug 會出問題, 此時直接執行 clean 任務再進行調試即可
C語言 整合
CUnit
參考資料
官網 : https://cunit.sourceforge.net/
github: https://github.com/jacklicn/CUnit
官方手冊: https://cunit.sourceforge.net/doc/index.html
中文手冊: 【單元測試】CUnit用戶手冊(中文)
簡明教程: 【單元測試】CUnit單元測試框架(不支持mock功能)
安裝
sudo apt-get update
sudo apt-get install build-essential automake autoconf libtool
mv configure.in configure.ac
aclocal
autoconf
autoheader
libtoolize --automake --copy --debug --force
automake --add-missing
automake
./configure
make
sudo make install
測試
#include <stdio.h>
#include <string.h>
#include <CUnit/Basic.h>
#include <CUnit/Automated.h>
/* 被測試的函數,在當中故意安裝了一個BUG */
static int sum(int a, int b)
{
if (a > 4)
{
return 0;
}
return (a + b);
}
static int suite_init(void)
{
return 0;
}
static int suite_clean(void)
{
return 0;
}
static void test_sum(void)
{
CU_ASSERT_EQUAL(sum(1, 2), 3);
CU_ASSERT_EQUAL(sum(5, 2), 7);
}
int main()
{
CU_pSuite pSuite = NULL;
/* initialize the CUnit test registry */
if (CUE_SUCCESS != CU_initialize_registry())
{
return CU_get_error();
}
/* add a suite to the registry */
pSuite = CU_add_suite("suite_sum", suite_init, suite_clean);
if (NULL == pSuite)
{
CU_cleanup_registry();
return CU_get_error();
}
/* add the tests to the suite */
if ((NULL == CU_add_test(pSuite, "test_sum", test_sum)))
{
CU_cleanup_registry();
return CU_get_error();
}
// basic
CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests();
// automated
CU_list_tests_to_file();
CU_automated_run_tests();
/* Clean up registry and return */
CU_cleanup_registry();
return CU_get_error();
}
編譯
gcc test.c `pkg-config --libs --cflags cunit` -o test
此時控制台有了 basic 模式的輸出, 並且有了 automated 模式的 xml 文件
laolang@laolang-pc:~/tmp/cunit$ ./test
CUnit - A unit testing framework for C - Version 2.1-3
http://cunit.sourceforge.net/
Suite: suite_sum
Test: test_sum ...FAILED
1. test.c:33 - CU_ASSERT_EQUAL(sum(5, 2),7)
Run Summary: Type Total Ran Passed Failed Inactive
suites 1 1 n/a 0 0
tests 1 1 0 1 0
asserts 2 2 1 1 n/a
Elapsed time = 0.000 seconds
laolang@laolang-pc:~/tmp/cunit$ l
總計 32K
-rw-rw-r-- 1 laolang laolang 1.7K 2023-06-11 18:17:16 CUnitAutomated-Listing.xml
-rw-rw-r-- 1 laolang laolang 1.6K 2023-06-11 18:17:16 CUnitAutomated-Results.xml
-rwxrwxr-x 1 laolang laolang 17K 2023-06-11 18:17:14 test*
-rw-rw-r-- 1 laolang laolang 1.2K 2023-06-11 18:17:02 test.c
laolang@laolang-pc:~/tmp/cunit$
然後從安裝包複製如下幾個文件, 和 cunit 輸出的 xml 同級
- CUnit-List.dtd
- CUnit-List.xsl
- CUnit-Run.dtd
- CUnit-Run.xsl
在本地起一個伺服器, 比如 npm 的 serve, 兩個文件效果如下
關於代碼覆蓋率
日誌
日誌框架有很多, 此處選擇 zlog, 官網寫的非常詳細
github: https://github.com/HardySimpson/zlog/
中文手冊: http://hardysimpson.github.io/zlog/UsersGuide-CN.html
整合結果
目錄結構
laolang@laolang-pc:~/tmp/helloc$ tree -a
.
├── app.log
├── CMakeLists.txt
├── coverage.sh
├── .gitignore
├── resources
│ └── cunit
│ ├── CUnit-List.dtd
│ ├── CUnit-List.xsl
│ ├── CUnit-Run.dtd
│ └── CUnit-Run.xsl
├── src
│ ├── app
│ │ ├── CMakeLists.txt
│ │ └── helloc.c
│ ├── CMakeLists.txt
│ ├── common
│ │ ├── CMakeLists.txt
│ │ ├── common.h
│ │ ├── zlog_conf.c
│ │ └── zlog_conf.h
│ └── datastruct
│ ├── CMakeLists.txt
│ ├── sum.c
│ └── sum.h
├── test
│ ├── CMakeLists.txt
│ ├── maintest.c
│ ├── test_sum.c
│ └── test_sum.h
├── .vscode
│ ├── launch.json
│ ├── settings.json
│ └── tasks.json
└── zlog.conf
8 directories, 26 files
laolang@laolang-pc:~/tmp/helloc$
.vscode
tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "build-debug",
"type": "shell",
"command": "cmake -S . -B cmake-build-debug -DCMAKE_BUILD_TYPE=Debug && cmake --build cmake-build-debug",
"dependsOn": [
"configure"
]
},
{
"label": "build-release",
"type": "shell",
"command": "cmake -S . -B cmake-build-release -DCMAKE_BUILD_TYPE=Release && cmake --build cmake-build-release",
"dependsOn": [
"configure"
]
},
{
"label": "clean",
"type": "shell",
"command": "rm -rf build && rm -rf cmake-build-debug && rm -rf cmake-build-release"
},
{
"label": "rebuild",
"type": "shell",
"dependsOn": [
"clean",
"build-debug",
"build-release"
]
},
{
"label": "run",
"type": "shell",
"command": "./cmake-build-release/bin/helloc",
"dependsOn": [
"build-release"
]
},
{
"label": "test",
"type": "shell",
"command": "./cmake-build-debug/bin/helloc_test && mkdir -p cmake-build-debug/report && mv CUnit*.xml cmake-build-debug/report && cp resources/cunit/CUnit-*.* cmake-build-debug/report/",
"dependsOn": [
"build-debug"
]
},
{
"label": "coverage",
"type": "shell",
"command": "./coverage.sh",
"dependsOn": [
"clean",
"test"
]
}
]
}
settings.json
{
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"**/Thumbs.db": true,
"**/cmake-build-debug":true,
"**/cmake-build-release":true
},
"cmake.cmakePath": "/home/laolang/program/cmake/bin/cmake",
"VsCodeTaskButtons.showCounter": true,
"VsCodeTaskButtons.tasks": [
{
"label": "$(notebook-delete-cell) clean",
"task": "clean"
},
{
"label": "$(debug-configure) rebuild",
"task": "rebuild"
},
{
"label": "$(notebook-execute) run",
"task": "run"
},
{
"label": "$(test-view-icon) test",
"task": "test"
},
{
"label": "coverage",
"task": "coverage"
}
]
}
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "app-debug",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceRoot}/cmake-build-debug/bin/helloc",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "rebuild"
}
]
}
coverage.sh
#!/bin/bash
BUILD_PATH=cmake-build-debug
lcov -d . -o ${BUILD_PATH}/app.info -b . -c --exclude '*/test/*' --exclude '*/src/main/*'
genhtml ${BUILD_PATH}/app.info -o ${BUILD_PATH}/lcov
zlog.con
[formats]
simple = "%d().%ms %p %V [%F:%L] - %m%n"
[rules]
my_cat.DEBUG >stdout; simple
*.* "app.log", 10MB * 0 ~ "app-%d(%Y%m%d).#2s.log"
cmake
頂層 cmake
cmake_minimum_required(VERSION 3.0)
project(helloc C)
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED True)
set(CMAKE_C_EXTENSIONS ON)
set(CMAKE_BUILD_WITH_INSTALL_RPATH True)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage -Wall")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
endif()
set(lib_common common)
set(lib_datastruct datastruct)
configure_file(${CMAKE_SOURCE_DIR}/zlog.conf ${CMAKE_BINARY_DIR}/bin/zlog.conf COPYONLY)
add_subdirectory(src)
add_subdirectory(test)
enable_testing()
add_test(NAME helloc_test COMMAND helloc_test)
test cmake
cmake_minimum_required(VERSION 3.25)
project(helloc_test C)
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED True)
set(CMAKE_C_EXTENSIONS ON)
set(CMAKE_BUILD_WITH_INSTALL_RPATH True)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage -Wall")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
include_directories(${CMAKE_SOURCE_DIR}/test)
include_directories(${CMAKE_SOURCE_DIR}/include)
aux_source_directory(. TEST_SRCS)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
add_executable(${PROJECT_NAME} ${TEST_SRCS})
target_link_libraries(${PROJECT_NAME} cunit zlog ${lib_common} ${lib_datastruct})
set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH "\${ORIGIN}/../lib")
其他文件與腳本
略
效果預覽
cunit 的測試報告上面已經有了, 代碼覆蓋率如下
註意事項
- 代碼覆蓋率要求代碼必須運行過
- 如果生成代碼覆蓋率或者運行測試的時候 lcov 報錯, 有可能是因為覆蓋率數據文件衝突, 先執行 clean 再執行 test 或者 coverage 即可
- vscode 的 debug 有可能會崩潰, 結束任務, 關閉終端面板, 手動刪除 build 目錄再次點擊 F5 即可
- 嘗試在 tasks.json 中配置變數, 失敗了
本文來自博客園,作者:laolang2016,轉載請註明原文鏈接:https://www.cnblogs.com/khlbat/p/17454015.html