「Google Test」の版間の差分
提供: C++入門
(ページの作成:「<!-- vim: filetype=mediawiki --> Google Test は、 C++ 向けのユニットテストフレームワークです。 読み方 ;Google Test: ぐー...」) |
|||
(同じ利用者による、間の3版が非表示) | |||
行12: | 行12: | ||
== 概要 == | == 概要 == | ||
+ | |||
+ | Google [[C++]] Testing Framework です。 | ||
+ | |||
+ | 赤と緑のカラー表示で、コンソールでも賑やかでステキです。 | ||
== インストール == | == インストール == | ||
行30: | 行34: | ||
が作成されます。 | が作成されます。 | ||
+ | |||
+ | == アサーション == | ||
+ | |||
+ | [[Google Test]] のアサーションは、マクロです。動作を調べるために、アサーションを利用します。 | ||
+ | |||
+ | ASSERT_* バージョンが失敗した場合は、致命的な失敗となり、実行中の関数を中断します。 | ||
+ | EXPECT_* バージョンが失敗した場合は、致命的ではない失敗となり、関数を中断しません。 | ||
+ | |||
+ | === 基本的なアサーション === | ||
+ | |||
+ | {|class="wikitable" | ||
+ | |+ 基本的なアサーション | ||
+ | !致命的なアサーション | ||
+ | !致命的ではないアサーション | ||
+ | !検証内容 | ||
+ | |---- | ||
+ | |ASSERT_TRUE(condition); | ||
+ | |EXPECT_TRUE(condition); | ||
+ | |condition が true | ||
+ | |---- | ||
+ | |ASSERT_FALSE(condition); | ||
+ | |EXPECT_FALSE(condition); | ||
+ | |condition が false | ||
+ | |---- | ||
+ | |} | ||
+ | |||
+ | === 2つの値の比較 === | ||
+ | |||
+ | {|class="wikitable" | ||
+ | |+ 2つの値の比較 | ||
+ | !致命的なアサーション | ||
+ | !致命的ではないアサーション | ||
+ | !検証内容 | ||
+ | |---- | ||
+ | |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); | ||
+ | |val1 >= val2 | ||
+ | |---- | ||
+ | |} | ||
+ | |||
+ | === 文字列の比較 === | ||
+ | |||
+ | {|class="wikitable" | ||
+ | |+ 文字列の比較 | ||
+ | !致命的なアサーション | ||
+ | !致命的ではないアサーション | ||
+ | !検証内容 | ||
+ | |---- | ||
+ | |ASSERT_STREQ(expected_str, actual_str); | ||
+ | |EXPECT_STREQ(expected_str, actual_str); | ||
+ | |2つの C 文字列の内容が等しい | ||
+ | |---- | ||
+ | |ASSERT_STRNE(str1, str2); | ||
+ | |EXPECT_STRNE(str1, str2); | ||
+ | |2つの C 文字列の内容が等しくない | ||
+ | |---- | ||
+ | |ASSERT_STRCASEEQ(expected_str, actual_str); | ||
+ | |EXPECT_STRCASEEQ(expected_str, actual_str); | ||
+ | |大文字小文字を無視した場合,2つの C 文字列の内容が等しい | ||
+ | |---- | ||
+ | |ASSERT_STRCASENE(str1, str2); | ||
+ | |EXPECT_STRCASENE(str1, str2); | ||
+ | |大文字小文字を無視した場合,2つの C 文字列の内容が等しくない | ||
+ | |---- | ||
+ | |} | ||
+ | |||
+ | == main()関数を書く == | ||
+ | |||
+ | |||
+ | <syntaxhighlight lang="cpp"> | ||
+ | #include "this/package/foo.h" | ||
+ | #include "gtest/gtest.h" | ||
+ | |||
+ | namespace { | ||
+ | |||
+ | // The fixture for testing class Foo. | ||
+ | class FooTest : public ::testing::Test { | ||
+ | protected: | ||
+ | // You can remove any or all of the following functions if its body | ||
+ | // is empty. | ||
+ | |||
+ | FooTest() { | ||
+ | // You can do set-up work for each test here. | ||
+ | } | ||
+ | |||
+ | virtual ~FooTest() { | ||
+ | // You can do clean-up work that doesn't throw exceptions here. | ||
+ | } | ||
+ | |||
+ | // If the constructor and destructor are not enough for setting up | ||
+ | // and cleaning up each test, you can define the following methods: | ||
+ | |||
+ | virtual void SetUp() { | ||
+ | // Code here will be called immediately after the constructor (right | ||
+ | // before each test). | ||
+ | } | ||
+ | |||
+ | virtual void TearDown() { | ||
+ | // Code here will be called immediately after each test (right | ||
+ | // before the destructor). | ||
+ | } | ||
+ | |||
+ | // Objects declared here can be used by all tests in the test case for Foo. | ||
+ | }; | ||
+ | |||
+ | // Tests that the Foo::Bar() method does Abc. | ||
+ | TEST_F(FooTest, MethodBarDoesAbc) { | ||
+ | const string input_filepath = "this/package/testdata/myinputfile.dat"; | ||
+ | const string output_filepath = "this/package/testdata/myoutputfile.dat"; | ||
+ | Foo f; | ||
+ | EXPECT_EQ(0, f.Bar(input_filepath, output_filepath)); | ||
+ | } | ||
+ | |||
+ | // Tests that Foo does Xyz. | ||
+ | TEST_F(FooTest, DoesXyz) { | ||
+ | // Exercises the Xyz feature of Foo. | ||
+ | } | ||
+ | |||
+ | } // namespace | ||
+ | |||
+ | int main(int argc, char **argv) { | ||
+ | ::testing::InitGoogleTest(&argc, argv); | ||
+ | return RUN_ALL_TESTS(); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
== ヘッダファイル == | == ヘッダファイル == | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
+ | /usr/local/include/gtest/gtest-death-test.h | ||
+ | /usr/local/include/gtest/gtest-message.h | ||
+ | /usr/local/include/gtest/gtest-param-test.h | ||
+ | /usr/local/include/gtest/gtest-spi.h | ||
+ | /usr/local/include/gtest/gtest-test-part.h | ||
+ | /usr/local/include/gtest/gtest-typed-test.h | ||
+ | /usr/local/include/gtest/gtest.h | ||
+ | /usr/local/include/gtest/gtest_pred_impl.h | ||
+ | /usr/local/include/gtest/gtest_prod.h | ||
+ | /usr/local/include/gtest/internal/gtest-death-test-internal.h | ||
+ | /usr/local/include/gtest/internal/gtest-filepath.h | ||
+ | /usr/local/include/gtest/internal/gtest-internal.h | ||
+ | /usr/local/include/gtest/internal/gtest-linked_ptr.h | ||
+ | /usr/local/include/gtest/internal/gtest-param-util-generated.h | ||
+ | /usr/local/include/gtest/internal/gtest-param-util.h | ||
+ | /usr/local/include/gtest/internal/gtest-port.h | ||
+ | /usr/local/include/gtest/internal/gtest-string.h | ||
+ | /usr/local/include/gtest/internal/gtest-tuple.h | ||
+ | /usr/local/include/gtest/internal/gtest-type-util.h | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | == 実行例 == | ||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
+ | g++ $(gtest-config --cppflags --cxxflags) -o foo.o -c foo.cpp | ||
+ | g++ $(gtest-config --ldflags --libs) -o foo foo.o | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | == ソースコード == | + | == サンプルコード == |
+ | |||
+ | === ソースコード foo.hpp === | ||
+ | |||
+ | プログラムの実装です。 | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
+ | #ifndef FOO_HPP | ||
+ | #define FOO_HPP | ||
+ | #include <exception> | ||
+ | #include <string> | ||
+ | |||
+ | class foo { | ||
+ | public: | ||
+ | int add(int a, int b) { | ||
+ | return a+b; | ||
+ | } | ||
+ | |||
+ | void throw_exception () throw(std::exception) { | ||
+ | throw std::exception (); | ||
+ | } | ||
+ | |||
+ | void no_throw_exception () { | ||
+ | ; | ||
+ | } | ||
+ | |||
+ | std::string get_str_foo () throw () { | ||
+ | return std::string("foo"); | ||
+ | } | ||
+ | |||
+ | bool is_true () { | ||
+ | return true; | ||
+ | } | ||
+ | |||
+ | bool is_false () { | ||
+ | return false; | ||
+ | } | ||
+ | |||
+ | }; | ||
+ | #endif // FOO_HPP | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | === ソースコード gtest_main.cpp === | ||
+ | テストプログラムのメイン関数です。 | ||
+ | <syntaxhighlight lang="cpp"> | ||
+ | #include <gtest/gtest.h> | ||
− | == | + | int |
+ | main(int argc, char *argv[]) | ||
+ | { | ||
+ | ::testing::InitGoogleTest(&argc, argv); | ||
+ | return RUN_ALL_TESTS(); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === ソースコード fooTest.cpp === | ||
+ | |||
+ | テストコードの実体です。 | ||
+ | gtest_main.cpp とわけなくても構いません。 | ||
+ | |||
+ | <syntaxhighlight lang="cpp"> | ||
+ | #include <gtest/gtest.h> | ||
+ | |||
+ | #include "foo.hpp" | ||
+ | |||
+ | TEST(foo, add) { | ||
+ | foo f; | ||
+ | ASSERT_EQ(3, f.add(1,2)); | ||
+ | ASSERT_EQ(4, f.add(2,2)); | ||
+ | } | ||
+ | |||
+ | TEST(foo, get_str_foo) { | ||
+ | foo f; | ||
+ | ASSERT_EQ("foo", f.get_str_foo()); | ||
+ | } | ||
+ | |||
+ | TEST(foo, is) { | ||
+ | foo f; | ||
+ | ASSERT_TRUE(f.is_true ()); | ||
+ | //ASSERT_FALSE(f.is_true ()); | ||
+ | ASSERT_FALSE(f.is_false ()); | ||
+ | } | ||
+ | |||
+ | TEST(foo, exception) { | ||
+ | foo f; | ||
+ | ASSERT_THROW(f.throw_exception(), std::exception); | ||
+ | ASSERT_NO_THROW(f.no_throw_exception()); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === コンパイル === | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
+ | g++ `gtest-config --ldflags --libs ` -I`gtest-config --includedir`gtest_main.cpp fooTest.cpp | ||
+ | |||
+ | # sh系ならこれでもよい。 | ||
+ | g++ $(gtest-config --ldflags --libs ) -I$(gtest-config --includedir) gtest_main.cpp fooTest.cpp | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === 実行例 === | ||
+ | |||
+ | すべてのテストが成功する例です。 | ||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
+ | ./a.out | ||
+ | [==========] Running 4 tests from 1 test case. | ||
+ | [----------] Global test environment set-up. | ||
+ | [----------] 4 tests from foo | ||
+ | [ RUN ] foo.add | ||
+ | [ OK ] foo.add (0 ms) | ||
+ | [ RUN ] foo.get_str_foo | ||
+ | [ OK ] foo.get_str_foo (0 ms) | ||
+ | [ RUN ] foo.is | ||
+ | [ OK ] foo.is (0 ms) | ||
+ | [ RUN ] foo.exception | ||
+ | [ OK ] foo.exception (1 ms) | ||
+ | [----------] 4 tests from foo (1 ms total) | ||
+ | |||
+ | [----------] Global test environment tear-down | ||
+ | [==========] 4 tests from 1 test case ran. (2 ms total) | ||
+ | [ PASSED ] 4 tests. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | is_true() を失敗させた例です。 | ||
+ | <syntaxhighlight lang="bash"> | ||
+ | [==========] Running 4 tests from 1 test case. | ||
+ | [----------] Global test environment set-up. | ||
+ | [----------] 4 tests from foo | ||
+ | [ RUN ] foo.add | ||
+ | [ OK ] foo.add (0 ms) | ||
+ | [ RUN ] foo.get_str_foo | ||
+ | [ OK ] foo.get_str_foo (0 ms) | ||
+ | [ RUN ] foo.is | ||
+ | fooTest.cpp:19: Failure | ||
+ | Value of: f.is_true () | ||
+ | Actual: true | ||
+ | Expected: false | ||
+ | [ FAILED ] foo.is (1 ms) | ||
+ | [ RUN ] foo.exception | ||
+ | [ OK ] foo.exception (2 ms) | ||
+ | [----------] 4 tests from foo (4 ms total) | ||
+ | |||
+ | [----------] Global test environment tear-down | ||
+ | [==========] 4 tests from 1 test case ran. (4 ms total) | ||
+ | [ PASSED ] 3 tests. | ||
+ | [ FAILED ] 1 test, listed below: | ||
+ | [ FAILED ] foo.is | ||
+ | 1 FAILED TEST | ||
</syntaxhighlight> | </syntaxhighlight> | ||
行54: | 行369: | ||
* [[ユニットテストフレームワーク]] | * [[ユニットテストフレームワーク]] | ||
+ | * [[gtest-config]] |
2013年3月9日 (土) 15:52時点における最新版
Google Test は、 C++ 向けのユニットテストフレームワークです。
読み方
- Google Test
- ぐーぐる てすと
目次
概要
Google C++ Testing Framework です。
赤と緑のカラー表示で、コンソールでも賑やかでステキです。
インストール
FreeBSDにインストールする場合
ports コレクションからインストールする場合
cd /usr/ports/devel/googletest sudo make install clean
pkgコマンドでインストールする場合
sudo pkg install googletest
portmasterコマンドでインストールする場合
sudo portmaster -y -d /usr/ports/devel/googletest
ソースからビルド
svn checkout http://googletest.googlecode.com/svn/trunk/ googletest-read-only cd googletest-read-only cmake . gmake
./libgtest.a ./libgtest_main.a
が作成されます。
アサーション
Google Test のアサーションは、マクロです。動作を調べるために、アサーションを利用します。
ASSERT_* バージョンが失敗した場合は、致命的な失敗となり、実行中の関数を中断します。 EXPECT_* バージョンが失敗した場合は、致命的ではない失敗となり、関数を中断しません。
基本的なアサーション
致命的なアサーション | 致命的ではないアサーション | 検証内容 |
---|---|---|
ASSERT_TRUE(condition); | EXPECT_TRUE(condition); | condition が true |
ASSERT_FALSE(condition); | EXPECT_FALSE(condition); | condition が false |
2つの値の比較
致命的なアサーション | 致命的ではないアサーション | 検証内容 |
---|---|---|
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); | val1 >= val2 |
文字列の比較
致命的なアサーション | 致命的ではないアサーション | 検証内容 |
---|---|---|
ASSERT_STREQ(expected_str, actual_str); | EXPECT_STREQ(expected_str, actual_str); | 2つの C 文字列の内容が等しい |
ASSERT_STRNE(str1, str2); | EXPECT_STRNE(str1, str2); | 2つの C 文字列の内容が等しくない |
ASSERT_STRCASEEQ(expected_str, actual_str); | EXPECT_STRCASEEQ(expected_str, actual_str); | 大文字小文字を無視した場合,2つの C 文字列の内容が等しい |
ASSERT_STRCASENE(str1, str2); | EXPECT_STRCASENE(str1, str2); | 大文字小文字を無視した場合,2つの C 文字列の内容が等しくない |
main()関数を書く
#include "this/package/foo.h" #include "gtest/gtest.h" namespace { // The fixture for testing class Foo. class FooTest : public ::testing::Test { protected: // You can remove any or all of the following functions if its body // is empty. FooTest() { // You can do set-up work for each test here. } virtual ~FooTest() { // You can do clean-up work that doesn't throw exceptions here. } // If the constructor and destructor are not enough for setting up // and cleaning up each test, you can define the following methods: virtual void SetUp() { // Code here will be called immediately after the constructor (right // before each test). } virtual void TearDown() { // Code here will be called immediately after each test (right // before the destructor). } // Objects declared here can be used by all tests in the test case for Foo. }; // Tests that the Foo::Bar() method does Abc. TEST_F(FooTest, MethodBarDoesAbc) { const string input_filepath = "this/package/testdata/myinputfile.dat"; const string output_filepath = "this/package/testdata/myoutputfile.dat"; Foo f; EXPECT_EQ(0, f.Bar(input_filepath, output_filepath)); } // Tests that Foo does Xyz. TEST_F(FooTest, DoesXyz) { // Exercises the Xyz feature of Foo. } } // namespace int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
ヘッダファイル
/usr/local/include/gtest/gtest-death-test.h /usr/local/include/gtest/gtest-message.h /usr/local/include/gtest/gtest-param-test.h /usr/local/include/gtest/gtest-spi.h /usr/local/include/gtest/gtest-test-part.h /usr/local/include/gtest/gtest-typed-test.h /usr/local/include/gtest/gtest.h /usr/local/include/gtest/gtest_pred_impl.h /usr/local/include/gtest/gtest_prod.h /usr/local/include/gtest/internal/gtest-death-test-internal.h /usr/local/include/gtest/internal/gtest-filepath.h /usr/local/include/gtest/internal/gtest-internal.h /usr/local/include/gtest/internal/gtest-linked_ptr.h /usr/local/include/gtest/internal/gtest-param-util-generated.h /usr/local/include/gtest/internal/gtest-param-util.h /usr/local/include/gtest/internal/gtest-port.h /usr/local/include/gtest/internal/gtest-string.h /usr/local/include/gtest/internal/gtest-tuple.h /usr/local/include/gtest/internal/gtest-type-util.h
実行例
g++ $(gtest-config --cppflags --cxxflags) -o foo.o -c foo.cpp g++ $(gtest-config --ldflags --libs) -o foo foo.o
サンプルコード
ソースコード foo.hpp
プログラムの実装です。
#ifndef FOO_HPP #define FOO_HPP #include <exception> #include <string> class foo { public: int add(int a, int b) { return a+b; } void throw_exception () throw(std::exception) { throw std::exception (); } void no_throw_exception () { ; } std::string get_str_foo () throw () { return std::string("foo"); } bool is_true () { return true; } bool is_false () { return false; } }; #endif // FOO_HPP
ソースコード gtest_main.cpp
テストプログラムのメイン関数です。
#include <gtest/gtest.h> int main(int argc, char *argv[]) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
ソースコード fooTest.cpp
テストコードの実体です。 gtest_main.cpp とわけなくても構いません。
#include <gtest/gtest.h> #include "foo.hpp" TEST(foo, add) { foo f; ASSERT_EQ(3, f.add(1,2)); ASSERT_EQ(4, f.add(2,2)); } TEST(foo, get_str_foo) { foo f; ASSERT_EQ("foo", f.get_str_foo()); } TEST(foo, is) { foo f; ASSERT_TRUE(f.is_true ()); //ASSERT_FALSE(f.is_true ()); ASSERT_FALSE(f.is_false ()); } TEST(foo, exception) { foo f; ASSERT_THROW(f.throw_exception(), std::exception); ASSERT_NO_THROW(f.no_throw_exception()); }
コンパイル
g++ `gtest-config --ldflags --libs ` -I`gtest-config --includedir`gtest_main.cpp fooTest.cpp # sh系ならこれでもよい。 g++ $(gtest-config --ldflags --libs ) -I$(gtest-config --includedir) gtest_main.cpp fooTest.cpp
実行例
すべてのテストが成功する例です。
./a.out [==========] Running 4 tests from 1 test case. [----------] Global test environment set-up. [----------] 4 tests from foo [ RUN ] foo.add [ OK ] foo.add (0 ms) [ RUN ] foo.get_str_foo [ OK ] foo.get_str_foo (0 ms) [ RUN ] foo.is [ OK ] foo.is (0 ms) [ RUN ] foo.exception [ OK ] foo.exception (1 ms) [----------] 4 tests from foo (1 ms total) [----------] Global test environment tear-down [==========] 4 tests from 1 test case ran. (2 ms total) [ PASSED ] 4 tests.
is_true() を失敗させた例です。
[==========] Running 4 tests from 1 test case. [----------] Global test environment set-up. [----------] 4 tests from foo [ RUN ] foo.add [ OK ] foo.add (0 ms) [ RUN ] foo.get_str_foo [ OK ] foo.get_str_foo (0 ms) [ RUN ] foo.is fooTest.cpp:19: Failure Value of: f.is_true () Actual: true Expected: false [ FAILED ] foo.is (1 ms) [ RUN ] foo.exception [ OK ] foo.exception (2 ms) [----------] 4 tests from foo (4 ms total) [----------] Global test environment tear-down [==========] 4 tests from 1 test case ran. (4 ms total) [ PASSED ] 3 tests. [ FAILED ] 1 test, listed below: [ FAILED ] foo.is 1 FAILED TEST