我想单独测试一个打印到stdout的C函数,但是在我搜索之后我到达了// check, if the node is part of a TextField
public static boolean checkTextField(Node node) {
while (node != null) {
if (node instanceof TextField) {
return true;
}
node = node.getParent();
}
return false;
}
,os.dup
以及其他不是捕获stdout的最酷方法的东西。 C共享库函数。所以我想把Python的stdout传递给C函数后写入它然后我可以得到要测试的值,但它不起作用。
这是代码:
将文件编译为共享库:
os.pip
gcc -shared -Wl,-soname,tomat -o tomat.so -fPIC tomat.c
/* filename: tomat.c */
#include <stdio.h>
#include <unistd.h>
int
tomat(int length, FILE *stdout_)
{
int remain = 0;
while ((remain = (length -= 1)) != 0)
{
fprintf(stdout_, "00:%d\n", remain);
sleep(1);
}
return 0;
}
答案 0 :(得分:0)
希望它能帮助别人。
import os
import sys
from tempfile import TemporaryFile
from io import TextIOWrapper, SEEK_SET
from contextlib import contextmanager
from ctypes import c_void_p
@contextmanager
def capture(stream, libc):
osfd = sys.stdout.fileno()
fd = os.dup(osfd)
try:
tfile = TemporaryFile(mode='w+b')
redirect_stdout(tfile.fileno(), osfd, libc)
yield
redirect_stdout(fd, osfd, libc)
tfile.flush()
tfile.seek(0, SEEK_SET)
stream.write(tfile.read())
finally:
tfile.close()
os.close(fd)
def redirect_stdout(fd, osfd, libc):
libc.fflush(c_void_p.in_dll(libc, 'stdout'))
sys.stdout.close()
os.dup2(fd, osfd)
sys.stdout = TextIOWrapper(os.fdopen(osfd, 'wb'))
我是如何使用它来测试计时器功能的输出的:
from io import BytesIO
from ctypes import CDLL
from unittest import TestCase
from helpers import capture
class TomatTestCase(TestCase):
def setUp(self):
self.libc = CDLL('./tomat.so')
self.maxDiff = None
def test_prints_every_second(self):
seconds = [
'01:00', '01:01', '01:02', '01:03', '01:04', '01:05', '01:06',
'01:07', '01:08', '01:09', '01:10', '01:11', '01:12', '01:13',
'01:14', '01:15', '01:16', '01:17', '01:18', '01:19', '01:20',
'01:21', '01:22', '01:23', '01:24', '01:25', '01:26', '01:27',
'01:28', '01:29', '01:30', '01:31', '01:32', '01:33', '01:34',
'01:35', '01:36', '01:37', '01:38', '01:39', '01:40', '01:41',
'01:42', '01:43', '01:44', '01:45', '01:46', '01:47', '01:48',
'01:49', '01:50', '01:51', '01:52', '01:53', '01:54', '01:55',
'01:56', '01:57', '01:58', '01:59', '01:60']
stream = BytesIO()
with capture(stream, self.libc):
self.libc.tomat(2)
stream = stream.getvalue().split()
output = [byte.decode() for byte in stream]
self.assertListEqual(output, seconds)
有关其工作原理的更多信息,请查看Eli Bendersky的帖子:http://eli.thegreenplace.net/2015/redirecting-all-kinds-of-stdout-in-python/