🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

ユニットテスト

ユニットテストは、システムのテスト手法の一つで、個々のモジュールを対象としたテストの事を指します。対象のモジュールが要求や性能を満たしているか確認する為に実行します。

テスト駆動開発

テスト駆動開発は、 プログラム開発手法の一種で、 プログラムに必要な各機能をテストとして書き、 そのテストが動作する必要最低限な実装を行い コードを洗練させる、といったサイクルを繰り返す手法の事です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

4028閲覧

CppUTestでprivateメンバ関数のテストコードを書く良い方法は?

hagi3to5

総合スコア23

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

ユニットテスト

ユニットテストは、システムのテスト手法の一つで、個々のモジュールを対象としたテストの事を指します。対象のモジュールが要求や性能を満たしているか確認する為に実行します。

テスト駆動開発

テスト駆動開発は、 プログラム開発手法の一種で、 プログラムに必要な各機能をテストとして書き、 そのテストが動作する必要最低限な実装を行い コードを洗練させる、といったサイクルを繰り返す手法の事です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

2クリップ

投稿2021/02/26 14:31

前提・実現したいこと

最近CppUTestでテストコードを書き始めたのですが、C++11で実装済みのクラスを検証するためのテストコードを書く中で、classのprivateメンバのテストコードをきれいに実装する方法が見つからず悩んでいます。

現在は、後述の「試したことの4.」に書いたstaticな非メンバ関数で実装しなおす方針で進めていますが、このままだとprivateメンバ変数も参照したくなる予感もしており、このまま進めてよいのか悩んでいます。

classのprivateメンバのテストは、どう実現するのが良いのでしょうか?皆様はどのように対応してますか?

  • 後述の「試したことの2.~4.」のいずれかを採用している
  • 別のもっと良いテストコードの実装方法を使っている
  • 評価しにくいclassの設計・実装が悪い
  • そもそもclassの内部処理を評価しようとすること自体が悪い
  • CppUTest以外のツールを使えば解決する
  • その他

該当のソースコード

c++

1class Hoge{ 2public: 3 Hoge() : hoge_(0){} 4 int update(){ 5 // 前処理やって 6 return updateHoge(); 7 } 8 9private: 10 int updateHoge(){/*テストしたい複雑な処理部*/} 11 int hoge_; 12};

試したこと

  1. 参考書として**"テスト駆動開発による組み込みプログラミング ―C言語とオブジェクト指向で学ぶアジャイルな設計"**を読んでいるのですが、すっきりする解決方法がわかりませんでした。
  2. private:をPRIVATE:に置き換えて、CppUTestビルド時のみ#define PRIVATE publicにする。

→ 既存コードに手を入れる必要があり、なんとなく不格好になったため不採用
0. GoogleTestのようにテストモジュールをclass Hogeのfirendに追加する方法をCppUTestで実現する。
→ 既存コードに手を入れますがfirend追加だけなので1よりマシと考えましたが、CppUTestでの実装方法がわからず断念
0. 評価したいprivateメンバ関数をstaticな非メンバ関数(例:static void Hoge_updateHoge(int&))にし、コール側で必要なメンバ変数を引数で渡すよう実装しなおす。
→ 今はこれで進めてますが、メンバ変数はどうするのか?もっとスマートな方法があるのでは?とモヤモヤしています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

GoogleTestのようにテストモジュールをclass Hogeのfirendに追加する方法をCppUTestで実現する。

→ 既存コードに手を入れますがfirend追加だけなので1よりマシと考えましたが、CppUTestでの実装方法がわからず断念

include/CppUTest/UtestMacros.h によると:

C++

1#define TEST(testGroup, testName) \ 2 /* External declarations for strict compilers */ \ 3 class TEST_##testGroup##_##testName##_TestShell; \ 4 extern TEST_##testGroup##_##testName##_TestShell TEST_##testGroup##_##testName##_TestShell_instance; \ 5 \ 6 class TEST_##testGroup##_##testName##_Test : public TEST_GROUP_##CppUTestGroup##testGroup \ 7{ public: TEST_##testGroup##_##testName##_Test () : TEST_GROUP_##CppUTestGroup##testGroup () {} \ 8 void testBody(); }; \ 9 class TEST_##testGroup##_##testName##_TestShell : public UtestShell { \ 10 virtual Utest* createTest() _override { return new TEST_##testGroup##_##testName##_Test; } \ 11 } TEST_##testGroup##_##testName##_TestShell_instance; \ 12 static TestInstaller TEST_##testGroup##_##testName##_Installer(TEST_##testGroup##_##testName##_TestShell_instance, #testGroup, #testName, __FILE__,__LINE__); \ 13 void TEST_##testGroup##_##testName##_Test::testBody()

なので、TEST(A,B) を friend とするには friend class TEST_A_B_Test; でよさげ。
※ あるいは friend void TEST_A_B_Test::testBody(); か。

投稿2021/02/28 00:40

編集2021/02/28 01:32
episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hagi3to5

2021/03/01 13:42

ありがとうございます。早速試してみます!
hagi3to5

2021/03/06 07:58

確認が遅くなりましたが、以下の方法で上手くいきました。ありがとうございました。 #define FRIEND_TEST(x,y) friend class TEST_##x##_##y##_Test; class HOGE{ FRIEND_TEST(HogeTest, test_hoge); }
guest

0

結論から言えば 3 が一般的には良いとされる考え方です。 プライベートなメンバは基本的に外へ見せたくないメンバだからそうなっているわけですが、どうしても出すのであれば範囲はコントロールされて然るべきだからです。 それがテストであっても同様です。

投稿2021/02/26 17:34

SaitoAtsushi

総合スコア5684

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hagi3to5

2021/03/01 13:43

回答ありがとうございます。 CppUTestでGoogleTestのようにfriendでテスト関数を書く方針でもう一度検討してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問