下載地址:https://github.com/google/googletest
ios
在分支中找到1.8.x版本:
c++
使用VS2015打開sln文件:
git
Debug 64位項目屬性配置, 配置完後生成項目:
github
Release 64位:
express
爲了方即可以將生成的lib複製或剪切到一個單獨的文件夾中,例如個人就是將其複製到我新建的build文件夾中:
函數
建立一個VC++控制檯項目,打開屬性管理器便可一次配置全局使用, 以Debug x64爲例配置以下:
測試
項目結構及代碼以下:
ui
// Sample.hpp #pragma once // 簡單粗暴實現的幾個C風格字符串相關函數 /** * @brief 字符串拷貝 * @param des 目標字符串,長度必需要 >= 源字符串的長度 + 1 * @param src 源字符串 * @return 目標字符串首地址 */ char* a_strcpy(char* des, const char* src) { if (!des || !src) return nullptr; char* address = des; while (*src != '\0') { *des = *src; des++; src++; } *des = '\0'; return address; } /** * @brief 字符串長度計算 * @param src 字符串 * @return 字符串長度 */ size_t a_strlen(const char* src) { if (!src) return 0; size_t len = 0; while (*src != '\0') { ++len; ++src; } return len; } /** * @brief 將src字符串追加在des尾部, 用戶需保證des和src內存區域不重疊且des必須有足夠大的空間來存放src * @param des 目標字符串 * @param src 源字符串 * @return 尾部追加過源字符串的目標字符串 */ char* a_strcat(char* des, const char* src) { if (!des) return nullptr; if (!src) return des; char* address = des; while (*des != '\0') { des++; } while (*src != '\0') { *des = *src; des++; src++; } *des = '\0'; return address; } /** * @brief 字符串比較 * @param s1 字符串1 * @param s2 字符串2 * @return s1或s2爲nullptr,返回-2; s1<s2,返回-1; s1=s2,返回0; s2>s2,返回1; */ int a_strcmp(const char* s1, const char* s2) { if (!s1 || !s2) return -2; while (*s1 != '\0' && *s2 != '\0') { if (*s1 < *s2) { return -1; } else if (*s1 == *s2) { s1++; s2++; } else if (*s1 > * s2) { return 1; } } if (*s1 == '\0' && *s2 != '\0') { return -1; } else if (*s1 == '\0' && *s2 == '\0') { return 0; } else if (*s1 != '\0' && *s2 == '\0') { return 1; } }
// Test.cpp #include <iostream> #include <gtest/gtest.h> // GoogleTest #include "Sample.hpp" // 須要測試的Function TEST(a_strcpy, nullptr) { char* a = ""; EXPECT_STREQ(nullptr, a_strcpy(nullptr, nullptr)); EXPECT_STREQ(nullptr, a_strcpy(a, nullptr)); EXPECT_STREQ(nullptr, a_strcpy(nullptr, a)); } TEST(a_strcpy, negative) { char a[6] = "aaaaa"; char b[2] = "b"; EXPECT_STRNE("baaaa", a_strcpy(a, b)); } TEST(a_strcpy, positive) { char a[6] = "aaaaa"; char b[2] = "b"; EXPECT_STREQ("b", a_strcpy(a, b)); } TEST(a_strlen, nullptr) { EXPECT_EQ(0, a_strlen(nullptr)); } TEST(a_strlen, positive) { EXPECT_EQ(0, a_strlen("")); EXPECT_EQ(1, a_strlen("a")); EXPECT_EQ(2, a_strlen("ab")); } TEST(a_strcat, nullptr) { char a[] = ""; EXPECT_STREQ(nullptr, a_strcat(nullptr, nullptr)); EXPECT_STREQ(a, a_strcat(a, nullptr)); EXPECT_STREQ(nullptr, a_strcat(nullptr, a)); } TEST(a_strcat, positive) { char a[10] = ""; char b[10] = "bbb"; EXPECT_STREQ("", a_strcat(a, "")); EXPECT_STREQ("aaa", a_strcat(a, "aaa")); EXPECT_STREQ("bbb", a_strcat(b, "")); EXPECT_STREQ("bbbaaa", a_strcat(b, "aaa")); } TEST(a_strcmp, nullptr) { EXPECT_EQ(-2, a_strcmp(nullptr, nullptr)); EXPECT_EQ(-2, a_strcmp("", nullptr)); EXPECT_EQ(-2, a_strcmp(nullptr, "")); } TEST(a_strcmp, LT) { EXPECT_EQ(-1, a_strcmp("", "a")); EXPECT_EQ(-1, a_strcmp("a", "ab")); EXPECT_EQ(-1, a_strcmp("ab", "abc")); } TEST(a_strcmp, EQ) { EXPECT_EQ(0, a_strcmp("", "")); EXPECT_EQ(0, a_strcmp("a", "a")); EXPECT_EQ(0, a_strcmp("ab", "ab")); } TEST(a_strcmp, GT) { EXPECT_EQ(1, a_strcmp("a", "")); EXPECT_EQ(1, a_strcmp("ab", "a")); EXPECT_EQ(1, a_strcmp("abc", "ab")); } int main(int argc, char* argv[]) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
測試結果:
google
斷言:gtest中採用了大量的宏來包裝斷言,按照其使用方法能夠分爲兩類:3d
按照經常使用功能能夠依次分爲12類,較經常使用的有如下幾類:
具體以下:
ASSERT系列 | EXPECT系列 | 經過條件 |
---|---|---|
ASSERT_TRUE(condition) | EXPECT_TRUE(condition) | condition == true |
ASSERT_FALSE(condition) | EXPECT_FALSE(condition) | condition == false |
ASSERT系列 | EXPECT系列 | 經過條件 |
---|---|---|
ASSERT_EQ (expected, actual) | EXPECT_EQ (expected, actual) | expected == actual |
ASSERT_NE (val1, val2) | EXPECT_NE (val1, val2) | val1 != val2 |
ASSERT_LT (val1, val2) | EXPECT_LT (val1, val2) | val1 < val2 |
ASSERT_LE (val1, val2) | EXPECT_LE (val1, val2) | val1 <= val2 |
ASSERT_GT (val1, val2) | EXPECT_GT (val1, val2) | val1 > val2 |
ASSERT_GE (val1, val2) | EXPECT_GE (val1, val2) | val2 >= val2 |
ASSERT系列 | EXPECT系列 | 經過條件 |
---|---|---|
ASSERT_STREQ (str1, str2) | EXPECT_STREQ (str1, str2) | 兩個C字符串內容相同(char * or wchar_t *) |
ASSERT_STRNE (str1, str2) | EXPECT_STRNE (str1, str2) | 兩個C字符串內容不一樣(同時支持char *和wchar_t *類型) |
ASSERT_STRCASEEQ (str1, str2) | EXPECT_STRCASEEQ (str1, str2) | 兩個C字符串內容相同,忽略大小寫(只支持char *類型) |
ASSERT_STRCASENE (str1, str2) | EXPECT_STRCASENE (str1, str2) | 兩個C字符串內容不一樣,忽略大小寫(只支持char *類型) |
ASSERT系列 | EXPECT系列 | 經過條件 |
---|---|---|
ASSERT_FLOAT_EQ (val1, val2) | EXPECT_FLOAT_EQ (val1, val2) | the two float values are almost equal |
ASSERT_DOUBLE_EQ (val1, val2) | EXPECT_DOUBLE_EQ (val1, val2) | the two double values are almost equal |
ASSERT系列 | EXPECT系列 | 經過條件 |
---|---|---|
ASSERT_NEAR (val1, val2, abs_error) | EXPECT_NEAR (val1, val2, abs_error) | 兩個數值val1和val2的絕對值差不超過abs_error |
ASSERT系列 | EXPECT系列 | 經過條件 |
---|---|---|
ASSERT_THROW (statement, exception_type) | EXPECT_THROW (statement, exception_type) | 拋出指定類型異常 |
ASSERT_THROW(statement) | EXPECT_THROW(statement) | 拋出任意類型異常 |
ASSERT_NO_THROW(statement) | EXPECT_NO_THROW(statement) | 不拋出異常 |
ASSERT系列 | EXPECT系列 | 經過條件 |
---|---|---|
ASSERT_PRED1(pred1, val1) | EXPECT_PRED1(pred1, val1) | pred1(val1) returns true |
ASSERT_PRED2(pred2, val1, val2) | EXPECT_PRED2(pred2, val1, val2) | pred2(val1, val2) returns true |
ASSERT系列 | EXPECT系列 | 經過條件 |
---|---|---|
ASSERT_HRESULT_SUCCEEDED(expression) | EXPECT_HRESULT_SUCCEEDED(expression) | expression is a success HRESULT |
ASSERT_HRESULT_FAILED(expression) | EXPECT_HRESULT_FAILED(expression) | expression is a failure HRESULT |
ASSERT系列 | EXPECT系列 | 經過條件 |
---|---|---|
ASSERT_PRED_FORMAT1(pred1, val1) | EXPECT_PRED_FORMAT1(pred1, val1) | pred1(val1) is successful |
ASSERT_PRED_FORMAT1(pred1, val1, val2) | EXPECT_PRED_FORMAT1(pred1, val1, val2) | pred2(val1, val2) is successful |