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

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

新規登録して質問してみよう
ただいま回答率
85.50%
テスト駆動開発

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

C++

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

Q&A

解決済

3回答

13681閲覧

Visual StudioでGoogle Testが実行できない

AloneLeisure

総合スコア13

テスト駆動開発

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

C++

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

2グッド

0クリップ

投稿2017/12/29 12:00

編集2017/12/29 16:01

###前提・実現したいこと
テスト駆動開発を勉強しようと思い、Visual StudioでGoogle Testを使用しようとしましたが、実行できません。
インクルードディレクトリ、スタティックリンクライブラリの設定は行っており、コンパイルまでは通っています。
以下のリンクエラーが発生したまま、足踏みが続いている状況です。

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

エラー LNK2019 未解決の外部シンボル _main が関数 "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) で参照されました。 TestDrivenDevelopmentChapter1 c:\Users***\documents\visual studio 2017\Projects\TestDrivenDevelopmentChapter1\TestDrivenDevelopmentChapter1\MSVCRTD.lib(exe_main.obj) 1

###該当のソースコード
「テスト駆動開発」の6ページまでのコードをC++に落とし込んだものになります。

MoneyTest.cpp(testTestDrivenDevelopmentChapter1プロジェクト内)

C++

1#include <gtest/gtest.h> 2 3#include <Dollar.h> 4 5TEST(MoneyTest, Multiplication) { 6 Dollar five(5); 7 five.times(2); 8 EXPECT_EQ(10, five.amount); 9}

Dollar.h(TestDrivenDevelopmentChapter1プロジェクト内)

C++

1#pragma once 2class Dollar 3{ 4public: 5 Dollar(int amount); 6 ~Dollar(); 7 8 void times(int multiplier); 9 10 int amount; 11}; 12

Dollar.cpp(TestDrivenDevelopmentChapter1プロジェクト内)

C++

1#include "Dollar.h" 2 3Dollar::Dollar(int amount) 4{ 5} 6 7Dollar::~Dollar() 8{ 9} 10 11 12 13void Dollar::times(int multiplier) 14{ 15}

###試したこと
エラーメッセージから推測するには、エントリポイントが見つからないのだと思います。
そこで、以下を試しました。

・MoneyTest.cppにInitGoogleTest()、RUN_ALL_TEST()を記述したmain関数を書く
→状況変わらず

・Dollar.cppに空のmain関数を書く
→当然ながら何もしないmain関数が実行されて終了する(テスト結果は表示されず)

・Dollar.cppにInitGoogleTest()、RUN_ALL_TEST()を記述したmain関数を書く
→InitGoogleTest()、RUN_ALL_TEST()の定義が見つからないコンパイルエラーが出る

###補足情報(言語/FW/ツール等のバージョンなど)
言語:C++
開発環境:Visual Studio Community 2017
テストフレームワーク:Google Test 1.7.0

eien_beginner, LouiS0616👍を押しています

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

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

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

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

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

guest

回答3

0

自己解決

自己解決しました。
結論から言えば、プロジェクト本体とテストプロジェクトを分けず、同一のプロジェクトで扱う必要があったようです。
以下、TestDrivenDevelopmentChapter1(Dollar側)を「テストされる側のプロジェクト」、
testTestDrivenDevelopmentChapter1(MoneyTest側)を「テストする側のプロジェクト」と呼称し、
その後の経過を述べていこうと思います。

件のリンクエラーについて

これについては、やはりmain関数が見つからないことが原因のようでした。
ただし、テストする側のプロジェクトではなく、テストされる側のmain関数だったようです。
そのためにDollar.cppにmain関数を書いた時にはリンクも通り実行できたのでしょう。

ただしGoogle Testの実行という目的は達せられないため、プロジェクトの実行順序を変更する必要がありました。
ソリューションのプロパティから[共通プロパティ]-[スタートアッププロジェクト]に移動し、
[シングルスタートアッププロジェクト]をテストする側のプロジェクトにする必要があったようです(ソリューション名と同一なため、デフォルトではテストされる側のプロジェクトになっていました)。
その後、今度は他のリンクエラーが出る形になりました。

###スタートアッププロジェクト変更後の各種リンクエラー
まず、大量の(私の環境では508もの)LNK2005エラーが出力されました。
これについては検索すれば即座に解決しました。コード生成のランタイムライブラリをMTdにし、
リンクするスタティックリンクライブラリをDebugモードのものにして解決しました。

今度はDollarのコンストラクタ、デストラクタ、およびtimes関数について、LNK2019エラーが出力されました。
どうやらテストされる側のファイルとテストする側のファイルが同じプロジェクトに存在する必要があるようです。
ですので、epistemeさんのアドバイスに従い、テストする側のプロジェクトに
Dollar.hおよびDollar.cppを追加し、ようやくテストの結果が表示されました。

###テストする側のプロジェクト削除
ただ、こうしなくてはいけないのではテストする側のプロジェクトが存在する意味がありません。
テストする側のプロジェクトを削除し、テストされる側のプロジェクトにMoneyTest.cppを追加、
そしてテストする側に行っていた各種インクルード・リンク設定をテストされる側のプロジェクトに行いました。
その際、epistemeさんのアドバイスのように . にインクルードパスを通す必要があるようです(MoneyTest.cppはテストする側のプロジェクトディレクトリ内にあるので)。
この構成にすれば、テストされる側のmain関数はそもそも問題にならなくなります(epistemeさんの構成はおそらくこの形なのだと思います)。

