Справка по настройке теста Google в VSCode

#c #visual-studio-code #cmake #googletest

#c #visual-studio-code #cmake #googletest

Вопрос:

Я не очень опытный программист и, когда я пишу код на своем компьютере, я использую Visual Studio. За несколько недель до этого я узнал о Visual Studio Code, и я был очень взволнован, и мне это очень понравилось. Однако, когда дело доходит до тестирования кода, у меня начинает болеть голова.

В Visual Studio я тестировал свой код с помощью Google Test, но я вижу, что в VSCode это намного сложнее, и я перепробовал все, каждый учебник, который я видел, чтобы использовать его. Не повезло, и каждый раз это происходит более или менее одинаково.

Например, допустим, я выполняю настройку в соответствии с руководством по googletest /README.md. Я создал решение с именем example, содержащее example.cpp , example.h и test.cpp , где мы находим модульные тесты.

example.h:

 #pragma once

int Add(int a, int b);
  

example.cpp:

 #include "example.h"

int Add(int a, int b) {
  return a   b;
}
  

test.cpp

 #include <gtest/gtest.h>
#include "example.h"

TEST(ExampleTest, AddTest)
{
    EXPECT_EQ(Add(2, 2), 4);
}
  

Затем я клонировал googletest, например, создал и открыл вставку с именем build и использовал $ cmake ../googletest в терминале. На данный момент пример выглядит так:

 example/
--build/
--googletest/
--example.cpp
--example.h
--test.cpp
  

Когда я пытаюсь запустить или отладить проект, терминал заканчивается кодом 1 и показывает ошибку fatal error C1083: Cannot open include file: 'gtest/gtest.h': No such file or directory , что странно, поскольку даже IntelliSense может обнаружить gtest.

Затем я попытался выполнить сборку с помощью CMake и создал CMakeLists.txt в примере и настроил его для запуска как исполняемый файл.

CMakeLists.txt:

 cmake_minimum_required(VERSION 3.0.0)
project(example VERSION 0.1.0)

include(CTest)
enable_testing()

add_executable(example test.cpp)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
  

Но затем CMake жалуется, говоря CMake Error: The source "C:/[...]/Projects/example/CMakeLists.txt" does not match the source "C:/[...]/Projects/example/googletest/CMakeLists.txt" used to generate cache. Re-run cmake with a different source directory.

Я прочитал почти все здесь, на Stack Overflow и на других сайтах, и ничего не помогло. Что я делаю не так?

Редактировать

Кроме того, вот tasks.json:

 {
  "tasks": [
    {
      "type": "shell",
      "label": "C/C  : cl.exe build active file",
      "command": "cl.exe",
      "args": [
        "/Zi",
        "/EHsc",
        "/Fe:",
        "${fileDirname}\${fileBasenameNoExtension}.exe",
        "${file}"
      ],
      "options": {
        "cwd": "${workspaceFolder}"
      },
      "problemMatcher": [
        "$msCompile"
      ],
      "group": {
        "kind": "build",
        "isDefault": true
      }
    }
  ],
  "version": "2.0.0"
}
  


Редактировать

Когда я использую /IC:/[...]/Projects/example/googletest/googletest/include и /link C:/[...]/Projects/example/example/build/Debug/example.lib C:/[...]/Projects/example/test.obj (я переместил example.cpp и example.h в файл с именем example, и я создал библиотеку через CMake), теперь я получаю это:

 /debug
