我对这整个“编程事物”还很陌生,但在 34 岁时,我认为我想学习基础知识。 不幸的是,我不认识任何 python 程序员。我学习编程是出于个人兴趣(而且越来越多是为了乐趣),但我的“社交栖息地”不是“程序员漫游的地方”;)。 我几乎完成了 Zed Shaws 的“艰难地学习 Python”,这是我第一次找不到问题的解决方案。在过去的两天里,当我反复改写(并搜索)我的问题时,我什至没有偶然发现有用的提示。 所以stackoverflow似乎是正确的地方。 顺便说一句:我也经常缺乏正确的词汇,所以请不要犹豫纠正我:)。这可能是我找不到答案的原因之一。 我使用 Python 2.7 和 nosetests。
我在解决问题的步骤中(我认为)在多大程度上解决了这个问题:
函数一:
def inp_1():
s = raw_input(">>> ")
return s
所有测试都导入以下内容以执行以下操作:
from nose.tools import *
import sys
from StringIO import StringIO
from mock import *
import __builtin__
# and of course the module with the functions
这是 inp_1 的测试:
import __builtin__
from mock import *
def test_inp_1():
__builtin__.raw_input = Mock(return_value="foo")
assert_equal(inp_1(), 'foo')
这个功能/测试没问题。
非常相似的是下面的函数2:
def inp_2():
s = raw_input(">>> ")
if s == '1':
return s
else:
print "wrong"
测试:
def test_inp_2():
__builtin__.raw_input = Mock(return_value="1")
assert_equal(inp_1(), '1')
__builtin__.raw_input = Mock(return_value="foo")
out = StringIO()
sys.stdout = out
inp_1()
output = out.getvalue().strip()
assert_equal(output, 'wrong')
这个功能/测试也是可以的。
当我使用上述所有内容时,请不要假设我真的知道“幕后”发生了什么。我有一些外行解释这是如何运作的,以及为什么我得到我想要的结果,但我也觉得这些解释可能并不完全正确。这不是我第一次这么想……学多了作品就不一样了。特别是所有带有“__”的东西都让我感到困惑,我不敢使用它,因为我真的不明白发生了什么。无论如何,现在我“只是”想添加一个 while 循环来请求输入,直到输入正确为止:
def inp_3():
while True:
s = raw_input(">>> ")
if s == '1':
return s
else:
print "wrong"
我认为对 inp_3 的测试与对 inp_2 的测试相同。至少我没有收到错误消息。但输出如下:
$ nosetests
......
# <- Here I press ENTER to provoke a reaction
# Nothing is happening though.
^C # <- Keyboard interrupt (is this the correct word for it?)
----------------------------------------------------------------------
Ran 7 tests in 5.464s
OK
$
其他 7 个测试是……。否则(好吧)。 inp_3 的测试将是测试 nr。 8. 时间就是我按下 CTRL-C 之前耗时。 我不明白为什么我没有收到错误消息或“测试失败”消息,而是收到“确定”消息。
所以除了您可能能够指出错误的语法和其他可以改进的地方(如果您愿意这样做,我真的很感激),我的问题是:
如何使用 nosetest 测试和中止 while 循环?
最佳答案
因此,这里的问题是当您第二次在测试中调用 inp_3 时,同时使用 Mock(return_value="foo")
模拟 raw_input。您的 inp_3 函数运行无限循环 (while True
) ,并且除了 if s == '1'
条件外,您不会以任何方式中断它。因此,使用 Mock(return_value="foo")
永远不会满足该条件,并且您的循环会一直运行,直到您用外部方式(在您的示例中为 Ctrl + C)中断它。如果是故意行为,则 How to limit execution time of a function call in Python将帮助您限制 inp_3 在测试中的执行时间。但是,在您的示例中的输入情况下,开发人员通常会限制用户的输入尝试次数。您可以使用变量来计算尝试次数,当它达到最大值时,应该停止循环。
def inp_3():
max_attempts = 5
attempts = 0
while True:
s = raw_input(">>> ")
attempts += 1 # this is equal to "attempts = attempts + 1"
if s == '1':
return s
else:
print "wrong"
if attempts == max_attempts:
print "Max attempts used, stopping."
break # this is used to stop loop execution
# and go to next instruction after loop block
print "Stopped."
另外,要学习 Python,我可以推荐 Mark Lutz 的书“Learning Python”。它很好地解释了 python 的基础知识。
更新:
我找不到一种方法来模拟 python 的 True(或 builtin.True)(是的,这听起来有点疯狂),看起来 python 没有(也不会) ) 请允许我这样做。但是,要准确实现您想要的效果,即运行一次无限循环,您可以使用一些技巧。
定义一个返回True的函数
def true_func():
return True
,在while循环中使用
while true_func():
然后用这样的逻辑在测试中模拟它:
def true_once():
yield True
yield False
class MockTrueFunc(object):
def __init__(self):
self.gen = true_once()
def __call__(self):
return self.gen.next()
然后在测试中:
true_func = MockTrueFunc()
这样你的循环将只运行一次。但是,此构造使用了一些高级 Python 技巧,例如生成器、“__”方法等。因此请谨慎使用。
但无论如何,无限循环通常被认为是糟糕的设计解决方案。最好不要习惯它:)。
关于python - 如何使用 nosetest (Python 2.7) 测试 while 循环(一次),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27191543/