Pytest 执行特定功能但不执行 main()
Pytest execute specific functions but not main()
我正在完成 udemy 的 python 编码课程,并且有一个 project 目录结构如下:
├── LICENSE
├── README.md
├── __init__.py
├── requirements.txt
├── src
│ ├── __init__.py
│ └── milage_converter.py
└── tests
├── __init__.py
└── milage_converter_test.py
在 milage_converter_test.py
内,我正在 运行 进行一些简单的测试,例如:
from py_exercises.src import milage_converter
def test_base_milage_string_to_float(monkeypatch):
# monkeypatch the "input" function, so that it returns "10".
monkeypatch.setattr('builtins.input', lambda _: "10")
assert milage_converter.get_base_milage(1) == 10.0
但是这些似乎在调用 main()
function in milage_converter.py
。
def get_conversion_direction():
"""Gets the conversion direction input from a user, converts to a float and returns."""
user_input = input(
"Would you like to convert from (1) Miles to Kilometers or (2) Kilometers to Miles: ")
try:
user_input = float(user_input)
except ValueError:
print(
"Invalid input, options are 1 for Miles to Kilometer or 2 for Kilometers to Miles.")
get_conversion_direction()
while user_input in (1, 2):
user_input = input(
"You chose an invalid value, please enter a value of 1 or 2: ")
return user_input
def get_base_milage(unit):
"""Gets the milage input from a user, converts to a float and returns."""
in_milage = input(f"Please input a value in {unit} to convert: ")
try:
in_milage = float(in_milage)
except ValueError:
print(
"Invalid input, please input a valid numerical value to convert.")
# Adding return avoids the exception being returned:
#
return get_base_milage(unit)
return in_milage
def main():
direction = get_conversion_direction()
if direction == 1:
print(
f"You have selected {direction}, converting from Miles to Kilometers.")
miles = int(get_base_milage("Miles"))
print(f"{miles} Miles is equal to {round(miles * 1.609344, 2)}")
else:
print(
f"You have selected {direction}, converting from Kilometers to Miles.")
kilometers = get_base_milage("Kilometers")
print(f"{kilometers} Kilometers is equal to {round(kilometers / 1.609344, 2)}")
main()
当我从项目目录 运行 pytest
时,我得到输入提示,就好像我有 运行 milage_converter.py
模块一样 python3.9 milage_converter.py
。这是抛出 pytest
无法捕获标准输入的错误。
------------------------------------------------------------------------------------------ Captured stdout -------------------------------------------------------------------------------------------
Would you like to convert from (1) Miles to Kilometers or (2) Kilometers to Miles:
====================================================================================== short test summary info =======================================================================================
ERROR tests/milage_converter_test.py - OSError: pytest: reading from stdin while output is captured! Consider using `-s`.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
========================================================================================== 1 error in 0.10s ==========================================================================================
我期望 pytest
会简单地调用指定的函数,get_base_milage()
并模拟输入。如果我在 milage_converter.py 的第 51 行注释掉 main()
pytest
会像我预期的那样 运行 ,所以我觉得我在这里遗漏了一些东西 pytest/mocking python.
如果您打算 运行 将 milage_converter.py
作为脚本,例如python milage_converter.py
,那么最好检查它是否如记录的那样 __main__:
A module can discover whether or not it is running in the main scope by checking its own name, which allows a common idiom for conditionally executing code in a module when it is run as a script or with python -m but not when it is imported:
if __name__ == "__main__":
# execute only if run as a script
main()
因此将此添加到您的 milage_converter.py
...
if __name__ == '__main__':
main()
你的测试失败的原因是当你通过from py_exercises.src import milage_converter
导入文件时(此时还没有活动补丁),它当然会读取文件中的代码。由于您对 main()
的调用就在那里,因此它会立即执行。现在有了这个条件,它将是 False
因此不会再执行它了。
相关参考:
- What does if __name__ == "__main__": do?
我正在完成 udemy 的 python 编码课程,并且有一个 project 目录结构如下:
├── LICENSE
├── README.md
├── __init__.py
├── requirements.txt
├── src
│ ├── __init__.py
│ └── milage_converter.py
└── tests
├── __init__.py
└── milage_converter_test.py
在 milage_converter_test.py
内,我正在 运行 进行一些简单的测试,例如:
from py_exercises.src import milage_converter
def test_base_milage_string_to_float(monkeypatch):
# monkeypatch the "input" function, so that it returns "10".
monkeypatch.setattr('builtins.input', lambda _: "10")
assert milage_converter.get_base_milage(1) == 10.0
但是这些似乎在调用 main()
function in milage_converter.py
。
def get_conversion_direction():
"""Gets the conversion direction input from a user, converts to a float and returns."""
user_input = input(
"Would you like to convert from (1) Miles to Kilometers or (2) Kilometers to Miles: ")
try:
user_input = float(user_input)
except ValueError:
print(
"Invalid input, options are 1 for Miles to Kilometer or 2 for Kilometers to Miles.")
get_conversion_direction()
while user_input in (1, 2):
user_input = input(
"You chose an invalid value, please enter a value of 1 or 2: ")
return user_input
def get_base_milage(unit):
"""Gets the milage input from a user, converts to a float and returns."""
in_milage = input(f"Please input a value in {unit} to convert: ")
try:
in_milage = float(in_milage)
except ValueError:
print(
"Invalid input, please input a valid numerical value to convert.")
# Adding return avoids the exception being returned:
#
return get_base_milage(unit)
return in_milage
def main():
direction = get_conversion_direction()
if direction == 1:
print(
f"You have selected {direction}, converting from Miles to Kilometers.")
miles = int(get_base_milage("Miles"))
print(f"{miles} Miles is equal to {round(miles * 1.609344, 2)}")
else:
print(
f"You have selected {direction}, converting from Kilometers to Miles.")
kilometers = get_base_milage("Kilometers")
print(f"{kilometers} Kilometers is equal to {round(kilometers / 1.609344, 2)}")
main()
当我从项目目录 运行 pytest
时,我得到输入提示,就好像我有 运行 milage_converter.py
模块一样 python3.9 milage_converter.py
。这是抛出 pytest
无法捕获标准输入的错误。
------------------------------------------------------------------------------------------ Captured stdout -------------------------------------------------------------------------------------------
Would you like to convert from (1) Miles to Kilometers or (2) Kilometers to Miles:
====================================================================================== short test summary info =======================================================================================
ERROR tests/milage_converter_test.py - OSError: pytest: reading from stdin while output is captured! Consider using `-s`.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
========================================================================================== 1 error in 0.10s ==========================================================================================
我期望 pytest
会简单地调用指定的函数,get_base_milage()
并模拟输入。如果我在 milage_converter.py 的第 51 行注释掉 main()
pytest
会像我预期的那样 运行 ,所以我觉得我在这里遗漏了一些东西 pytest/mocking python.
如果您打算 运行 将 milage_converter.py
作为脚本,例如python milage_converter.py
,那么最好检查它是否如记录的那样 __main__:
A module can discover whether or not it is running in the main scope by checking its own name, which allows a common idiom for conditionally executing code in a module when it is run as a script or with python -m but not when it is imported:
if __name__ == "__main__": # execute only if run as a script main()
因此将此添加到您的 milage_converter.py
...
if __name__ == '__main__':
main()
你的测试失败的原因是当你通过from py_exercises.src import milage_converter
导入文件时(此时还没有活动补丁),它当然会读取文件中的代码。由于您对 main()
的调用就在那里,因此它会立即执行。现在有了这个条件,它将是 False
因此不会再执行它了。
相关参考:
- What does if __name__ == "__main__": do?