提问人:Kevinkun 提问时间:5/22/2023 更新时间:5/22/2023 访问量:117
调用使用 try/except 捕获异常的函数时,无法在 pytest 中测试 ValueError
Failed to test ValueError in pytest when calling a function that using try/except to catch exception
问:
我有这个代码,基本上只是为了在几分钟内找出人们的年龄:
import datetime, inflect, operator, sys
Inflect = inflect.engine()
def main():
# Ask user for their dob, Wait for return of final year minutes in words
print(get_year(input("Date of Birth: ")))
def get_year(date):
# Get and Validate user DOB input
try:
# Split each YY MM DD based on -
date = date.split("-")
# Convert user input to datetime format
date = datetime.date(int(date[0]), int(date[1]), int(date[2]))
# Get years distance between user's input date and today's date
years_distance = operator.sub(datetime.date.today(), date)
# Get user age in minutes: Convert years distance to minutes by divide seconds to 60
# Also Convert to int so we don't get float as result, which we don't want word 'point zero'
years_distance_in_minutes = int(years_distance.total_seconds() / 60)
# Conver string numbers to words
return convert_to_words(years_distance_in_minutes)
except ValueError:
sys.exit("Invalid date")
def convert_to_words(minutes):
# Convert number to words with inflect engine
words = Inflect.number_to_words(minutes, andword="")
return words.capitalize() + " minutes"
if __name__ == "__main__":
main()
这是我的pytest代码:
import pytest
from seasons import get_year
def test_valid_get_year():
assert get_year("2022-05-22") == "Five hundred twenty-five thousand, six hundred minutes"
assert get_year("2021-05-22") == "One million, fifty-one thousand, two hundred minutes"
assert get_year("1997-11-06") == "Thirteen million, four hundred thirty-two thousand, three hundred twenty minutes"
@pytest.mark.parametrize("date", ["cat", "22/05/202", "November 6, 1997", "1999-13-30", "3000-11-06"])
def test_invalid_get_year(date):
with pytest.raises(ValueError):
get_year(date)
如果您查看我的函数,它将完美地处理任何无效格式日期,并且会立即使用。get_year()
try/except
sys.exit("Invalid date")
但是当我运行pytest时,这段代码总是失败的:
@pytest.mark.parametrize("date", ["cat", "22/05/202", "November 6, 1997", "1999-13-30", "3000-11-06"])
def test_invalid_get_year(date):
with pytest.raises(ValueError):
get_year(date)
输出始终为:
except ValueError:
> sys.exit("Invalid date")
E SystemExit: Invalid date
> with pytest.raises(ValueError):
E Failed: DID NOT RAISE <class 'ValueError'>
在我的理解中,pytest 似乎在我的函数中不能完美地工作。有一个示例,我不需要使用,我可以单独验证每行代码并引发 ValueError。try/except
get_year()
try/except
if/else
但是有没有办法像我一样使用并且必须通过它?try/except
get_year()
pytest
答:
0赞
Yum Lee
5/22/2023
#1
在错误处理期间调用是一种不好的做法。
这行代码本质上是一个断言,告诉pytest期待你的函数出现异常。sys.exit
with pytest.raises
get_year
因为它调用 ,程序在异常之前退出, , 可以到达 pytest,所以它抱怨以下消息:sys.exit
ValueError
E Failed: DID NOT RAISE <class 'ValueError'>
删除并让 python 运行时为您处理异常。sys.exit
try:
...
except ValueError as err:
log_your_error(err)
raise # this will re-raise the error so that pytest sees it
评论
0赞
Kevinkun
5/22/2023
您的代码可以完美地工作。但事情是这样的:目标是在用户输入无效格式日期时退出。在捕获异常后如何处理这个问题?sys.exit()
try/except
0赞
Yum Lee
5/22/2023
@Kevinkun尝试在 main 函数中捕获 ValueError 并打印出错误消息并退出。即使您什么都不做,Python 运行时也会打印出默认错误消息并退出。
0赞
Kevinkun
5/22/2023
我刚刚解决了这个问题。在 I do 和 my pytest 中,我更改为 .你怎么看?except ValueError:
raise sys.exit("Invalid date")
ValueError
SystemExit
with pytest.raises(SystemExit):
0赞
Yum Lee
5/22/2023
@Kevinkun 是的。这也行得通。该词在该处不是必需的,因为在内部引发 SystemExit 异常。raise
sys.exit
评论
ValueError
sys.exit
SystemExit