1

我有一个 C 应用程序,它为输入命令提供了一个“shell”。我正在尝试为应用程序编写一些自动化测试代码(使用 CUnit)。从标准输入读取“shell”输入,如下所示:

fgets(buf, sizeof(buf), stdin);

我可以通过 freopen()'ning stdin 将命令自动“写入”到应用程序并将其连接到中间文件。当应用程序“正常”执行时,fgets() 调用会阻塞,直到字符可用,因为它是“交互式设备”,但在中间文件上则不然。那么我怎样才能假装 fgets 认为中间文件是一个“交互式设备”。

C 程序适用于使用 MinGW 编译的 Windows (XP)。

问候!

4

3 回答 3

1

fgets从文件读取时不会阻塞,因为它到达文件末尾,导致EOF在流上设置,因此调用fgets立即返回。当您从交互式输入运行时,EOF永远不会设置,除非您当然键入 Ctrl-Z(或 UNIX 系统上的 Ctrl-D)。

如果您真的想使用中间文件,我认为您需要增强您的外壳,以便当它遇到 EOF 时,它会在适当的等待后清除并重新测试它。我认为这样的功能应该可以工作:-

void waitForEofClear(FILE *f)
{
   while (feof(f)) {
      clearerr(f);
      sleep(1);
   }
}

然后你可以在fgets:-

waitForEofClear(stdin);
fgets(buf, sizeof(buf), stdin);
于 2010-03-03T21:56:28.177 回答
1

正如其他答案所表明的那样,简单地使用文件是行不通的。所以,你需要决定你要做什么。FIFO(命名管道)或普通(匿名)管道可用于为被测交互式程序提供数据——或者,在 Unix 上,您可以使用伪 tty。所有这些的好处是程序在没有数据读取时阻塞,等待下一个信息到达,而不是立即决定'没有数据要读取,必须是EOF'。

然后,您将需要一个半智能(甚至智能)程序定期将数据写入通道以供被测程序读取。该程序需要知道在它写入的消息之间暂停多长时间。这可能就像“等待一秒钟;写入下一行数据'。或者你可能会做一些更复杂的事情。

我知道的一个方案有两个程序 - 一个捕获程序,用于记录用户键入的内容及其时间(因此“数据”文件是结构化的;它的记录包括延迟(以秒为单位)加上一组要发送的字符(计数和字节列表)。运行它以捕获用户键入的内容并记录它(以及将数据发送到程序)。然后有第二个重播程序读取文件,并解释延迟和字符序列。

如果输入序列是稳定的,该方案就可以充分发挥作用;如果始终需要相同的击键序列来获得所需的结果。如果发送给程序的数据需要适应被测程序正在做什么及其响应,并且可能在不同的时间做不同的事情,那么你最好使用“ expect ”。这有能力做任何你需要的事情——至少对于非 GUI 程序。

于 2010-03-04T03:18:41.733 回答
0

我不确定 Windows 等效项是什么,但在 Linux 中,我会将中间文件设为 fifo。如果我要做一个真正重要的自动驾驶,我会把它包装在一个期望脚本中。

于 2010-03-04T00:01:10.290 回答