環境
Ubuntu 20.04@WSL2
❯ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.3 LTS
Release: 20.04
Codename: focal
C++ compiler: g++
❯ g++ --version
g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
やること
Google Testを使ったC++の単体テスト。(初心者はビルドツールはBazelを使うことを推奨している)
If you’re using GoogleTest for the first time or need a refresher, we recommend this tutorial as a starting point.
Quickstart: Building with Bazel
Bazelのインストール
Bazelを直接インストールのではなく、Bazeliskというラッパーをインストールする。go install, npm installらへんでインストールするのが楽
npm install -g @bazel/bazelisk
bazelisk/README.md at master · bazelbuild/bazelisk
npmでインストール後は、 bazel
baselisk
のシンボリックリンクが追加されていた
~/.nvm/versions/node/v15.3.0/bin ※PATHがすでに通っている
bazel -> ../lib/node_modules/@bazel/bazelisk/bazelisk.js ※インストール後追加されていた
bazelisk -> ../lib/node_modules/@bazel/bazelisk/bazelisk.js ※インストール後追加されていた
Bazel workspaceの用意
テストコードを追加するローカルリポジトリをBazel workspaceとする
まず、このworkspace内で使用するBazelのバージョンを指定するために、リポジトリのroot直下に .bazelversion
ファイルを用意する。
cd ${workspaceとするディレクトリのパス}
echo '5.1.0' > .bazelversion
Google Testの依存を追加するために、WORKSPACE
ファイルを追加する。
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "com_google_googletest",
urls = ["https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip"],
strip_prefix = "googletest-609281088cfefc76f9d0ce82e1ff6c30cc3591e5",
)
これでGoogleTestの依存関係を追加できているはずなので、GoogleTestをインクルードしたテストコードをビルドすることができる。
テストコードを用意して、ビルド実行
テストコード追加
#include <gtest/gtest.h>
// Demonstrate some basic assertions.
TEST(HelloTest, BasicAssertions) {
// Expect two strings not to be equal.
EXPECT_STRNE("hello", "world");
// Expect equality.
EXPECT_EQ(7 * 6, 42);
}
BUILD
ファイルを追加
cc_test(
name = "hello_test",
size = "small",
srcs = ["hello_test.cc"],
deps = ["@com_google_googletest//:gtest_main"],
)
ビルド実行
//以降は、BUILDファイルのWorkspaceのルートからの相対パス。
bazel test --test_output=all //:hello_test
bazel test --test_output=all //${BUILDファイルのパス}:${name}
Build Tutorial - C++
Googletestの書き方
Googletest Primer
テストを書く前に
用語
googletestはISTQBなどで定義される、一般的な用語の定義とは違うので、注意が必要
Meaning |
googletest term |
ISTQB term |
grouping related tests |
Test Case |
Test Suite |
Exercise a particular program path with specific input values and verify the results |
Test |
Test Case |
Assertions
googletest assertionsはマクロ
Assertions |
Description |
ASSERT_* |
generate fatal failures when they fail, and abort the current function |
EXPECT_* |
generate nonfatal failures, which don’t abort the current function. |
Assertions Reference
Assertions Reference
シンプルなテストを書く
フォーマット
- 第一引数:the name of the test suite
- 第二引数:the test’s name within the test suite
※どちらもC++で有効なidentiferで、_
は使えない
TEST(TestSuiteName, TestName) {
... test body ...
}
自分はこういう風にした
インクルードが面倒でよくわからなかったので、パッケージごとにBUILDファイル用意。パッケージのディレクトリ直下に必要なファイルをすべて用意。
lib配下にパッケージのディレクトリを作成
cd lib
mdkir Math ※パッケージ名の例
問題を解いたあとに、スニペットにしておきたいと思ったものを、関数にしておく
touch digit.hpp
2.の単体テストコードを用意
touch digitTest.cpp
作成したパッケージのディレクトリ内にBUILDファイルを用意
touch BUILD
cc_test(
name = "lib_math_test", ※任意の名前。実行する際に使う
size = "small",
srcs = ["digit.hpp","digitTest.cpp"], ※テストコードと、テストコードがインクルードするファイルを記載
deps = ["@com_google_googletest//:gtest_main"],
)
テスト実行
bazel test --test_output=all //lib/Math:lib_math_test ※Mathパッケージ配下のテストコードを実行する
完成したらVSCode用にスニペットにしておく
snippet generator
ディレクトリ構成
lib
└── Math ※パッケージ
├── BUILD ※パッケージごとに用意
├── digit.h ※実装ファイル(今回はテンプレート関数だったので、実装もヘッダファイルで宣言。なのでヘッダファイルのみ)
└── digitTest.cpp ※テストコード
テンプレート関数のテストを書く時に参考にした記事
テンプレートのヘッダを用意した場合の注意点。テンプレートはヘッダに宣言だけでなく実装も定義する。
C++ テンプレート ヘッダと実装を別にした時に起こること - Qiita
その他
Google C++ スタイルガイド 日本語全訳