404 Not Found

404 Not Found


nginx

C++における単体テスト

[第]49[課では]パフォーマンスの最適化について学びました。

[今]、[私たちは]ユニットテスト――[コードの][品質を保証するための重要なスキル]――を学びます。

[コードを]書いた[だけでテストしない]のは、[料理を作ったのに味見をしない]ようなものだ。


1. ユニットテスト[概要]

(1) 1.1 ユニットテストとは?

ユニットテスト(Unit Test)[とは、][最小のテスト可能単位](関数、クラス)[に対して行うテスト]のことです。

[強み]:


(2) 1.2 [テストフレームワークの選定]

[フレームワーク] [説明]
Google Test Google[出品],[最]stream[行]
Catch2 [単一]ヘッダーファイル、[シンプルで使いやすい]
Boost.Test Boost[ライブラリの一部]
Doctest [Catch2に似た]クラス、[より高速]

[おすすめ]: Google Test([機能充実])[または] Catch2([シンプル])



2. Google Test[入門]

(1) 2.1 [インストール]Google Test

Linux:

BASH
sudo apt-get install libgtest-dev

Windows: [vcpkgを使用するか、ソースコードから]コンパイルします。


(2) 2.2 [最初のテスト]

例:[Google Testを使用して]加算をテストする関数 (難易度 ⭐)

▶ サンプル 2: codeexample (難易度 ⭐)

CPP
#include <gtest/gtest.h>

int add(int a, int b) {
 return a + b;
}

TEST(AddTest, Positive) {
 EXPECT_EQ(add(2, 3), 5);
}

TEST(AddTest, Negative) {
 EXPECT_EQ(add(-2, -3), -5);
}

int main(int argc, char** argv) {
 ::testing::InitGoogleTest(&argc, argv);
 return RUN_ALL_TESTS();
}
▶ 試してみよう

[実行結果]:

TEXT
[==========] Running 2 tests from 1 test suite.
[ PASSED ] 2 tests.


3. [アサーションマクロ]

(1) 3.1 ASSERT と EXPECT の違い

[マクロ] [失敗時の動作]
ASSERT_* [終了][現在テスト中]
EXPECT_* [続行][実行]

[おすすめ]: [使用] EXPECT_*([さらに多くの失敗例を確認可能])


(2) 3.2 [よく使われるアサーション]

[断言] [説明]
EXPECT_EQ(a, b) a == b
EXPECT_NE(a, b) a ≠ b
EXPECT_LT(a, b) a < b
EXPECT_GT(a, b) a > b
EXPECT_TRUE(cond) cond[真]
EXPECT_FALSE(cond) cond[false]
EXPECT_THROW(statement, exception_type) [期待]例外をスローする


4. [試験治具](Test Fixture)

(1) 4.1 なぜ[治具]が必要なのでしょうか?

[問題]: [複数のテストで][同じ初期化コード]が必要。

[解決策]: [試験治具](継承 testing::Test


(2) 4.2 例:[治具を用いたキューのテスト] (難易度 ⭐⭐)

CPP
#include <gtest/gtest.h>
#include queue

class QueueTest : public testing::Test {
protected:
 void SetUp() override {
 q.push(1);
 q.push(2);
 q.push(3);
 }
 
 void TearDown() override {
 // ()
 }
 
 std::queueint q;
};

TEST_F(QueueTest, Size) {
 EXPECT_EQ(q.size(), 3);
}

TEST_F(QueueTest, Front) {
 EXPECT_EQ(q.front(), 1);
}

int main(int argc, char** argv) {
 ::testing::InitGoogleTest(&argc, argv);
 return RUN_ALL_TESTS();
}


5. [テスト駆動開発](TDD)

(1) 5.1 TDDとは何か?

TDD(テスト駆動開発)とは、[まずテストを書き]、[その後]コードを書くことを指します。

stream[程]:

  1. [テストを作成]([失敗])
  2. [写]code([通過])
  3. [リファクタリング]

(2) 5.2 例:TDD[開発]stack (難易度 ⭐⭐⭐)

CPP
// 1. writetesting
TEST(StackTest, PushAndPop) {
 Stackint s;
 s.push(42);
 EXPECT_EQ(s.pop(), 42);
}

// 2. write
template<typename T>
class Stack {
 std::vectorT data;
public:
 void push(const T& x) { data.push_back(x); }
 T pop() { T x = data.back(); data.pop_back(); return x; }
};


6. 演習:[学生のテスト]クラス

▶ サンプル 1: [完全なテスト] (難易度 ⭐⭐⭐)

CPP
#include <gtest/gtest.h>
#include string

class Student {
 std::string name;
 int age;
 
public:
 Student(const std::string& name, int age) : name(name), age(age) {}
 
 std::string getName() const { return name; }
 int getAge() const { return age; }
};

TEST(StudentTest, Constructor) {
 Student s("...", 20);
 EXPECT_EQ(s.getName(), "...");
 EXPECT_EQ(s.getAge(), 20);
}

int main(int argc, char** argv) {
 ::testing::InitGoogleTest(&argc, argv);
 return RUN_ALL_TESTS();
}
▶ 試してみよう

❓ よくある質問

Q:ユニットテストで[すべての]バグを[発見できる]か? A:[できない]。ユニットテストでは、[既知の]タイプのエラーしか[発見できない]。[さらに、統合テスト]や[システムテスト]も必要となる。


Q [テスト]コード[は製品]コード[と一緒にリリースしますか]?
A [必要ありません]。[テスト]コード[は通常、開発時にのみ使用されます]。

Q [非公開]関数をどのようにテストすればよいですか?
A - [方法]1:[公開]インターフェースをテストする([間接テスト]) - [方法]2:FRIEND_TESTを使用して[非公開]メンバーを公開する - [方法]3:[リファクタリング]を行い、[非公開]関数を[独立した]クラスに抽出する

📖 まとめ

[知識ポイント] [要点]
ユニットテスト [最小テスト単位]
Google Test [最]先端の[C++][テストフレームワーク]
[断言マクロ] EXPECT_* [和] ASSERT_*
[テスト治具] [共有の初期化]code
TDD [まずテストを書く],[それから]コードを書く

📝 練習問題

  1. **初心者(難易度 ⭐):[add(a,b) 関数] を[作成]し、[Google Test を使って] 3 [個]のテストケースを[作成]してください:[正の数の加算]、[負の数の加算]、[0 の加算]。

  2. **中級(難易度 ⭐⭐):[isPalindrome関数を作成し]、[文字列が]回文であるかどうかを[判定]してください。[少なくとも]5つのテストケースを[作成し]、[正常]/[境界]/[特殊]な入力を[網羅]してください。

  3. **上級(難易度 ⭐⭐⭐):[1つの]「[銀行口座]」クラス([預入/引出/残高照会などの]メソッドを含む)に対して、[完全な]ユニットテストを[作成する]。[通常の入出金]、[当座貸越の拒否]、[並行処理の安全性]([該当する場合])をテストする。



[次のレッスン]:演習:[アドレス帳システム](#51)

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%