Open imshota opened 3 years ago
演習2 テストフレームワークを使って自分のOSSにテストを追加せよ
作業記録
CUnit というテストフレームワークを使う https://ja.osdn.net/projects/cunitforando/
やり方はこのサイトを参考にしました https://www.eureka-moments-blog.com/entry/2019/02/17/181353
この関数をテストする
bool mysanitize(char *s)
{
if (strchr(s, (int)'-') != NULL || strchr(s, (int)';') != NULL)
{
return true;
}
return false;
}
テストケースはこのように設定
#include <stdio.h>
#include <stdbool.h>
#include <testRunner.h>
#include "mysanitize.h"
static unsigned int testMysanitize(void);
/** Main function. */
int main(void)
{
return (int)testRunner(testMysanitize);
}
static unsigned int testMysanitize(void)
{
bool err;
char *data;
data = "testing";
err = mysanitize(data); // do Test
TEST_ASSERT_EQUALS(err, false);
data = "abc;efg";
err = mysanitize(data); // do Test
TEST_ASSERT_EQUALS(err, true);
data = "123 - 456";
err = mysanitize(data); // do Test
TEST_ASSERT_EQUALS(err, true);
data = "test ; -";
err = mysanitize(data); // do Test
TEST_ASSERT_EQUALS(err, true);
return 0;
}
実際にテストしてみる。
% make
gcc -ggdb -Wall -I../../CUnitForAndo/include -I../real/include -I./include -c ./src/mysanitizeTest.c
gcc -ggdb -Wall -ggdb -Wall -I../../CUnitForAndo/include -I../real/include -I./include -o ./runExe.exe mysanitize.o mysanitizeTest.o testRunner.o
% make run
./runExe.exe
OK (4 tests)
無事サニタイズできているらしい。
演習3 テスト駆動開発により自分のOSSに機能を追加せよ
作業記録
テスト駆動開発はスライドの手順通りに行う
入力文字列の中に';' か '-' があれば、それを空白文字に変える。
% cat mysanitizeTest.c
#include <stdio.h>
#include <testRunner.h>
#include "mysanitize.h"
static unsigned int testMysanitize(void);
/* Main function. / int main(void) { return (int)testRunner(testMysanitize); }
static unsigned int testMysanitize(void) { char ret; char data;
data = "testing";
ret = mysanitize(data); // do Test
TEST_ASSERT_EQUALS(ret, "testing");
data = "abc;efg";
ret = mysanitize(data); // do Test
TEST_ASSERT_EQUALS(ret, "abc efg");
data = "123 - 456";
ret = mysanitize(data); // do Test
TEST_ASSERT_EQUALS(ret, "123 456");
data = "test sabu; 1-1";
ret = mysanitize(data); // do Test
TEST_ASSERT_EQUALS(ret, "test sabu 1 1");
return 0;
}
3. テストを動かす→コンパイルが失敗する
% make gcc -ggdb -Wall -ggdb -Wall -I../../CUnitForAndo/include -I../real/include -I./include -o ./runExe.exe mysanitize.o mysanitizeTest.o testRunner.o Undefined symbols for architecture x86_64: "_mysanitize", referenced from: _testMysanitize in mysanitizeTest.o ld: symbol(s) not found for architecture x86_64 collect2: error: ld returned 1 exit status make: *** [runExe.exe] Error 1
4. 実装が空の関数を書く
% cat mysanitize.h
char mysanitize(char s);
% cat mysanitize.c
char mysanitize(char s) { return s; }
5. テストを動かす→テストが失敗する
% make run ./runExe.exe ./src/mysanitizeTest.c:24: error: TestCaseError<0x0d936e35><0x0d936e3d> NG (now 1 ok...) make: *** [run] Error 255
一つ動いているのは、サニタイズをしていないから。
6. 関数を実装する
% cat mysanitize.c
char mysanitize(char s) { char p = strchr(s, ';'), q = strchr(s, '-'); if (p) { p = ' '; } if (q) { q = ' '; } return s; }
7. テストを動かす→テストが成功する
% make run
gcc -ggdb -Wall -I../../CUnitForAndo/include -I../real/include -I./include -c ./src/mysanitizeTest.c
In file included from ./src/mysanitizeTest.c:2:
./src/mysanitizeTest.c: In function 'testMysanitize':
./src/mysanitizeTest.c:18:24: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
18 | TEST_ASSERT_EQUALS((int)ret1, (int)"testing");
| ^
../../CUnitForAndo/include/testRunner.h:44:29: note: in definition of macro 'TEST_ASSERT_EQUALS'
44 | int assertErrorA = (_a);\
| ^~
./src/mysanitizeTest.c:18:35: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
18 | TEST_ASSERT_EQUALS((int)ret1, (int)"testing");
| ^
../../CUnitForAndo/include/testRunner.h:45:29: note: in definition of macro 'TEST_ASSERT_EQUALS'
45 | int assertErrorB = (_b);\
| ^~
../../CUnitForAndo/include/testRunner.h:44:28: warning: initialization of 'int' from 'char ' makes integer from pointer without a cast [-Wint-conversion]
44 | int assertErrorA = (_a);\
| ^
./src/mysanitizeTest.c:23:5: note: in expansion of macro 'TEST_ASSERT_EQUALS'
23 | TEST_ASSERT_EQUALS(ret2, "abc efg");
| ^~~~~~
../../CUnitForAndo/include/testRunner.h:45:28: warning: initialization of 'int' from 'char ' makes integer from pointer without a cast [-Wint-conversion]
45 | int assertErrorB = (_b);\
| ^
./src/mysanitizeTest.c:23:5: note: in expansion of macro 'TEST_ASSERT_EQUALS'
23 | TEST_ASSERT_EQUALS(ret2, "abc efg");
| ^~~~~~
../../CUnitForAndo/include/testRunner.h:44:28: warning: initialization of 'int' from 'char ' makes integer from pointer without a cast [-Wint-conversion]
44 | int assertErrorA = (_a);\
| ^
./src/mysanitizeTest.c:28:5: note: in expansion of macro 'TEST_ASSERT_EQUALS'
28 | TEST_ASSERT_EQUALS(ret3, "123 456");
| ^~~~~~
../../CUnitForAndo/include/testRunner.h:45:28: warning: initialization of 'int' from 'char ' makes integer from pointer without a cast [-Wint-conversion]
45 | int assertErrorB = (_b);\
| ^
./src/mysanitizeTest.c:28:5: note: in expansion of macro 'TEST_ASSERT_EQUALS'
28 | TEST_ASSERT_EQUALS(ret3, "123 456");
| ^~~~~~
../../CUnitForAndo/include/testRunner.h:44:28: warning: initialization of 'int' from 'char ' makes integer from pointer without a cast [-Wint-conversion]
44 | int assertErrorA = (_a);\
| ^
./src/mysanitizeTest.c:33:5: note: in expansion of macro 'TEST_ASSERT_EQUALS'
33 | TEST_ASSERT_EQUALS(ret4, "test sabu 1 1");
| ^~~~~~
../../CUnitForAndo/include/testRunner.h:45:28: warning: initialization of 'int' from 'char ' makes integer from pointer without a cast [-Wint-conversion]
45 | int assertErrorB = (_b);\
| ^
./src/mysanitizeTest.c:33:5: note: in expansion of macro 'TEST_ASSERT_EQUALS'
33 | TEST_ASSERT_EQUALS(ret4, "test sabu 1 1");
| ^~~~~~
gcc -ggdb -Wall -ggdb -Wall -I../../CUnitForAndo/include -I../real/include -I./include -o ./runExe.exe mysanitize.o mysanitizeTest.o testRunner.o
./runExe.exe
./src/mysanitizeTest.c:18: error: TestCaseError<0xe3ba7628><0x0c05be08>
NG (now 0 ok...)
make: *** [run] Error 255
...前回通った最初のテストケースも通らなくなってしまった。
よって、自分で確認することにする。
char mysanitize(char s) { char p = strchr(s, ';'), q = strchr(s, '-'); if (p) { p = ' '; } if (q) { q = ' '; } return s; }
int main(void) { char data1[] = "testing"; char *ret1 = mysanitize(data1); // do Test printf("%s\n", ret1);
char data2[] = "abc;efg"; char *ret2 = mysanitize(data2); // do Test printf("%s\n", ret2);
char data3[] = "123 - 456"; char *ret3 = mysanitize(data3); // do Test printf("%s\n", ret3);
char data4[] = "test sabu; 1-1"; char *ret4 = mysanitize(data4); // do Test printf("%s\n", ret4);
return 0; }
テスト
% ./test.out testing abc efg 123 456 test sabu 1 1
テスト成功している。
演習1 自分のOSSにテストを1つ追加せよ
作業記録
自分の検体であるSQLプログラムのサービステストを追加する。 サービスとしては、以下を想定している。
ユーザからIDとPASSを標準入力として受け取る データベースdata.dbからSQL文 select * from scores where id = ID AND pass = 'PASS' を実行する。
テストとして、以下をインライン
もしテストが成功すれば、 "Success to Log In" が表示されデータベース内のID, PASS, SCOREを "id = ID, pass = PASS, score = SCORE" の形で出力される。
失敗している これはfgetsで改行文字まで読み込んでしまっているのが原因
以下を追加
もう一度テストしてみる
テスト成功である