C言語向けのユニットテスト・フレームワークは数多く存在するため、どれを使ったら良いか迷ってしまいます。そこで、2019年5月現在のおすすめのフレームワークを3つご紹介します。この中から選べば間違いありません。
選定にあたっては、重要と思われる下記の4要件を満たすものから選びました。
- 使い方がわかりやすいこと
- 今も開発が継続していること
- モック対応していること
- 自動テストディスカバリ機能があること
この条件に当てはまるものフレームワークとして、Unity、CppUTest、Google Testの3つがあります。まずは、順番に簡単な紹介からしていきましょう。
Unity
http://www.throwtheswitch.org/
ゲームエンジンのUnityと混同してしまいそうですが、これは別物です。C言語用に作られたユニットテスト・フレームワークで、テストコードもモックも全てC言語です。
Unity単体でも使用可能ですが、CMockとCeedlingを組み合わせることでより柔軟にテストを行うことができます。
CMockはモックにしたいモジュールのヘッダファイルを使って、モックを自動生成してくれるツールです。
Ceedlingはテストビルド管理ツールで、UnityとCMockを組み合わせてテストを実行してくれます。Unity単体だと自動テストディスカバリ機能はありませんが、Ceedlingと組み合わせることで実現できます。
CeedlingはRubyとRakeで作られているので、これらのインストールも必要です。入ってない人には準備がちょっと面倒ですね。
CppUTest
C/C++の両方で使えるように設計して作られたユニットテスト・フレームワークです。
テストコードやモックはCでもC++でも同じような書き方ができるところが特徴的です。
メモリリーク検出機能がデフォルトで付いているのが地味に嬉しいですね。
Google Test
https://github.com/google/googletest
Googleが開発したC++用のユニットテスト・フレームワークです。C++用ですがC言語用としても利用できます。
モックはGoogle Mockを使います。非常にシンプルな書き方でモックを作れるのが特徴ですが、残念ながらこの機能はC言語では利用できません。
Unity、CppUTest、Google Testの比較
ご紹介した3つのフレームワークをいくつかの観点で比較してみましょう。
インストール
どのフレームワークもライブラリとしてリンクすれば使えるようになるので、単体のインストールの難易度はどれもあまり変わりません。
ユニットテストにおいて自動テストディスカバリのあるなしで作業効率が大きく変わりますので、これを必須とするとUnityはCeedlingもインストールしなければならないのが、少し面倒ですね。
テストコードの書き方
それぞれのテストコードの書き方を見てみましょう。
Unity
void test_FunctionUnderTest_should_ReturnFive(void) {
TEST_ASSERT_EQUAL_INT( 5, FunctionUnderTest() );
TEST_ASSERT_EQUAL_INT( 5, FunctionUnderTest() ); //twice even!
}
引用:http://www.throwtheswitch.org/unity
CppUTest
TEST(FirstTestGroup, SecondTest)
{
STRCMP_EQUAL(“hello”, “world”);
}
引用:https://cpputest.github.io/manual.html
Google Test
// 正の数の階乗をテスト
TEST(FactorialTest, HandlesPositiveInput) {
EXPECT_EQ(1, Factorial(1));
EXPECT_EQ(2, Factorial(2));
EXPECT_EQ(6, Factorial(3));
EXPECT_EQ(40320, Factorial(8));
}
引用:http://opencv.jp/googletestdocs/primer.html
テストコードの書き方は異なりますが、どれも同じくらい簡単に書けまし、わかりやすいです。さすがにどのフレームワークも洗練されていますね。
モックの書き方
次にモックの書き方を見ていきたいのですが、UnityのCMockはソースコードが自動生成されますし、Google TestのGoogle MockはC言語では利用不可のため、CppUTestだけご紹介します。
CppUTest (CppUMock)
int function () {
return mock().actualCall(“function”).returnIntValue();
}
引用:https://cpputest.github.io/mocking_manual.html
C言語でもC++でも書けるようにするためなのか、少し手間かもしれません。引数が多い場合などは複数行にわたってしまうかもしれません。でも、直感的にわかりやすいAPIとなっていて難しさはありません。
まとめ
私の一番のおすすめは、単品で自動テストディスカバリ機能がついていて、モックも作りやすいCppUTestです。C言語のユニットテスト・フレームワークでは最適と思います。迷ったらこれにしておきましょう。
モックは必要ないということであれば、Google Testもおすすめです。こちらも単品で自動テストディスカバリ機能がついているので、使い勝手は非常に良いです。
CppUTestとGoogle TestはテストコードにC++がどうしても入ってしまうので、それを嫌う場合にはUnityを使うのが良いでしょう。
終わりに、私はC言語のユニットテストにCppUTestを使っています。参考になる記事も書いていますので、良ければご覧になってください。