笨辦法學C 練習30 自動化測試

2021-09-19 04:48:47 字數 3905 閱讀 8414

原文: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.alibyour_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語句更加靈活,然而內部的機...