原文:exercise 30: automated testing自動化測試經常用於例如python和ruby的其它語言,但是很少用於c。一部分原因是自動化載入和測試c的**片段具有較高的難度。這一章中,我們會建立乙個非常小型的測試「框架」,並且使用你的框架目錄構建測試用例的示例。譯者:飛龍
我接下來打算使用,並且你會包含進框架目錄的框架,叫做「minunit」,它以jera design所編寫的一小段**作為開始,之後我擴充套件了它,就像這樣:
#undef ndebug
#ifndef _minunit_h
#define _minunit_h
#include #include #include #define mu_suite_start() char *message = null
#define mu_assert(test, message) if (!(test))
#define mu_run_test(test) debug("\n-----%s", " " #test); \
message = test(); tests_run++; if (message) return message;
#define run_tests(name) int main(int argc, char *ar**) \
else \
printf("tests run: %d\n", tests_run);\
exit(result != 0);\
}int tests_run;
#endif
原始的內容所剩不多了,現在我使用dbg.h
巨集,並且在模板測試執行器的末尾建立了大量的巨集。在這小段**中我們建立了整套函式單元測試系統,一旦它結合上shell指令碼來執行測試,你可以將其用於你的c**。
為了基礎這個練習,你應該讓你的src/libex29.c
正常工作,並且完成練習29的附加題,是ex29.c
引導程式並合理執行。練習29中我這事了乙個附加題來使它像單元測試一樣工作,但是現在我打算重新想你展示如何使用minunit.h
來做這件事。
首先我們需要建立乙個簡單的空單元測試,命名為tests/libex29_tests.c
,在裡面輸入:
#include "minunit.h"
char *test_dlopen()
char *test_functions()
char *test_failures()
char *test_dlclose()
char *all_tests()
run_tests(all_tests);
這份**展示了tests/minunit.h
中的run_tests
巨集,以及如何使用其他的測試執行器巨集。我沒有編寫實際的測試函式,所以你只能看到單元測試的結構。我首先會分解這個檔案:
libex29_tests.c:1
包含minunit.h
框架。
libex29_tests.c:3-7
第乙個測試。測試函式具有固定的結構,它們不帶任何引數並且返回char *
,成功時為null
。這非常重要,因為其他巨集用於向測試執行器返回錯誤資訊。
libex29_tests.c:9-25
與第乙個測試相似的更多測試。
libex29_tests.c:27
控制其他測試的執行器函式。它和其它測試用例格式一致,但是使用額外的東西來配置。
libex29_tests.c:28
為mu_suite_start
測試設定一些通用的東西。
libex29_tests.c:30
這就是使用mu_run_test
返回結果的地方。
libex29_tests.c:35
在你執行所有測試之後,你應該返回null
,就像普通的測試函式一樣。
libex29_tests.c:38
最後需要使用run_tests
巨集來啟動main
函式,讓它執行all_tests
啟動器。
這就是用於執行測試所有**了,現在你需要嘗試使它執行在專案框架中。下面是我的執行結果:
not printable
我首先執行make clean
,之後我執行了構建,它將模板改造為libyour_library.a
和libyour_library.so
檔案。要記住你需要在練習29的附加題中完成它。但如果你沒有完成的話,下面是我所使用的makefile
的檔案差異:
diff --git a/code/c-skeleton/makefile b/code/c-skeleton/makefile
index 135d538..21b92bf 100644
--- a/code/c-skeleton/makefile
+++ b/code/c-skeleton/makefile
@@ -9,9 +9,10 @@ test_src=$(wildcard tests/*_tests.c)
tests=$(patsubst %.c,%,$(test_src))
target=build/libyour_library.a
+so_target=$(patsubst %.a,%.so,$(target))
# the target build
-all: $(target) tests
+all: $(target) $(so_target) tests
dev: cflags=-g -wall -isrc -wall -wextra $(optflags)
dev: all
@@ -21,6 +22,9 @@ $(target): build $(objects)
ar rcs $@ $(objects)
ranlib $@
+$(so_target): $(target) $(objects)
+ $(cc) -shared -o $@ $(objects)
+ build:
@mkdir -p build
@mkdir -p bin
完成這些改變後,你現在應該能夠構建任何東西,並且你可以最後補完剩餘的單元測試函式:
#include "minunit.h"
#include typedef int (*lib_function)(const char *data);
char *lib_file = "build/libyour_library.so";
void *lib = null;
int check_function(const char *func_to_run, const char *data, int expected)
char *test_dlopen()
char *test_functions()
char *test_failures()
char *test_dlclose()
char *all_tests()
run_tests(all_tests);
我希望你可以弄清楚它都幹了什麼,因為這裡沒有什麼新的東西,除了check_function
函式。這是乙個通用的模式,其中我需要重複執行一段**,然後通過為之建立巨集或函式來使它自動化。這裡我打算執行.so
中所載入的函式,所以我建立了乙個小型函式來完成它。 笨辦法學python 自動化測試(筆記)
由於專案都建立在自己電腦上,沒有考慮怎麼能讓別人也簡單的匯入自己寫的模組,本文主要用於自己記錄與學習。兩種匯入方法 1 第一種就是臨時的匯入路徑,在關閉shell之後就會復原,每次使用模組都需要重新匯入。具體操作如下圖所示 這樣就可以把包含所想要匯入的模組的路徑放入sys.path中。2 第二種是永...
笨辦法學C 練習0 準備
原文 exercise 0 the setup 譯者 飛龍 在這一章中,你將為c語言程式設計配置好你的系統。乙個好訊息是對於所有使用linux或者mac的人,你的系統是為c語言程式設計而設計的。c語言的創造者也對unix作業系統的創造做出了貢獻,並且linux和osx都是基於unix的。事實上,安裝...
笨辦法學C 練習13 Switch語句
原文 exercise 13 switch statement 譯者 飛龍 在其它類似ruby的語言中,switch語句可以處理任意型別的表示式。一些語言比如python沒有switch語句,因為帶有布林表示式的if語句可以做相同的事情。對於這些語言,switch語句比if語句更加靈活,然而內部的機...