/out:c:[...]Projectsexample/test.exe
C:/[...]/Projects/example/example/build/Debug/example.lib C:/[...]/Projects/example/test.obj 
test.obj 
test.obj : warning LNK4042: object specified more than once; extras ignored
LINK : warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library
test.obj : error LNK2019: unresolved external symbol "bool __cdecl testing::internal::IsTrue(bool)" (?IsTrue@internal@testing@@YA_N_N@Z) referenced in function "public: static void (__cdecl*__cdecl testing::internal::SuiteApiResolver<class testing::Test>::GetSetUpCaseOrSuite(char const *,int))(void)" (?GetSetUpCaseOrSuite@?$SuiteApiResolver@VTest@testing@@@internal@testing@@SAP6AXXZPEBDH@Z)
test.obj : error LNK2019: unresolved external symbol "public: __cdecl testing::internal::GTestLog::GTestLog(enum testing::internal::GTestLogSeverity,char const *,int)" (??0GTestLog@internal@testing@@QEAA@W4GTestLogSeverity@12@PEBDH@Z) referenced in function "public: static void (__cdecl*__cdecl testing::internal::SuiteApiResolver<class testing::Test>::GetSetUpCaseOrSuite(char const *,int))(void)" (?GetSetUpCaseOrSuite@?$SuiteApiResolver@VTest@testing@@@internal@testing@@SAP6AXXZPEBDH@Z)
test.obj : error LNK2019: unresolved external symbol "public: __cdecl testing::internal::GTestLog::~GTestLog(void)" (??1GTestLog@internal@testing@@QEAA@XZ) referenced in function "public: static void (__cdecl*__cdecl testing::internal::SuiteApiResolver<class testing::Test>::GetSetUpCaseOrSuite(char const *,int))(void)" (?GetSetUpCaseOrSuite@?$SuiteApiResolver@VTest@testing@@@internal@testing@@SAP6AXXZPEBDH@Z)
test.obj : error LNK2019: unresolved external symbol "public: __cdecl testing::Message::Message(void)" (??0Message@testing@@QEAA@XZ) referenced in function "private: virtual void __cdecl ExampleTest_AddTest_Test::TestBody(void)" (?TestBody@ExampleTest_AddTest_Test@@EEAAXXZ)
test.obj : error LNK2019: unresolved external symbol "class testing::AssertionResult __cdecl testing::internal::EqFailure(char const *,char const *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const amp;,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const amp;,bool)" (?EqFailure@internal@testing@@YA?AVAssertionResult@2@PEBD0AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@1_N@Z) referenced in function "class testing::AssertionResult __cdecl testing::internal::CmpHelperEQFailure<int,int>(char const *,char const *,int const amp;,int const amp;)" (??$CmpHelperEQFailure@HH@internal@testing@@YA?AVAssertionResult@1@PEBD0AEBH1@Z)
test.obj : error LNK2019: unresolved external symbol "void const * __cdecl testing::internal::GetTestTypeId(void)" (?GetTestTypeId@internal@testing@@YAPEBXXZ) referenced in function "void __cdecl `dynamic initializer for 'private: static class testing::TestInfo * ExampleTest_AddTest_Test::test_info_''(void)" (??__E?test_info_@ExampleTest_AddTest_Test@@0QEAVTestInfo@testing@@EA@@YAXXZ)
test.obj : error LNK2019: unresolved external symbol "class testing::TestInfo * __cdecl testing::internal::MakeAndRegisterTestInfo(char const 
*,char const *,char const *,char const *,struct testing::internal::CodeLocation,void const *,void (__cdecl*)(void),void (__cdecl*)(void),class testing::internal::TestFactoryBase *)" (?MakeAndRegisterTestInfo@internal@testing@@YAPEAVTestInfo@2@PEBD000UCodeLocation@12@PEBXP6AXXZ3PEAVTestFactoryBase@12@@Z) referenced in function "void __cdecl `dynamic initializer for 'private: static class testing::TestInfo * ExampleTest_AddTest_Test::test_info_''(void)" (??__E?test_info_@ExampleTest_AddTest_Test@@0QEAVTestInfo@testing@@EA@@YAXXZ)
test.obj : error LNK2019: unresolved external symbol "class testing::AssertionResult __cdecl testing::AssertionSuccess(void)" (?AssertionSuccess@testing@@YA?AVAssertionResult@1@XZ) referenced in function "class testing::AssertionResult __cdecl testing::internal::CmpHelperEQ<int,int>(char const *,char const *,int const amp;,int const amp;)" (??$CmpHelperEQ@HH@internal@testing@@YA?AVAssertionResult@1@PEBD0AEBH1@Z)
test.obj : error LNK2019: unresolved external symbol "public: virtual __cdecl testing::Test::~Test(void)" (??1Test@testing@@UEAA@XZ) referenced in function "public: virtual __cdecl ExampleTest_AddTest_Test::~ExampleTest_AddTest_Test(void)" (??1ExampleTest_AddTest_Test@@UEAA@XZ)
test.obj : error LNK2019: unresolved external symbol "protected: __cdecl testing::Test::Test(void)" (??0Test@testing@@IEAA@XZ) referenced in function "public: __cdecl ExampleTest_AddTest_Test::ExampleTest_AddTest_Test(void)" (??0ExampleTest_AddTest_Test@@QEAA@XZ)
test.obj : error LNK2001: unresolved external symbol "protected: virtual void __cdecl testing::Test::SetUp(void)" (?SetUp@Test@testing@@MEAAXXZ)
test.obj : error LNK2001: unresolved external symbol "protected: virtual void __cdecl testing::Test::TearDown(void)" (?TearDown@Test@testing@@MEAAXXZ)
test.obj : error LNK2019: unresolved external symbol "public: __cdecl testing::internal::AssertHelper::AssertHelper(enum testing::TestPartResult::Type,char const *,int,char const *)" (??0AssertHelper@internal@testing@@QEAA@W4Type@TestPartResult@2@PEBDH1@Z) referenced in function "private: virtual void __cdecl ExampleTest_AddTest_Test::TestBody(void)" (?TestBody@ExampleTest_AddTest_Test@@EEAAXXZ)
test.obj : error LNK2019: unresolved external symbol "public: __cdecl testing::internal::AssertHelper::~AssertHelper(void)" (??1AssertHelper@internal@testing@@QEAA@XZ) referenced in function "private: virtual void __cdecl ExampleTest_AddTest_Test::TestBody(void)" (?TestBody@ExampleTest_AddTest_Test@@EEAAXXZ)
test.obj : error LNK2019: unresolved external symbol "public: void __cdecl testing::internal::AssertHelper::operator=(class testing::Message const amp;)const " (??4AssertHelper@internal@testing@@QEBAXAEBVMessage@2@@Z) referenced in function "private: virtual void __cdecl ExampleTest_AddTest_Test::TestBody(void)" (?TestBody@ExampleTest_AddTest_Test@@EEAAXXZ)
c:[...]Projectsexampletest.exe : fatal error LNK1120: 15 unresolved externals
The terminal process "C:windowsSystem32WindowsPowerShellv1.0powershell.exe -Command cl.exe /Zi /EHsc /Fe: c:[...]Projectsexample/test.exe c:[...]Projectsexampletest.cpp /IC:/[...]/Projects/example/googletest/googletest/include '/link C:/[...]/Projects/example/example/build/Debug/example.lib C:/[...]/Projects/example/test.obj'" terminated with exit code: 1.
  

Комментарии:

1. Насколько хорошо вы разбираетесь в CMake?

2. Можете ли вы также опубликовать задачи. json, который был сгенерирован из VS Code?

3. Я не очень хорошо знаю CMake, но я знаю пару вещей.

4. Вам нужен /I<путь к gtest-include> в аргументах.

5. В Visual Studio свойства показывают вывод командной строки. Вы можете просмотреть это и проверить, что нужно добавить в задачи. json -> атрибут args

Ответ №1:

Я понял, как решить проблему. Короче говоря, я использовал CMake для включения Google Test в проект.

Во-первых, я переместил example.cpp и example.h в новую папку с именем example и создал CMakeLists.txt для компиляции в виде библиотеки.

example/CMakeLists.txt:

 add_library(example_lib example.cpp example.h)
  

Затем я изменил CMakeLists.txt в корне этого:

 cmake_minimum_required(VERSION 3.18.2) # Set your version.
# If you don't, wou'll get a LNK1169 error and many others (don't know why)

project(example)

include(CTest)
enable_testing()

add_executable(example test.cpp)

add_subdirectory(googletest)
add_subdirectory(example)

target_link_libraries(example PUBLIC example_lib gtest gtest_main gmock gmock_main)

include(GoogleTest) # To use gtest_discover_tests

gtest_discover_tests(example) # Runs GTest with CTest

  

И теперь вы настраиваете, собираете и запускаете! 🙂

Комментарии:

1. Я также хочу поблагодарить @user3389943. Он / Она мне очень помог, и без него / нее я бы уже сдался.