結局、冒頭にも述べたように、プロジェクト本体とテストプロジェクトを分けてはいけないというのが今回の問題の本質だったようです。
検索した限りでは両者を各個プロジェクトに分離している構成が多く見られるのですが、この点、腑に落ちないところです。

ともあれ、真摯に対応してくださったepistemeさん、hmmmさん、誠にありがとうございました。

投稿2017/12/30 00:43

編集2017/12/30 00:55
AloneLeisure

総合スコア13

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

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

hmmm

2017/12/30 04:17

私は例えば、最終製品のEXE(中身はほぼなしでLIBのコードを実行する),最終製品のEXEにリンクするLIB(ここに製品に必要な処理がはいる)、テスト用のEXEと3つのプロジェクトにしてます。テスト用のEXEのプロジェクトは製品用のLIBが使えるようにインクルードなども設定し、製品用のLIBをリンクさせて製品用の処理のテストを実行しています。
AloneLeisure

2017/12/30 06:36

ご助言ありがとうございます。大変参考になります。 現在の目的はGoogle Testを使ってC++でのテスト駆動開発を勉強することでしたので、当面は現在の1プロジェクト構成で進めてみようと思います。 ただ、現在の構成ではソリューション・プロジェクトが大きくなった時に限界が来るだろうことも感じているので、 その際にはhmmmさんのアドバイスが役に立ちそうです。
guest

0

gtest-packageのgoogletest/src にある gtest-all.cc と gtest_main.cc をプロジェクトに追加して一緒にコンパイル/リンクするだけなんぢゃがの。

  • console-application でプロジェクト作成
  • googletest-release-1.7.0/include と googletest-release-1.7.0/src そして . にinclude-pathを通す
  • プロジェクトに googletest-release-1.7.0/src/gtest_main.cc および gtest-all.cc を追加する
  • テストおよびテスト対象(~.h,~.cpp)を追加

これだけでできたです。

投稿2017/12/29 13:12

編集2017/12/29 14:23
episteme

総合スコア16614

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

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

AloneLeisure

2017/12/29 13:43

ご回答ありがとうございます。 折角頂いた回答に更に質問するのは恐縮なのですが、その2ファイルをどう追加するのでしょうか。 テスト側のプロジェクトに当該2ファイルを追加しましたが、やはり同様のエラーが出ます。 当該2ファイルを含んでいるgtest.vcxprojおよびgtest_main.vcxprojをソリューションに追加し、テスト側のプロジェクトが2プロジェクトを参照するようにして実行しても、結果は同様。 さらに、上記2つを組み合わせても同じ結果でした。 私が未熟なのは重々承知していますが、gtest-all.ccおよびgtest-main.ccの追加方法をご教授くださると助かります。
episteme

2017/12/29 14:02

プロジェクトまるごと差し上げます。twitter:@epitwit にメッセージください。
AloneLeisure

2017/12/29 14:15

失礼を承知で申し上げます。 このサイトは私だけでなく、後に他の初心者の方も解決方法を求めて来訪する場所です。 裏口でファイルのやり取りをして「解決しました」ではその用をなしません。 言葉での回答をお願いします。
episteme

2017/12/29 14:23

加筆しといた。
AloneLeisure

2017/12/29 14:51

度々ありがとうございます。 ただ、残念ながら未だ成功していません。 srcへのインクルードパスが通っていなかったのはご指摘により修正しましたが、結果は質問時と変わりません。
episteme

2017/12/29 14:55 編集

僕とこでは一発OKでした。 main()はgtest_main.ccで実装されているので"mainが見つからん"はずがないのです。 お役に立てず申し訳ない。
guest

0

「テスト駆動開発」の6ページまでのコードをC++に落とし込んだものになります。

この本にはmain関数の記載はなかったんでしょうか?

・MoneyTest.cppにInitGoogleTest()、RUN_ALL_TEST()を記述したmain関数を書く
→状況変わらず

これでできるような気がしますが、Main.cppと別ファイルに分けてみてはどうですか?

Main.cpp

c++

1#include <gtest/gtest.h> 2 3int main(int argc, char **argv) { 4 ::testing::InitGoogleTest(&argc, argv); 5 return RUN_ALL_TESTS(); 6}

投稿2017/12/29 12:52

hmmm

総合スコア818

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

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

AloneLeisure

2017/12/29 13:55 編集

ご回答ありがとうございます。 当該書籍ではJava、JUnit、Eclipse環境での解説となっています。 それをC++、Google Test、Visual Studio環境でやりたいというのは完全に私のわがままになります。 ともかくこうした背景事情にあるので書籍に環境構築面を期待することはできません。 頂いたアドバイス通り、テスト側のプロジェクトでMain.cppを作成しましたが、状況は変わりませんでした。
hmmm

2017/12/29 16:03 編集

エラー内容のexe_main.objというのはVCランタイム内のコードで、この中でmainを実行しています。AloneLeisureさんが推測している通りmainを含んだobjが足りずリンクできないだけのはずです。回答に記載の内容でリンクできないのであれば、ソースコードの問題ではなくプロジェクトファイルなどに問題があるのでしょう。ソリューション内のファイルを一式githubなどにアップすることをお勧めします。
AloneLeisure

2017/12/30 00:48

度々ありがとうございます。 自己解決にも記述しましたが、おっしゃる通り、プロジェクトやソリューションの構成の問題が大きかったようです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問