Giao diện
Google Test Writing
🎯 Mục tiêu
🎯 Sau bài thực hành này, bạn sẽ:
- Viết unit tests rõ ràng với Google Test
- Sử dụng test fixtures chia sẻ setup/teardown
- Tạo parameterized tests cho nhiều input cases
Mô tả bài tập
Google Test là framework testing phổ biến nhất trong C++. Bài tập giúp bạn viết tests hiệu quả và có cấu trúc.
Yêu cầu
Bài 1: Basic Unit Tests
Viết tests cho class StringUtils (toUpper, trim, isPalindrome).
cpp
#include <gtest/gtest.h>
#include "string_utils.h"
TEST(StringUtilsTest, ToUpperConvertsLowercase) {
EXPECT_EQ(StringUtils::toUpper("hello"), "HELLO");
}
TEST(StringUtilsTest, TrimRemovesWhitespace) {
// TODO: trim " hello " → "hello"
}
TEST(StringUtilsTest, IsPalindromeReturnsTrueForPalindrome) {
// TODO: "racecar" → true
}
TEST(StringUtilsTest, ToUpperHandlesEmptyString) {
// TODO: edge case chuỗi rỗng
}Bài 2: Test Fixtures — BankAccount
cpp
class BankAccountTest : public ::testing::Test {
protected:
std::unique_ptr<BankAccount> account;
void SetUp() override {
account = std::make_unique<BankAccount>("User", 1000.0);
}
};
TEST_F(BankAccountTest, DepositIncreasesBalance) { /* TODO */ }
TEST_F(BankAccountTest, WithdrawDecreasesBalance) { /* TODO */ }
TEST_F(BankAccountTest, WithdrawThrowsOnInsufficientFunds) {
// TODO: EXPECT_THROW(account->withdraw(2000), std::runtime_error)
}Bài 3: Parameterized Tests — isPrime
cpp
class PrimeTest : public ::testing::TestWithParam<std::pair<int, bool>> {};
TEST_P(PrimeTest, CheckPrimality) {
auto [input, expected] = GetParam();
EXPECT_EQ(isPrime(input), expected);
}
INSTANTIATE_TEST_SUITE_P(PrimeNumbers, PrimeTest,
::testing::Values(
std::make_pair(-1, false), std::make_pair(0, false),
std::make_pair(1, false), std::make_pair(2, true),
std::make_pair(17, true), std::make_pair(25, false)
));Gợi ý
Gợi ý Bài 1
Dùng EXPECT_EQ cho equality, EXPECT_TRUE/FALSE cho boolean. Mỗi test nên test MỘT hành vi.
Gợi ý Bài 2
Fixture: SetUp() chạy trước mỗi TEST_F. EXPECT_THROW(expr, ExceptionType) test exception.
Lời giải tham khảo
Xem lời giải
cpp
// Bài 1
TEST(StringUtilsTest, TrimRemovesWhitespace) {
EXPECT_EQ(StringUtils::trim(" hello "), "hello");
}
TEST(StringUtilsTest, IsPalindromeReturnsTrueForPalindrome) {
EXPECT_TRUE(StringUtils::isPalindrome("racecar"));
}
TEST(StringUtilsTest, ToUpperHandlesEmptyString) {
EXPECT_EQ(StringUtils::toUpper(""), "");
}
// Bài 2
TEST_F(BankAccountTest, DepositIncreasesBalance) {
account->deposit(500);
EXPECT_DOUBLE_EQ(account->getBalance(), 1500.0);
}
TEST_F(BankAccountTest, WithdrawDecreasesBalance) {
account->withdraw(300);
EXPECT_DOUBLE_EQ(account->getBalance(), 700.0);
}
TEST_F(BankAccountTest, WithdrawThrowsOnInsufficientFunds) {
EXPECT_THROW(account->withdraw(2000), std::runtime_error);
}