階乗計算機のテストとデバッグ
この最後のステップでは、さまざまなテスト技術とデバッグ戦略を使って、階乗計算機を十分にテストしてデバッグする方法を学びます。
複数のテストケースとデバッグ機能を含む包括的なテストプログラムを作成しましょう。~/project ディレクトリに factorial_test.c という名前のファイルを作成します。
cd ~/project
touch factorial_test.c
#include <stdio.h>
#include <assert.h>
#include <limits.h>
// 詳細なエラーチェック付きの階乗計算関数
int calculateFactorial(int n) {
// 関数呼び出しを追跡するためのデバッグ出力
printf("DEBUG: Calculating factorial for %d\n", n);
// 入力範囲を検証する
if (n < 0) {
fprintf(stderr, "ERROR: Factorial undefined for negative numbers\n");
return -1;
}
// 特殊ケースを処理する
if (n == 0 || n == 1) return 1;
// オーバーフロー保護付きの階乗計算
long long factorial = 1;
for (int i = 2; i <= n; i++) {
factorial *= i;
// オーバーフローチェック
if (factorial > INT_MAX) {
fprintf(stderr, "ERROR: Factorial exceeds integer limit\n");
return -1;
}
}
return (int)factorial;
}
// 階乗計算を検証するためのテスト関数
void runTests() {
// 期待される結果付きのテストケース
struct TestCase {
int input;
int expected;
} tests[] = {
{0, 1}, // エッジケース:0!
{1, 1}, // エッジケース:1!
{5, 120}, // 通常のケース:5!
{10, 3628800} // より大きな数
};
int numTests = sizeof(tests) / sizeof(tests[0]);
printf("Running %d test cases...\n", numTests);
// テストケースを反復処理する
for (int i = 0; i < numTests; i++) {
int result = calculateFactorial(tests[i].input);
// アサーションスタイルのテスト
if (result == tests[i].expected) {
printf("Test case %d PASSED: factorial(%d) = %d\n",
i+1, tests[i].input, result);
} else {
printf("Test case %d FAILED: Expected %d, Got %d\n",
i+1, tests[i].expected, result);
}
}
}
int main() {
// 包括的なテストスイートを実行する
runTests();
// 対話型のテストモード
int number;
printf("\nEnter a number to calculate its factorial (or negative to exit): ");
while (scanf("%d", &number) == 1 && number >= 0) {
int result = calculateFactorial(number);
if (result!= -1) {
printf("Factorial of %d is: %d\n", number, result);
}
printf("\nEnter another number (or negative to exit): ");
}
return 0;
}
このプログラムをコンパイルして実行します。
gcc factorial_test.c -o factorial_test
./factorial_test
実行結果例は以下のようになります。
Running 4 test cases...
DEBUG: Calculating factorial for 0
Test case 1 PASSED: factorial(0) = 1
DEBUG: Calculating factorial for 1
Test case 2 PASSED: factorial(1) = 1
DEBUG: Calculating factorial for 5
Test case 3 PASSED: factorial(5) = 120
DEBUG: Calculating factorial for 10
Test case 4 PASSED: factorial(10) = 3628800
Enter a number to calculate its factorial (or negative to exit):
示されている重要なデバッグとテスト技術:
- 関数実行を追跡するためのデバッグ出力文
- エッジケースを含む包括的なテストケース
- 無効な入力に対するエラーハンドリング
- オーバーフロー保護
- アサーションスタイルのテスト
- 対話型のテストモード
デバッグのヒント:
- 関数呼び出しのログ記録と追跡に
printf() を使用する
- エッジケースを明示的に処理する
- 入力検証を実装する
- より大きな数の計算に long long を使用する
- さまざまなシナリオを検証するためのテストスイートを作成する