3

Visual Studio で Catch2 単体テストを実行しようとしています。練習用に小さなテスト プロジェクトを作成しました。このテスト プロジェクトをコンパイルしようとすると、リンカー エラーが発生します。現在、このリンカー エラーを診断しようとしていますが、Catch2.hppヘッダー ファイルには数千行のコードが含まれています。私の願いは、Catch2 や単体テスト全般に詳しい人が問題を診断できることです。

このプロジェクトを作成したプロセスについて説明します。新しいソリューションで新しいプロジェクトを作成しました。以下にリストされている4つのファイルがすべて同じディレクトリにあります。

テストしたいクラス:

//a.h

#pragma once

class A {
    friend int A_Tester_Func1(A a);
public:
    A(int num) : my_num_(num) {
    }
private:
    int my_num_;
};

テスト:

//atester.cpp

#pragma once

#include "catch.hpp"
#include "a.h"

int A_Tester_Func1(A a) {
    return a.my_num_;
}

TEST_CASE("a contains a positive integer", "[a]") {
    //...
    A a(3);
    REQUIRE(A_Tester_Func1(a) == 3);

}

テストを実行する主な機能:

//tester.cpp

#define CATCH_CONFIG_MAIN
#include "catch.hpp" // this should create the main function

Catch2 テスト フレームワーク:

// catch.hpp

/*
 *  Catch v2.13.2
 *  Generated: 2020-10-07 11:32:53.302017
*/

//~17-18k lines of code that from Catch2

#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED

[ローカル Windows デバッガー] ボタンを使用して Visual Studio でこのコードをコンパイルしようとすると、多数の未解決の外部シンボル リンカー エラーが発生します。Catch2 が「部分的にコンパイルされている」ことをどこかで読んだと思います。それと何か関係があるのか​​もしれませんが、私にはわかりません。このガイド ( StackOverflow: Visual Studio で Catch2 を使用した単体テストのベスト プラクティス) に従うことでうまくいきましたが、上記の小さな例が正常にリンクされない理由を理解しようとしています。

完全を期すために以下のリンカーエラーを含めましたが、おそらく質問には必要ないと思います。

