質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.35%
Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

ユニットテスト

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

C++

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

Q&A

解決済

2回答

5793閲覧

C++で単体テストのテストコードでリンクエラーが発生する

MomenToufu

総合スコア10

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

ユニットテスト

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

C++

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

0グッド

0クリップ

投稿2021/08/04 08:29

編集2021/08/04 08:35

前提・実現したいこと

 現在、C++のコードにおいて単体テストについて学習しています。
任意のクラスのメンバー関数を対象としてテストコードを作成したのですが、ビルド時にリンクエラーが発生します。

  1. テストコードでは、対象としているクラスのヘッダーファイルをインクルードしてます。
  2. 対象としてるクラスはヘッダーとソースは別のファイルにしてます。
  3. 2のヘッダーとソースを1つのファイルとした時、この問題は起きません。
  4. テストコードで対象としているクラスのヘッダーとソースファイルをインクルードするとこの問題は起きません。
  5. メイン関数(対象のクラスを宣言、定義しているプロジェクトのメイン関数)からではリンクエラーは発生しません。

これらから、テストコードのプロジェクトから別のプロジェクトの.cpp を見れてないように思うのですが
見れるようにするにはどの様にするのでしょうか?

発生している問題・エラーメッセージ

LNK2019 未解決の外部シンボル "public: int __thiscall TEST_SUM::Sum::sum(void)" が関数 "public: void __thiscall UnitTest1::UnitTest1::TestMethod1(void)" で参照されました LNK2019 未解決の外部シンボル "public: void __thiscall TEST_SUM::Sum::setA(int)" が関数 "public: void __thiscall UnitTest1::UnitTest1::TestMethod1(void)" で参照されました LNK2019 未解決の外部シンボル "public: void __thiscall TEST_SUM::Sum::setB(int)" が関数 "public: void __thiscall UnitTest1::UnitTest1::TestMethod1(void)" で参照されました

該当のソースコード

単体テスト対象のクラス(ヘッダー)

C++

1#pragma once 2namespace TEST_SUM 3{ 4 class Sum 5 { 6 private: 7 int a; 8 int b; 9 10 public: 11 void setA(int a); 12 void setB(int b); 13 14 int sum(); 15 16 Sum() 17 { 18 this->a = 0; 19 this->b = 0; 20 }; 21 }; 22} 23 24

単体テスト対象のクラス(ソース)

C++

1#include "Sum.h" 2void TEST_SUM::Sum::setA(int a) 3{ 4 this->a = a; 5} 6void TEST_SUM::Sum::setB(int b) 7{ 8 this->b = b; 9} 10int TEST_SUM::Sum::sum() 11{ 12 return this->a + this->b; 13}

テストコード

C++

1#include "pch.h" 2#include "CppUnitTest.h" 3#include "../Stady_TEST2/Sum.h" 4//#include "../Stady_TEST2/Sum.cpp" 5 6using namespace Microsoft::VisualStudio::CppUnitTestFramework; 7 8namespace UnitTest1 9{ 10 TEST_CLASS(UnitTest1) 11 { 12 public: 13 TEST_METHOD(TestMethod1) 14 { 15 TEST_SUM::Sum ABC; 16 ABC.setA(10); 17 ABC.setB(10); 18 19 Assert::AreEqual(20, ABC.sum()); 20 } 21 }; 22}

補足情報(FW/ツールのバージョンなど)

Visual Studio 2019
Microsoft CppUnitTestフレームワークを使用

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

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

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

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

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

guest

回答2

0

ベストアンサー

やろうとしていることから察するに、テスト対象とテストが別プロジェクトになっているものと思います。

この場合、前提としてテスト対象のクラスや関数がエクスポートされている必要があります。
後述の手順で設定すればできますが、とにかく面倒臭いです。

VC++でのテストを学び始めるならば、まずは同一プロジェクト内にテストを入れてしまうことをお勧めします。
Visual Studio で C++ 用の Microsoft 単体テスト フレームワークを使用する
とりあえず、これの「同じプロジェクトで単体テストを作成するには」だけやってみればOKです。

別ソリューションでやりたい場合も、上記リンク先を参照してください。

##同一ソリューション・別プロジェクトでのテストをしたい場合

まずはクラスをエクスポート

VC++の場合、標準ではクラスや関数はEXEやDLLの外から参照することができません。参照できる(リンクできる)ようにするには明示的にエクスポートする必要があります。

クラスをエクスポートするには以下のようにします。(他の方法もあるけれど省略。興味があれば調べてみてください)
テスト対象のプロジェクトのヘッダ。※クラスを記述するヘッダとは別にしてください。framework.hやpch.hで良いです

C++

1#define MyDllExport1 __declspec( dllexport )

テストプロジェクトのヘッダ。こちらもpch.hに追記で良いでしょう。テスト対象側とよく似ていますが、dllexport と dllimport の部分が違いますので注意してください。

C++

1#define MyDllExport1 __declspec( dllimport )

MyDllExport1の部分は何でも良いのですが、プロジェクトごとにつけることになります

さらにテスト対象クラスのヘッダ(Sum.h)は以下のように修正(MyDllExport1を追加)します。

C++

1namespace TEST_SUM 2{ 3 class MyDllExport1 Sum 4 { 5// 中身は省略。通常通り書けば良い 6 }; 7}

プロジェクトの設定

これだけではまだリンクエラーは消えません。テストプロジェクトに参照設定をする必要があります。
0. 一度ビルドする(テストプロジェクトは失敗するけれど、テスト対象のプロジェクトはビルドできるはず)

  1. ソリューションエクスプローラーでテストプロジェクトを選択、Alt+Enterなどしてプロパティを開く
  2. 構成プロパティ ⇒ リンカー ⇒ 入力 とたどり、追加の依存ファイルの右端をクリックし、編集を選ぶ
  3. ビルドされたフォルダに出力されている、テスト対象プロジェクトの.libファイルを入力してOKをクリック

設定を自分で頑張って変更していなければ $(OutDir)\Stady_TEST2.lib で良いはず

ここまできたらビルドが成功すると思います。メニューのテストからテストエクスプローラーを起動してテストの実行をしてみましょう。

おまけ

テスト対象のクラス名に"TEST"はつけない方が良いです。非常にまぎらわしいです。
超どうでも良いですが、「学習」の意の英単語は study です。

投稿2021/08/04 14:35

ishina_yum

総合スコア509

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

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

MomenToufu

2021/08/05 00:53

回答ありがとうございます。いろいろと恥ずかしい所をお見せしたみたいで...。誤字やネーミングに関しては慎重に考えたいと思います。 経緯として、https://www.fenet.jp/dotnet/column/tool/2562/ を参考にC#で単体テストを行えたので、これのC++バージョンでいけるんではないかと思っていたところです。 同一ソリューション、別プロジェクトではDILLのインポートが必要になるとの事ご教授いただきありがとうございます。ご提案にある様に同一プロジェクトで実施し、今回のようなシチュエーションが必要になった場合に再度考えたいと思います。
guest

0

Sum.cpp がプロジェクトに含まれていないんじゃなかろーか、と。

投稿2021/08/04 09:23

episteme

総合スコア16612

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

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

MomenToufu

2021/08/05 00:44

回答ありがとうございます。プロジェクトの構成について確認してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問