[英]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.