如何在pytest中对多输入函数进行迭代断言验证?
如何依次迭代验证每个输入的断言?
我参考了Stack Overflow上的已采纳回答,想要通过迭代方式编写断言,依次测试每个输入对应迭代器中的元素,但当前代码无法正常运行,遇到了几个问题:
问题1:多断言语句直接失效
下面的代码在第一个输入验证通过后,后续断言直接报错:
def test_test_get_genre_rock(monkeypatch): responses = iter(['rock','ska','punk']) monkeypatch.setattr('builtins.input', lambda _: next(responses)) genre = str(input("Select 1 to 5 genres - press 'ENTER' when done: ")).lower() assert genre == "rock" assert genre == "ska" # 显然多断言这么写是错的
原因很简单:genre只被赋值了一次,拿到的是迭代器的第一个值rock,后续断言要求它等于ska,自然不成立。
问题2:逗号分隔断言值的误区
尝试用逗号分隔多个值时,第二个参数根本不会被当作断言条件:
def test_test_get_genre_rock(monkeypatch): responses = iter(['rock','ska','punk']) monkeypatch.setattr('builtins.input', lambda _: next(responses)) genre = str(input("Select 1 to 5 genres - press 'ENTER' when done: ")).lower() assert genre == "rock", "ska" # 这两行代码效果完全一致 assert genre == "rock", "ska" assert genre == "rock"
Python的assert语法中,逗号后面的内容是错误提示信息,不是第二个断言条件,所以这种写法和单独写assert genre == "rock"没有区别。
问题3:or运算符的局限性
用or运算符时测试能通过,但这只是验证输入值属于列表中的任意项,无法保证顺序:
assert genre == "rock" or genre == "ska" or genre == "punk"
这不符合需求——我需要的是第一个输入对应迭代器的第0个元素,第二个输入对应第1个,以此类推。
解决方案:多次调用input并依次断言
要实现依次验证每个输入的顺序匹配,核心是每次调用input()都获取迭代器的下一个元素,然后单独断言:
方案1:直接多次调用input并断言
def test_test_get_genre_rock(monkeypatch): responses = iter(['rock','ska','punk']) monkeypatch.setattr('builtins.input', lambda _: next(responses)) # 验证第一个输入 genre = str(input("Select 1 to 5 genres - press 'ENTER' when done: ")).lower() assert genre == "rock" # 验证第二个输入 genre = str(input("Select 1 to 5 genres - press 'ENTER' when done: ")).lower() assert genre == "ska" # 验证第三个输入 genre = str(input("Select 1 to 5 genres - press 'ENTER' when done: ")).lower() assert genre == "punk"
方案2:测试批量输入的函数(更贴近实际场景)
如果是要测试一个需要多次输入的函数,比如用户循环输入直到回车结束,那么可以通过验证函数的输出结果来确保顺序正确:
假设待测试函数:
def collect_genres(): genres = [] prompt = "Select 1 to 5 genres - press 'ENTER' when done: " while True: genre = input(prompt).lower() if not genre: break genres.append(genre) return genres
对应的测试代码:
def test_collect_genres(monkeypatch): # 最后一个空字符串触发循环退出 responses = iter(['rock','ska','punk','']) monkeypatch.setattr('builtins.input', lambda _: next(responses)) collected = collect_genres() # 直接断言结果列表和迭代器元素顺序完全一致 assert collected == ['rock', 'ska', 'punk']
这样就能确保每个输入按顺序对应迭代器中的元素,完全满足需求。
内容的提问来源于stack exchange,提问作者Derfoozer
相关产品推荐
相关产品推荐

