前言
在嵌入式領域,尤其是MCU領域,一般很少有使用單元測試框架,一般就是開發階段開發人員按照自己的習慣和經驗進行自測,然后就是系統集成測試,所以一般在單元測試這一環做的不是很規范。實際上我們在開發中應該要改善這種現狀,加強單元測試的管理,避免單元測試純憑開發人員是否有時間做,做到什么程度也是隨緣。應該由測試來保證開發質量,避免依賴于個人,并且積累測試用例庫,這樣有助于產品迭代穩定,尤其是在BSP等領域,有一個好的測試框架和測試用例集能很好的完成芯片的驗證,和生產測試等工作。
恰好有這樣一個框架,專為嵌入式領域純粹的C測試而生-unity,使用ANSI C編寫,移植性好,資源占用少,就一個C文件和h文件,可以通過h進行一些配置,特別適合MCU開發等領域。
官網
http://www.throwtheswitch.org/
http://www.throwtheswitch.org/unity
下載源碼
https://github.com/ThrowTheSwitch/Unity/
或者
https://github.com/ThrowTheSwitch/Unity/archive/master.zip
使用
http://www.throwtheswitch.org/unity
這個頁面可以看到基本的介紹,瀏覽一下就知道個大概了,
https://github.com/ThrowTheSwitch/Unity/
下的README.md也可以先看一下。
先不管細節,不需要了解很多,不管三七二十一先用了再說。
這里使用某個MCU的開發板,MDK環境進行測試。
我們這里使用源碼中的example_1進行測試。
添加代碼
將下載的源碼Unity\\src下的unity.c,unity.h,unity_internals.h
Unity\\examples下的unity_config.h
放到自己工程的unity目錄下,這一部分是unity源碼
Unity\\examples\\example_1\\src下的所有文件放置到自己工程的src目錄下,這一部分是用戶代碼需要測試的
Unity\\examples\\example_1\\test下的所有文件放置到自己工程的test目錄下,這一部分是測試代碼
配置頭文件包含路徑
添加上述幾個文件夾到頭文件包含路徑
依賴
默認依賴打印輸出函數putchar
見unity_internals.h中
#ifndef UNITY_OUTPUT_CHAR
/* Default to using putchar, which is defined in stdio.h */
#include < stdio.h >
#define UNITY_OUTPUT_CHAR(a) (void)putchar(a)
#else
/* If defined as something else, make sure we declare it here so it's ready for use */
#ifdef UNITY_OUTPUT_CHAR_HEADER_DECLARATION
extern void UNITY_OUTPUT_CHAR_HEADER_DECLARATION;
#endif
#endif
我們要根據自己的情況進行移植,
unity_config.h中配置以下宏,其中RS232_putc在我們自己的代碼中實現
注意:需要在unity_internals.h中#define UNITY_INCLUDE_CONFIG_H 1
或者在工程配置中定義宏UNITY_INCLUDE_CONFIG_H,才會使用unity_config.h
比如MDK工程中設置
如果已經實現了標準輸入輸出重定向,有putchar則不需要使能這些宏,直接使用putchar。
測試1
example_1中有兩個測試,一個是源碼帶2的一個是不帶2的。
代碼中
先將帶2的相關代碼不進行編譯
將TestProductionCode_Runner.c中的main函數名改為testrunner_main
在自己工程的main函數中調用該函數(先 extern int testrunner_main(void);申明下函數)
運行程序打印如下
test/TestProductionCode.c:20:test_FindFunction_WhichIsBroken_ShouldReturnZeroIfItemIsNotInList_WhichWorksEvenInOurBrokenCode:PASS
test/TestProductionCode.c:33:test_FindFunction_WhichIsBroken_ShouldReturnTheIndexForItemsInList_WhichWillFailBecauseOurFunctionUnderTestIsBroken:FAIL: Expected 1 Was 0
test/TestProductionCode.c:41:test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValue:PASS
test/TestProductionCode.c:51:test_FunctionWhichReturnsLocalVariable_ShouldReturnTheCurrentCounterValueAgain:PASS
test/TestProductionCode.c:61:test_FunctionWhichReturnsLocalVariable_ShouldReturnCurrentCounter_ButFailsBecauseThisTestIsActuallyFlawed:FAIL: Expected 0x00001234 Was 0x00005A5A
-----------------------
5 Tests 2 Failures 0 Ignored
FAIL
測試2
使用帶2的代碼
TestProductionCode2_Runner.c中main函數名改為testrunner2_main
在自己的代碼中調用
testrunner2_main
先 extern int testrunner2_main(void);申明該函數
運行看到輸出如下
test/TestProductionCode2.c:20:test_IgnoredTest:IGNORE: This Test Was Ignored On Purpose
test/TestProductionCode2.c:25:test_AnotherIgnoredTest:IGNORE: These Can Be Useful For Leaving Yourself Notes On What You Need To Do Yet
test/TestProductionCode2.c:30:test_ThisFunctionHasNotBeenTested_NeedsToBeImplemented:IGNORE
-----------------------
3 Tests 0 Failures 3 Ignored
OK
總結
以上可以看到,unnity進行單元測試十分方便,移植也很簡單,先進行一個初體驗,后面再詳細介紹其使用和設計原理。
審核編輯:湯梓紅
-
mcu
+關注
關注
146文章
17123瀏覽量
350980 -
嵌入式
+關注
關注
5082文章
19104瀏覽量
304797 -
源碼
+關注
關注
8文章
639瀏覽量
29185 -
Unity
+關注
關注
1文章
127瀏覽量
21806
發布評論請先 登錄
相關推薦
評論