我有一个C应用程序,它提供了一个用于输入命令的“shell”。我正在尝试为应用程序编写一些自动化测试代码(使用CUnit)。从stdin读取“shell”输入,如下所示:
fgets(buf, sizeof(buf), stdin);
我可以通过freopen()将stdin自动“写入”到应用程序并将其挂钩到中间文件。当应用程序“正常”执行时,fgets()调用块直到可用,因为它是“交互式设备”,但在中间文件上却不是这样。那么我怎么能假装fgets认为中间文件是一个“交互设备”。
C程序适用于使用MinGW编译的Windows(XP)。
问候!
答案 0 :(得分:1)
fgets
没有阻塞,因为它到达文件末尾会导致EOF
在流上设置,因此调用fgets
会立即返回。当您从交互式输入运行时EOF
从未设置,除非您在当前键入Ctrl-Z(或UNIX系统上的Ctrl-D)。
如果你真的想要使用一个中间文件,我认为你需要增强你的shell,这样当它击中一个EOF时它会在适当的等待后清除并重新测试它。我认为这样的功能应该起作用: -
void waitForEofClear(FILE *f)
{
while (feof(f)) {
clearerr(f);
sleep(1);
}
}
然后您可以在fgets
: -
waitForEofClear(stdin);
fgets(buf, sizeof(buf), stdin);
答案 1 :(得分:1)
正如其他答案所表明的那样,简单地使用文件是行不通的。所以,你需要决定你要做什么。 FIFO(命名管道)或普通(匿名)管道可用于为测试中的交互程序提供数据 - 或者,在Unix上,您可以使用伪tty。所有这些的优点是程序在没有数据读取时阻塞,等待下一个信息到达,而不是立即决定“没有数据要读取,必须是EOF”。
然后,您需要一个半智能(甚至是智能)程序,定期将数据写入通道以供读取的程序读取。该程序需要知道它写入的消息之间要暂停多长时间。这可能就像'等一秒钟'一样简单;写下一行数据'。或者你可能会做一些更复杂的事情。
我知道的一个方案有两个程序 - 一个捕获程序来记录用户键入的内容及其时间(所以'数据'文件是结构化的;它有包含延迟的记录(以秒为单位)第二个)加上一组要发送的字符(计数和字节列表)。这是为了捕获用户输入和记录的内容(以及将数据发送到程序)。然后有第二个重播程序读取文件,并解释延迟和字符序列。
如果输入序列稳定,该方案可以正常工作;如果总是需要相同的击键序列来获得所需的结果。如果发送给程序的数据需要适应被测程序正在做的事情及其响应,并且可能在不同的时间做不同的事情,那么最好使用“expect”。这可以满足您的需求 - 至少对于非GUI程序而言。
答案 2 :(得分:0)
我不确定Windows的等价物是什么,但在Linux中我会将中间文件设为fifo。如果我要做一个真正的非平凡的自动驾驶,我会把它包装在一个期望的脚本中。