奥さん、僕ぁC言語でもTDDしたいんですよ!
……というわけで、Rubyで実現する素敵なC言語TDD環境、Unityです。
3Dゲームを作るアレではなく、TDD用テストフレームワークです。
UnityはRubyistにはお馴染みのRackを使っています。
Ruby&Rack環境が方は先に導入しておいて下さい。
導入が終わりましたら、
"公式様"にとんで頂き、
下の方にある「download unity」から圧縮ファイルを入手します。
これを解凍すると色々と並んでいます……が
今回用があるのはexampleです。
これの中身を詳しく見て行くと
$ ls examples/ helper rakefile_helper.rb test makefile readme.txt test1.out rakefile.rb src test2.out
となっています。
テスト対象のファイルはsrc、
テストはtestに突っ込みます。
なお、今回のコードは下記のの記事で書いたコマンド形式のアレをベースにしています
shuzo-kino.hateblo.jp
/*src/wap.c*/ #include "wap.h" #include <stdio.h> #include <string.h> typedef struct { char *cmd; void (*func)(); } cmd_t; static cmd_t cmd_tbl[] = { {"rx", wap_rx}, {"tx", wap_tx}, {NULL, NULL} //いわゆる番兵法 }; int wap_init() { return 0; } int wap_handler(char argc, char *argv[]) { int i; for (i=0; cmd_tbl[i].cmd != NULL; i++) { if (strcmp( argv[0], cmd_tbl[i].cmd) == TRUE) { //テーブル中にコマンドがあれば、実行. cmd_tbl[i].func(); return 0; } } return -1; } int wap_tx() { return 0; } int wap_rx() { return 0; }
/*src/wap.h*/ int wap_handler(char argc, char *argv[]); int wap_init(); int wap_tx(); int wap_rx();
/*test/TestWap.c*/ #include "unity.h" #include "wap.h" void setUp(void) { } void tearDown(void) { } void test_wap_init(void) { TEST_ASSERT_EQUAL(0, wap_init()); } void test_wap_tx(void) { TEST_ASSERT_EQUAL(0, wap_tx()); } void test_wap_rx(void) { TEST_ASSERT_EQUAL(0, wap_rx()); } void test_rx_wap_handler(void) { char argc; char *argv[1] = {"rx"}; TEST_ASSERT_EQUAL(0, wap_handler(argc, argv)); } void test_tx_wap_handler(void) { char argc; char *argv[1] = {"tx"}; TEST_ASSERT_EQUAL(0, wap_handler(argc, argv)); }
これを配置し終わったら、テストコードを置いたディレクトリにてコマンドを入力すれば初回テスト完了です。
お疲れさまでした。
$ rake all Running system tests... gcc -DUNITY_INCLUDE_DOUBLE -DUNITY_SUPPORT_TEST_CASES -DTEST -c -m32 -Wall -Wno-address -std=c99 -pedantic -Isrc/ -I../src/ -Itest/ src/ProductionCode.c -obuild/ProductionCode.o ... gcc -DUNITY_INCLUDE_DOUBLE -DUNITY_SUPPORT_TEST_CASES -DTEST -c -m32 -Wall -Wno-address -std=c99 -pedantic -Isrc/ -I../src/ -Itest/ ../src/unity.c -obuild/unity.o gcc -DUNITY_INCLUDE_DOUBLE -DUNITY_SUPPORT_TEST_CASES -DTEST -c -m32 -Wall -Wno-address -std=c99 -pedantic -Isrc/ -I../src/ -Itest/ src/wap.c -obuild/wap.o src/wap.c:14: warning: initialization from incompatible pointer type src/wap.c:15: warning: initialization from incompatible pointer type gcc -DUNITY_INCLUDE_DOUBLE -DUNITY_SUPPORT_TEST_CASES -DTEST -c -m32 -Wall -Wno-address -std=c99 -pedantic -Isrc/ -I../src/ -Itest/ build/TestWap_Runner.c -obuild/TestWap_Runner.o gcc -DUNITY_INCLUDE_DOUBLE -DUNITY_SUPPORT_TEST_CASES -DTEST -c -m32 -Wall -Wno-address -std=c99 -pedantic -Isrc/ -I../src/ -Itest/ test/TestWap.c -obuild/TestWap.o gcc -lm -m32 build/unity.o build/wap.o build/TestWap_Runner.o build/TestWap.o -o build/TestWap.exe build/TestWap.exe test/TestWap.c:13:test_wap_init:PASS test/TestWap.c:17:test_wap_tx:PASS test/TestWap.c:22:test_wap_rx:PASS test/TestWap.c:27:test_rx_wap_handler:PASS test/TestWap.c:34:test_tx_wap_handler:PASS ----------------------- 5 Tests 0 Failures 0 Ignored OK FAIL: There were failures
参考本
テスト駆動開発による組み込みプログラミング ―C言語とオブジェクト指向で学ぶアジャイルな設計
- 作者:James W. Grenning
- 発売日: 2013/04/24
- メディア: 大型本
今回のサンプルはマクロ付きのC風な感じでしかありませんでした。
ところが、本文中、特に付録B「Unityクイックリファレンス」ではもっとイケてる書き方を紹介しています。
これについては理解が深まり次第記事にしようと思っています。