[英]Get the last string printed in C/C++
我正在嘗試使用 googletest 創建測試儀。 問題是我正在測試的函數返回 void 並打印結果。 我想將最后一個字符串打印到控制台中,以便我可以測試輸出。 字符串可能包括\\n
。
所以我有這個功能:
void f_sequence(char sequenceStr[])
{
//logic...
if(condotion1)
printf("somthing1");
else if(condotion2)
printf("somthing2")
(...)
}
然后是測試人員:
TEST(TesterGroup, TesterName)
{
f_sequence("input");
EXPECT_EQ("somthing1", /*how do i get the output?*/);
}
是否可以?
我測試的函數在 c 中,而 Test 函數本身(測試器)在 c++ 中。 使用printf
打印輸出。 我無法更改功能本身。 我正在使用 CLion 最新版本。
將標准輸出重定向到緩沖區。
#include <stdio.h>
#include <unistd.h>
#define BUFFER_SIZE 1024
int stdoutSave;
char outputBuffer[BUFFER_SIZE];
void replaceStdout()
{
fflush(stdout); //clean everything first
stdoutSave = dup(STDOUT_FILENO); //save the stdout state
freopen("NUL", "a", stdout); //redirect stdout to null pointer
setvbuf(stdout, outputBuffer, _IOFBF, 1024); //set buffer to stdout
}
void restoreStdout()
{
freopen("NUL", "a", stdout); //redirect stdout to null again
dup2(stdoutSave, STDOUT_FILENO); //restore the previous state of stdout
setvbuf(stdout, NULL, _IONBF, BUFFER_SIZE); //disable buffer to print to screen instantly
}
void printHelloWorld()
{
printf("hello\n");
printf("world");
}
int main()
{
replaceStdout();
printHelloWorld();
restoreStdout();
// Use outputBuffer to test EXPECT_EQ("somthing1", outputBuffer);
printf("Fetched output: (%s)", outputBuffer);
return 0;
}
參考資料: http : //kaskavalci.com/redirecting-stdout-to-array-and-restoring-it-back-in-c/
我不知道是否有可能獲得上次打印的內容,但是如果您在調用測試函數之前控制環境,則可以重定向標准輸出的位置,這樣您就可以將其寫入文件,然后您可以檢查.
請參閱 IMO 被忽略的舊答案。 來自它的示例在此處修改:
FILE *fp_old = stdout; // preserve the original stdout
stdout = fopen("/path/to/file/you/want.txt","w"); // redirect stdout to anywhere you can open
// CALL YOUR FUNCTION UNDER TEST HERE
fclose(stdout); // Close the file with the output contents
stdout=fp_old; // restore stdout to normal
// Re-open the file from above, and read it to make sure it contains what you expect.
兩種方式:
如果您使用的是 POSIX 兼容系統,則可以使用>
將程序的輸出重定向到文件,然后稍后從文件中讀取以確認輸出正確。
另一種方式是這樣的:
freopen("output.txt", "w", stdout);
f_sequence();
freopen("/dev/tty", "w", stdout);
適用於 POSIX 兼容系統。 在其他平台上,您需要將"/dev/tty"
更改為其他內容。 我不知道一種完全可移植的方法來做到這一點。
然后從output.txt
讀取。 上面的代碼片段所做的是改變stdout
是什么,以便它打印到一個文件而不是普通的 stdout。
一種解決方案:您可以編寫一個單獨的程序來執行該函數,並且在單元測試中,您可以將該程序作為子進程執行並檢查輸出。 這可以通過std::system
,但要非常小心,不要將任何非常量輸入傳遞給它。 即使在單元測試中,您也不希望出現 shell 注入漏洞。 存在避免在子進程中使用 shell 的系統特定功能。
另一個解決方案,至少在 POSIX 上是可能的:用文件描述符替換標准輸出/錯誤流,然后讀取文件。
Googletest 具體:似乎有testing::internal::CaptureStdout
,它似乎實現了替換標准流的想法。 但正如命名空間所暗示的那樣,這不是官方 API,因此將來可能會發生變化。
有一個 API 調用 ( cmd_rsp
) 的解決方案(在C
) 帶有源代碼here ,當在您的程序中調用時,它會創建一個單獨的進程,並通過管道連接到stdin
和stdout
,從中它接受命令並返回響應通過自動調整大小緩沖區。 在概念上類似於popen(...)
。
一個簡單的用例:
char *buf = NULL;
/// test cmd_rsp
buf = calloc(BUF_SIZE, 1);
if(!buf)return 0;
if (!cmd_rsp("dir /s", &buf, BUF_SIZE))//note the first argument can be any legal command that
//can be sent via the CMD prompt in windows,
//including a custom executable
{
printf("%s", buf);
}
else
{
printf("failed to send command.\n");
}
free(buf);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.