[英]How to test an EXE with Google Test?
我在 Visual Studio 中有一個 C++ 項目,並添加了另一個專用於測試的項目。 這兩個項目都是 EXE(控制台應用程序)。 那么如何在第二個項目中使用第一個項目呢?
只是為了澄清,如果第一個項目是一個可以簡單地包含在第二個項目中的庫,那么這里的問題將是不言而喻的,但是作為一個 EXE,這就是問題所在。
根據您的評論,您有一個 C++ 控制台應用程序 ( MyApp)
,您已經為其開發了一些特定於應用程序的類,您希望在 Visual Studio 中使用 googletest 對這些類進行單元測試。 如何?
正如你所說,如果你想對一個庫進行單元測試,這樣做的方法是顯而易見的。 你會:
UnitTest
)。UnitTest
項目依賴於庫項目,以便構建UnitTest
確保MyApp
是最新的。UnitTest
應用程序。 但是由於您要進行單元測試的類是特定於MyApp
,因此您沒有任何庫。
對此的回答是:您沒有包含要進行單元測試的類的庫? 所以做一個!
這樣你就可以使用 3 個項目:-
MyAppLib
,生成包含要進行單元測試的所有功能的庫。MyApp
,生成與當前相同的可執行文件,但鏈接MyAppLib
UnitTest
,生成對MyAppLib
單元測試的可執行文件,也鏈接MyAppLib
但是,如果您不喜歡演習中士的回答,您可以解決它。
從通常的構建系統的角度(設計到 Visual Studio 的角度來看), MyApp
項目的重要輸出是構建目標 - .exe
。 生成的.obj
文件只是中間的副產品。 VS 不支持將這些副產品視為依賴項目的自動鏈接器輸入,並且如果依賴項目也是同類的.exe
- 就像你的情況一樣 - 那么這種自動鏈接無論如何都是不可能的,因為主要入口點將被多重定義。
但從單元測試的角度來看,情況正好相反。 .exe
,而(某些) .obj
文件全部或部分包含您要進行單元測試的類的實現。 在類foo
在foo.h
定義並在foo.cpp
實現的foo.cpp
, UnitTest
的鏈接中需要目標文件foo.obj
。
為簡單起見,假設MyApp
僅使用一個特定於應用程序的類foo
,在foo.h
定義並在foo.cpp
實現。 然后您有兩種構建UnitTest
選項。
a) 您可以將foo.cpp
添加到UnitTest
的源文件中。 當然不要復制。 只需從MyApp
的源文件夾中添加一個現有項目。 然后你就完成了,但是這門課程的缺點是foo.cpp
在UnitTest
項目中會受到不利的編輯。
b) 您可以將foo.obj
鏈接UnitTest
所需的靜態庫,並按照上面的步驟 1) - 6) 進行操作。 這尤其意味着在步驟 3) 中, UnitTest
的 {Debug|Release} 構建配置了包含\\path\\to\\MyApp\\{Debug|Release}
(相對或絕對形式)的庫搜索目錄。
實際上,對於選項 b),很可能有多個來自MyApp
.obj
文件必須在UnitTest
鏈接,並且它們的數量很可能會隨着時間的推移而增加。 維護UnitTest
的正確鏈接可能會成為一件苦差事,您可能會得出結論,畢竟演習中士是對的。
要看。 Google Test(主要)是一個單元測試框架(過度簡化,測試類)。 您絕對可以將 is 用於其他類型的測試,但它沒有用於其他類型測試的“內置”功能,您必須自己編寫。
如果您嘗試系統測試您的可執行文件,則可以運行該過程。 如果您使用的是多平台系統或已經有 boost 依賴,我建議使用 Boost.Process。 否則,請看這里: 使用 stdin stdout 和 stderr 啟動 exe/進程?
您編寫的“測試”將調用可執行文件,並可以相應地輸入標准輸入或標准輸出。
例如:
std::string path_to_exectuable = "thepath";
TEST(FooTester,CheckHelpScriptReturns0)
{
using bp =::boost::process;
std::vector<std::string> args; args.push_back("--help");
bp::context ctx;
ctx.stdout_behavior = bp::capture_stream();
bp::child c = bp::launch(exec, args, ctx);
bp::status s = c.wait();
ASSERT_TRUE(s.exited())<<"process didn't exit!";
ASSERT_EQ(s.exit_status(),0)<<"Help didn't return 0";
}
我處於類似的情況,我的設置方式可以有效地實現與 Mike Kinghan 的答案相同的目標,就編譯器而言,但從用戶的角度來看,這是一種不同的方式。
我所做的是創建一個我稱之為“測試”的自定義配置。 您可以通過打開項目設置,選擇“配置管理器...”並在配置選擇框中選擇“新建...”來創建新配置。
出現提示時,我選擇從默認的“調試”配置中復制設置,以便我可以在測試中使用調試器,就像我在“調試”配置中一樣。
在新的測試配置下,我將編譯器和鏈接器的選項設置為像往常一樣使用 google 測試。
屬性的重要變化是我定義了一個我稱之為“TESTING”的預處理器變量。
我重寫了我的“main.cpp”,看起來像這樣:
...
// includes
// functions
// whatever
...
#ifdef TESTING
#include <gtest/gtest.h>
#endif
int main(int argc, char **argv) {
#ifdef TESTING
::testing::InitGoogleTest(&argc, argv);
int val = RUN_ALL_TESTS();
getchar(); // not necessary, but keeps the console open
return val;
#endif
// rest of main() as normal...
}
我想表明的是,我只在定義main
地方更改了幾行,我不必在整個文件中進行粗略的更改。
現在這一切都設置好了,我只是為我的測試創建了一個新的源文件夾,並在其中創建了“.cpp”文件。 為了避免普通的可執行文件膨脹,我用檢查 TESTING 變量來包裝這些文件,所以我有這樣的東西:
tests/Test.cpp:
#ifdef TESTING
#include <gtest/gtest.h>
#include "my_class_header.h"
TEST(TestMyClass, test_something) {
// perform some test on class
}
#endif
我認為這些文件在 Debug 和 Release 配置下仍然會被編譯器“命中”,因此大量這些文件可能會減慢構建速度,但 Debug 和 Release 對象不會因測試代碼而變得臃腫。
兩個要點是:
.obj
文件可能會成為一件苦差事,但通過使用這種方法,默認的 Visual Studio 設置會為您管理。一個缺點是所有目標文件的有效冗余副本將在“測試”輸出目錄中創建。 有了更多的配置,肯定有一種方法可以“共享”調試目標文件,但我沒有理由走那么遠。
這是一種非常簡單的方法,可能比將您的應用程序重構為單獨的庫和主程序要容易得多。 我不喜歡使用預處理器 wankery,但在這種情況下,它相當簡單,沒有太多代碼膨脹,並且完全完成了它需要的功能。 您可以隨時以另一種方式觸發測試,而無需使用預處理器。
如果您對在不同項目中進行測試不是很嚴格,您可以在您的應用程序項目中編寫測試。 然后讓應用程序在接收到某些命令行參數時執行測試,否則執行正常的應用程序邏輯,即
int main(int argc, char* argv[])
{
if (argc >= 2 && std::string(argv[1]) == "--tests")
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
else
{
// Application logic goes here
}
}
TEST(ExampleTests, TestSQRTCalculation) // assuming all the right headers are included
{
EXPECT_NEAR(2.0, std::sqrt(4.0), 0.000001);
}
這避免了僅為測試目的創建不必要的庫,盡管如果結構正確,您仍然可以這樣做。 缺點是測試代碼會進入您要發布的可執行文件。 如果你不想要,我猜你需要一個額外的配置,它指定一個預處理器指令來禁用測試。
調試測試或在構建后自動運行它們很容易,只需分別指定“--tests”作為調試參數或在構建后命令行中。
如果你想測試一個控制台應用程序,你可以運行一個測試,打開一個控制台窗口並運行第一個應用程序的 exe 文件。 然后在您的 googletest 中捕獲您剛剛運行的 exe 的標准輸出。
[為了更好地控制第一個應用程序,您可能需要將第一個應用程序解析參數發送給它,例如 -x 之類的標志或您需要的任何東西。]
我准備了一個 github 存儲庫,其中包括與 Mike 的“drill-sergeant”建議並行的 Visual Studio 2015 解決方案。 您可以直接使用它,無需任何額外的要求或依賴。
https://github.com/fuatcoskun/GoogleTestVS2015
我希望它有幫助...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.