2017-03-10 33 views
2

我想在本地(C++)gradle項目中集成單元測試,但我似乎無法找到工作解決方案。鏈接測試可執行文件時發生問題,因爲有兩個可用的域(一個用於主應用程序,一個用於單元測試)。有誰知道如何在鏈接步驟中排除其中的一個?如何排除第二個主要鏈接測試EXE與gradle?

這是我設置的一個小例子:

項目結構

build.gradle 
src 
    -> main 
     -> cpp 
      -> main.cpp 
      -> registry.cpp 
     -> headers 
      -> registry.hpp 
    -> test 
     -> cpp 
      -> main_test.cpp 
      -> test_registry.cpp 
libs 
    -> googletest 
     -> 1.7.0 
      -> include 
       -> ... 
      -> lib 
       -> libgtest.a 

的build.gradle

apply plugin: 'cpp' 
apply plugin: 'google-test-test-suite' 

model { 
    platforms { 
     x86 { 
      architecture "x86" 
     } 
     x64 { 
      architecture "x86_64" 
     } 
    } 

    components { 
     main(NativeExecutableSpec) { 
      baseName "Registry" 
      targetPlatform "x86" 
      binaries.all { 
       cppCompiler.args "-std=c++11", "-municode", "-mwindows" 
       linker.args "-municode", "-mwindows" 
      } 
     } 
    } 

    testSuites { 
     mainTest(GoogleTestTestSuiteSpec) { 
      testing $.components.main 

      sources { 
       cpp.source.srcDir 'src/test/cpp' 
      } 
     } 
    } 

    repositories { 
     libs(PrebuiltLibraries) { 
      googleTest { 
       headers.srcDir "libs/googletest/1.7.0/include" 
       binaries.withType(StaticLibraryBinary) { 
        staticLibraryFile = 
         file("libs/googletest/1.7.0/lib/libgtest.a") 
       } 
      } 
     } 
    } 
} 

model { 
    binaries { 
     withType(GoogleTestTestSuiteBinarySpec) { 
      lib library: "googleTest", linkage: "static" 

      cppCompiler.args "-std=c++11", "-municode" 
      linker.args "-municode" 
     } 
    } 
} 

錯誤消息

:compileMainExecutableMainCpp 
:linkMainExecutable 
:mainExecutable 
:assemble 
:compileMainTestGoogleTestExeMainCpp 
:compileMainTestGoogleTestExeMainTestCpp 
:linkMainTestGoogleTestExe 
C:\Users\minimal\build\objs\mainTest\mainCpp\e7f4uxujatdodel7e7qw5uhsp\main.obj:main.cpp:(.text+0x0): multiple definition of `wmain' 
C:\Users\minimal\build\objs\mainTest\mainTestCpp\271ezc0ay5ubap2l962cnectq\main_test.obj:main_test.cpp:(.text+0x0): first defined here 
collect2.exe: error: ld returned 1 exit status 

:linkMainTestGoogleTestExe FAILED 

FAILURE: Build failed with an exception. 

* What went wrong: 
Execution failed for task ':linkMainTestGoogleTestExe'. 
> A build operation failed. 
     Linker failed while linking mainTest.exe. 

options.txt

-o 
C:\\Users\\minimal\\build\\exe\\mainTest\\mainTest.exe 
C:\\Users\\minimal\\build\\objs\\mainTest\\mainTestCpp\\271ezc0ay5ubap2l962cnectq\\main_test.obj 
C:\\Users\\minimal\\build\\objs\\mainTest\\mainTestCpp\\dp6ieaohq04qqqa31sdfwrsxj\\test_registry.obj 
C:\\Users\\minimal\\build\\objs\\mainTest\\mainCpp\\68sxcjmhakj69ha7wqtijofs3\\Registry.obj 
C:\\Users\\minimal\\build\\objs\\mainTest\\mainCpp\\e7f4uxujatdodel7e7qw5uhsp\\main.obj 
C:\\Users\\minimal\\libs\\googletest\`.7.0\\lib\\libgtest.a 
-municode 
-m32 

任何幫助,不勝感激!

回答

2

你的問題來自試圖用googletest做錯誤的事情。

Googletest是一個單元測試框架。這意味着它是檢驗 - 在這裏指一堆不包括main功能功能和/或類 。它不適用於具有main功能的測試應用程序 。您通過運行 應用程序並對其明顯行爲進行控制(可能是自動的)觀察 來測試應用程序。這種測試有不同的名稱,但是是 而不是單元測試,單元測試是第一位的。

要用googletest測試一個庫,你需要創建一個應用程序到 運行你的googletest測試用例。該應用程序,測試亞軍,需要 自己的main功能,什麼也不做,但運行測試用例:

​​

這是足夠常見有人有一個包含 一堆專用功能的應用程序和/或他們想要用googletest進行單元測試的類別 。做到這一點的方法是: -

  • 重構應用到:

    • 庫 - 稱之爲應用程序庫 - 包含您需要的功能和/或類 單元 - 測試,不包括main函數。
    • 其餘部分包括main函數。
  • 通過將剩餘部分與應用程序庫鏈接來構建應用程序。

  • 創建一個測試運行器應用程序,包括您的googletest測試用例 和googletest main函數。當然,測試用例,應用程序庫的標題。

  • 通過將測試用例和主函數鏈接到應用程序庫來構建測試運行器。

  • 通過運行測試運行器對應用程序庫進行單元測試。

這個最簡單最快捷的辦法就是把所有的應用程序, 除了main功能,爲應用程序庫。但它可能更聰明 將東西從應用程序移動到應用程序庫只有當你開發 單元測試覆蓋它,所以你隨時知道,無論是在應用程序庫 有單元測試,其餘不'噸。以這種方式繼續,除非 main函數位於應用程序庫中,並且具有單元測試。

你幾乎肯定會發現,分解出的應用程序庫 這樣您就可以與應用程序和測試運行都將其鏈接的過程中暴露在應用 設計上的缺陷,並強迫你做的更好。這可以啓動一個 應用程序庫,以便逐漸成熟爲一個多應用程序庫,一個穩定的高品質 軟件資產。

所以,你開始一個項目,應用項目,你最終 三個項目:

  • 是構建應用程序庫
  • 是構建應用程序
  • 一個一個項目一個項目建立測試跑步者的項目

這樣或那樣的任何構建系統,您將允許您自動創建 這些項目之間的依賴關係。顯然,你想:

  • 建設需要構建應用程序庫
  • 構建測試亞軍,要求建造的應用libary

應用程序,但你可以走的更遠,並建設應用程序需要 構建測試運行器 - 它將構建應用程序庫 - 併成功運行測試運行器的 。這樣,除非單元測試成功,否則您不會構建應用程序 。這可能是對你的 桌面開發週期矯枉過正,但不是CI構建。

在接下來的應用程序,你可以開始這個3項目的模式, 並只有當你可以從 應用程序庫,必須由單元測試覆蓋得到它,它必須在應用程序中添加功能在測試跑步者中通過 。然後你用正確的方式使用googletest。

+0

謝謝你的廣泛答案。我通常熟悉單元測試(不是在C/C++上下文中),並且已經將代碼明確地設置了測試用例。然而,我並不知道對項目結構施加的隱含限制。因爲它是一個非常小的應用程序,所以我選擇了所描述的快速/簡單方法(根項目只包含主項目,而庫項目包含「API」及其相應的單元測試。 – lazlev