1>atester.obj : error LNK2019: unresolved external symbol "public: __thiscall Catch::StringRef::StringRef(char const *)" (??0StringRef@Catch@@QAE@PBD@Z) referenced in function "public: class Catch::BinaryExpr<int const &,int const &> const __thiscall Catch::ExprLhs<int const &>::operator==<int>(int const &)" (??$?8H@?$ExprLhs@ABH@Catch@@QAE?BV?$BinaryExpr@ABHABH@1@ABH@Z)
1>atester.obj : error LNK2019: unresolved external symbol "struct Catch::ITestInvoker * __cdecl Catch::makeTestInvoker(void (__cdecl*)(void))" (?makeTestInvoker@Catch@@YAPAUITestInvoker@1@P6AXXZ@Z) referenced in function "void __cdecl `anonymous namespace'::`dynamic initializer for 'autoRegistrar1''(void)" (??__EautoRegistrar1@?A0xf9ca9c7d@@YAXXZ)
1>atester.obj : error LNK2019: unresolved external symbol "public: __thiscall Catch::NameAndTags::NameAndTags(class Catch::StringRef const &,class Catch::StringRef const &)" (??0NameAndTags@Catch@@QAE@ABVStringRef@1@0@Z) referenced in function "void __cdecl `anonymous namespace'::`dynamic initializer for 'autoRegistrar1''(void)" (??__EautoRegistrar1@?A0xf9ca9c7d@@YAXXZ)
1>atester.obj : error LNK2019: unresolved external symbol "public: __thiscall Catch::AutoReg::AutoReg(struct Catch::ITestInvoker *,struct Catch::SourceLineInfo const &,class Catch::StringRef const &,struct Catch::NameAndTags const &)" (??0AutoReg@Catch@@QAE@PAUITestInvoker@1@ABUSourceLineInfo@1@ABVStringRef@1@ABUNameAndTags@1@@Z) referenced in function "void __cdecl `anonymous namespace'::`dynamic initializer for 'autoRegistrar1''(void)" (??__EautoRegistrar1@?A0xf9ca9c7d@@YAXXZ)
1>atester.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall Catch::AutoReg::~AutoReg(void)" (??1AutoReg@Catch@@UAE@XZ) referenced in function "void __cdecl `anonymous namespace'::`dynamic atexit destructor for 'autoRegistrar1''(void)" (??__FautoRegistrar1@?A0xf9ca9c7d@@YAXXZ)
1>atester.obj : error LNK2019: unresolved external symbol "public: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl Catch::StringMaker<int,void>::convert(int)" (?convert@?$StringMaker@HX@Catch@@SA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@Z) referenced in function "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl Catch::Detail::stringify<int>(int const &)" (??$stringify@H@Detail@Catch@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABH@Z)
1>atester.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall Catch::ITransientExpression::~ITransientExpression(void)" (??1ITransientExpression@Catch@@UAE@XZ) referenced in function "public: virtual __thiscall Catch::BinaryExpr<int const &,int const &>::~BinaryExpr<int const &,int const &>(void)" (??1?$BinaryExpr@ABHABH@Catch@@UAE@XZ)
1>atester.obj : error LNK2019: unresolved external symbol "void __cdecl Catch::formatReconstructedExpression(class std::basic_ostream<char,struct std::char_traits<char> > &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class Catch::StringRef,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?formatReconstructedExpression@Catch@@YAXAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@3@VStringRef@1@1@Z) referenced in function "private: virtual void __thiscall Catch::BinaryExpr<int const &,int const &>::streamReconstructedExpression(class std::basic_ostream<char,struct std::char_traits<char> > &)const " (?streamReconstructedExpression@?$BinaryExpr@ABHABH@Catch@@EBEXAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@@Z)
1>atester.obj : error LNK2019: unresolved external symbol "public: __thiscall Catch::AssertionHandler::AssertionHandler(class Catch::StringRef const &,struct Catch::SourceLineInfo const &,class Catch::StringRef,enum Catch::ResultDisposition::Flags)" (??0AssertionHandler@Catch@@QAE@ABVStringRef@1@ABUSourceLineInfo@1@V21@W4Flags@ResultDisposition@1@@Z) referenced in function "void __cdecl ____C_A_T_C_H____T_E_S_T____0(void)" (?____C_A_T_C_H____T_E_S_T____0@@YAXXZ)
1>atester.obj : error LNK2019: unresolved external symbol "public: void __thiscall Catch::AssertionHandler::handleExpr(struct Catch::ITransientExpression const &)" (?handleExpr@AssertionHandler@Catch@@QAEXABUITransientExpression@2@@Z) referenced in function "void __cdecl ____C_A_T_C_H____T_E_S_T____0(void)" (?____C_A_T_C_H____T_E_S_T____0@@YAXXZ)
1>atester.obj : error LNK2019: unresolved external symbol "public: void __thiscall Catch::AssertionHandler::handleUnexpectedInflightException(void)" (?handleUnexpectedInflightException@AssertionHandler@Catch@@QAEXXZ) referenced in function __catch$?____C_A_T_C_H____T_E_S_T____0@@YAXXZ$0
1>atester.obj : error LNK2019: unresolved external symbol "public: void __thiscall Catch::AssertionHandler::complete(void)" (?complete@AssertionHandler@Catch@@QAEXXZ) referenced in function __catch$?____C_A_T_C_H____T_E_S_T____0@@YAXXZ$0
1>MSVCRTD.lib(exe_main.obj) : error LNK2019: unresolved external symbol _main referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ)

これらのエラーの原因は何ですか? catch.hppソース ファイルと同じプロジェクトを維持しながら、これらのエラーを修正するにはどうすればよいですか?

4

3 に答える 3