【发布时间】:2016-06-02 22:34:21
【问题描述】:
如果您在 Google 或 SO 中搜索“unit test stdin stdout python”,您会发现很多问题,每一个问题都以一种或另一种方式回答
你真的需要对 Python 的内置
input/sys.stdin方法进行单元测试吗?
我的回答是是的,我强调这样做,因为我基本上是在实现我自己的input + 穷人的libreadline / libcurses,我需要使用标准输入和终端的内容。
我碰巧使用 Unix 派生的操作系统,所以我有管道 | 和 shell 重定向 <,所以我可以编写一个小 shell 脚本和一些 Python 帮助代码一起执行此操作,并测试终端的操作( ANSI 转义序列、光标移动、打印的确切内容等)我可以从已知的/dev/tty/whatever 中读取信息,但我不想这样做的主要原因有两个:
测试代码应该和它正在测试的代码一样跨平台(而且不那么脆弱!)
-
我非常喜欢
unittest,谢谢,我不想仅仅为了测试我的模块而求助于 shell 脚本和 unix hackery(就像我喜欢 unix hackery 一样)。
必须有更好的方法来测试curses 之类的东西,而不是在您使用 curses 时,而是在您开发 curses 时.
既然有人要求,以下是我要测试的一些示例:(full code on github)
def _Getch():
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
class xyctl:
def _terminal_size():
import fcntl, struct
h, w, hp, wp = struct.unpack('HHHH',
fcntl.ioctl(0, termios.TIOCGWINSZ,
struct.pack('HHHH', 0, 0, 0, 0)))
return w, h, w * h
def _matrix_calc(adj_x, adj_y):
cur_x, cur_y = xyctl.getter()
new_x, new_y = (
(cur_x + adj_x),
(cur_y + adj_y)
)
if (new_x * new_y) < (xyctl._terminal_size()[2]):
return new_x, new_y
else:
_writer(CHAR_BEL)
def getter():
_writer(CHAR_ESC + "[6n")
pos = until("R", raw=True)
_writer(CHAR_CRR + CHAR_SPC * (len(pos) + 1) + CHAR_CRR)
pos = pos[2:].split(";")
pos[0], pos[1] = int(pos[1]), int(pos[0])
return pos
def setter(new_x, new_y):
_writer(CHAR_ESC + "[{};{}H".format(new_x, new_y))
def adjust(adj_x, adj_y):
new_x, new_y = xyctl._matrix_calc(adj_x, adj_y)
xyctl.setter(new_x, new_y)
【问题讨论】:
-
@downvoter/s
please consider adding a comment if you think this post can be improved -
你能给出一个你想测试的代码片段的具体例子吗?它可能通过模拟或存根
input或sys.stdin来完成,这样您就不必测试内置函数,而是测试您的代码对它们的作用。 -
@das-g 我已经编辑了我的问题
标签: python unit-testing