2010-09-27 90 views
31

使用googletest框架時可以捕獲stdout和stderr嗎?如何使用googletest捕獲stdout/stderr?

例如,我想調用一個將錯誤寫入控制檯(stderr)的函數。 現在,當在測試中調用函數時,我想斷言沒有輸出出現在那裏。

或者,也許我想測試錯誤行爲,並且想要斷言當我(故意)產生錯誤時打印某個字符串。

+4

從設計的角度來看,我建議修改的實施,使切換到日誌文件是那麼痛苦。例如,使用'ostream'接口會更容易。 – 2010-09-27 12:01:47

回答

24

在測試輸出時,我已經使用此片段將cout調用重定向到stringstream。希望它可能引發一些想法。我以前從未使用過googletest。

// This can be an ofstream as well or any other ostream 
std::stringstream buffer; 

// Save cout's buffer here 
std::streambuf *sbuf = std::cout.rdbuf(); 

// Redirect cout to our stringstream buffer or any other ostream 
std::cout.rdbuf(buffer.rdbuf()); 

// Use cout as usual 
std::cout << "Hello World"; 

// When done redirect cout to its old self 
std::cout.rdbuf(sbuf); 

在重定向回原始輸出之前,請使用google測試檢查緩衝區中的輸出。

2

避免這樣做總是一個好的設計理念。如果你真的想這樣做了以下工作:

#include <cstdio> 
#include <cassert> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <iostream> 

int main() { 
    int fd = open("my_file.log", O_WRONLY|O_CREAT|O_TRUNC, 0660); 
    assert(fd >= 0); 
    int ret = dup2(fd, 1); 
    assert(ret >= 0); 
    printf("This is stdout now!\n"); 
    std::cout << "This is C++ iostream cout now!" << std::endl; 
    close(fd); 
} 

要使用標準錯誤而不是標準輸出改變的第二個參數DUP2爲2。對於沒有通過,你可以使用管道對,而不是一個文件去捕捉。

+4

當然這也是不可移植到沒有dup2的系統... – Flexo 2010-10-27 09:57:43

49

Googletest此提供各種功能:

testing::internal::CaptureStdout(); 
std::cout << "My test" 
std::string output = testing::internal::GetCapturedStdout(); 
+0

可能是最簡單的可能解決方案 – 2015-10-26 01:54:31

+0

這隻適用於'stdout',而不是'stderr'?有死亡測試可以捕獲「stderr」,但在很多情況下,您可能沒有測試過程終止。 – meowsqueak 2015-11-25 01:53:41

+1

testing :: internal :: CaptureStderr()也存在。這裏使用例如:https://googletest.googlecode.com/svn/trunk/test/gtest-death-test_test.cc – Heinzi 2015-11-25 14:37:50

1

而不是做到這一點,使用依賴注入,除去直接利用std::cout。在您的測試代碼中,使用類std:ostringstream的模擬對象作爲模擬對象,而不是真實的std::cout

因此,不是這樣的:

void func() { 
    ... 
    std::cout << "message"; 
    ... 
} 

int main (int argc, char **argv) { 
    ... 
    func(); 
    ... 
} 

有這樣的:

void func(std::ostream &out) { 
    ... 
    out << "message"; 
    ... 
} 

int main(int argc, char **argv) { 
    ... 
    func(std::cout); 
    ... 
}