天天看點

《測試驅動的嵌入式C語言開發》——2.3節CppUTest:一個用C++實作的自動化單元測試架構

2.3 cpputest:一個用c++實作的自動化單元測試架構

現在你已經見過了unity,接下來我會快速介紹一下cpputest,同時也是我更傾向于使用的對c和c++代碼進行單元測試的自動化測試架構。事實上,不僅因為它是一個功能全面的測試架構,同時也因為我是cpputest的作者之一。本書開始的幾個例子會用unity,在第8章之後會使用cpputest。

cpputest是為了支援在多種作業系統上開發嵌入式軟體而特别設計的。cpputest的宏被設計成不需要了解c++也可以寫測試用例。這使得c程式員更容易用這個測試架構。

cpputest隻使用c++語言中主要的那部分子集,這種選擇很好地适應了那些編譯器不能完全支援全部c++語言特性的嵌入式開發。你會看到用unity和cpputest寫出的單元測試幾乎一模一樣。你當然可以選擇任意一個測試架構來進行你的産品開發。

用cpputest、寫sprintf測試用例

以下用cpputest寫的測試用例和在2.2節中用unity寫的sprintf()測試用例功能相當:

《測試驅動的嵌入式C語言開發》——2.3節CppUTest:一個用C++實作的自動化單元測試架構

除了那些宏的名字有些不同外,測試用例是一樣的。

用cpputest寫的sprintf的測試夾具

讓我們來看一下在2.2節中,unity寫的測試夾具的例子若用cpputest寫會是什麼樣子。

《測試驅動的嵌入式C語言開發》——2.3節CppUTest:一個用C++實作的自動化單元測試架構
《測試驅動的嵌入式C語言開發》——2.3節CppUTest:一個用C++實作的自動化單元測試架構

還是非常相似,表達了相同的概念。格式上的一點不同是,cpputest的test_group緊接下來是用一組大括号來包起共享資料聲明和函數。所有大括号包起來的東西都是test_group的一部分,并且對于測試組中的每個test()來講都是可以通路的。共享資料(output、expected和length)在一個叫做setup()的特殊輔助函數中進行初始化。正如你猜的那樣,它在每個test()之前都會先被調用一下。另一個特别的函數teardown()會在每個test()之後調用。在本例中,沒有使用teardown()函數。expect()和given()是自由格式的輔助函數,對于同個一test_group中的所有test()用例都可以通路。

以下重構過的測試用例和我們的unity測試用例相同:

《測試驅動的嵌入式C語言開發》——2.3節CppUTest:一個用C++實作的自動化單元測試架構

cpputest的一個優勢是,測試是自動安裝的。它不需要任何額外的腳本來生成測試容器或者手工來寫如run_test_case()、test_group_runner()和run_test_group()這些東西。一點微小的差別是用來斷言的宏不太一樣。每個測試架構都有自己的一套宏,盡管功能上其實有重複。

你可能會發現unity和cpputest的宏和測試結構看上去很相似。這并不奇怪,它們都沿用了一種很不錯的模式。我第一次是在junit中看到這種模式,junit是一種java語言的測試架構。更細節的原因是我也曾為unity項目中測試夾具宏的部分作出過貢獻。

cpputest的輸出

正如在unity部分就講解過的,測試在這裡被作為make自動化建構的一部分來運作。測試輸出看起來是這樣的:

《測試驅動的嵌入式C語言開發》——2.3節CppUTest:一個用C++實作的自動化單元測試架構

失敗資訊會報告出錯條件的行号、出錯測試用例的名字和出錯的原因。請注意在總結部分會包括失敗的個數。

就算是你故意在測試用例中加入一個錯誤,記得一定要把它删掉,否則的話你将有催生一個bug的風險。

繼續閱讀