我很困惑。我正在尝试学习使用 pytest-bdd 和 gherkin,但我收到一个 TypeError 说 NoneType 不可迭代。我认为这意味着我试图从中获取值的 dict 不知何故成为了这里某处的 NoneType 对象,但我不知道何时、如何或为什么。发生了什么?如何修复此代码?(请假设此代码引用的程序按预期工作,因为它确实如此。)
这是我遇到很多次的错误(每个测试用例一次):
________________________ test_verify_correct_returns_for_retirement_time[2021-11-January-2099] ________________________
request = <FixtureRequest for <Function test_verify_correct_returns_for_retirement_time[2021-11-January-2099]>>
_pytest_bdd_example = {'month': '11', 'month_name': 'January', 'retire_year': '2099', 'year': '2021'}
@pytest.mark.usefixtures(*args)
def scenario_wrapper(request, _pytest_bdd_example):
scenario = templated_scenario.render(_pytest_bdd_example)
> _execute_scenario(feature, scenario, request)
..\..\..\..\appdata\local\programs\python\python39\lib\site-packages\pytest_bdd\scenario.py:174:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\..\..\..\appdata\local\programs\python\python39\lib\site-packages\pytest_bdd\scenario.py:144: in _execute_scenario
_execute_step_function(request, scenario, step, step_func)
..\..\..\..\appdata\local\programs\python\python39\lib\site-packages\pytest_bdd\scenario.py:114: in _execute_step_function
return_value = step_func(**kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
user_inputs = {'user_birthmonth': '11', 'user_birthyear': '2021'}, retire_year = '2099', month_name = 'January'
@then(parsers.parse("the text the program returns should include 'This will be in {month_name} of {retire_year}.'"), converters=CONVERTERS)
def check_return(user_inputs, retire_year, month_name):
> assert f'This will be in {month_name} of {retire_year}.' in main(user_inputs["user_birthyear"], user_inputs["user_birthmonth"])
E TypeError: argument of type 'NoneType' is not iterable
test_basic_functionality_steps.py:36: TypeError
from pytest_bdd import scenarios, parsers, given, when, then
import pytest
from .full_retirement_age import main
CONVERTERS = {
'year': str,
'month': str,
'retire_years': str,
'retire_months': str,
'retire_year': str,
'month_name': str
}
scenarios("basic_functionality.feature")
@pytest.fixture
@given("the user is using the full_retirement_age.py program")
def user_inputs():
return dict(user_birthyear="", user_birthmonth="")
@when(parsers.parse('the user enters {year} when prompted for their year of birth'), converters=CONVERTERS)
def input_year(user_inputs, year):
user_inputs["user_birthyear"] = year
@when(parsers.parse('the user enters {month} when prompted for their month of birth'), converters=CONVERTERS)
def input_month(user_inputs, month):
user_inputs["user_birthmonth"] = month
@then(parsers.parse("the text the program returns should include 'Your full retirement age is {retire_years} and {retire_months} months.'"), converters=CONVERTERS)
def check_return(user_inputs, retire_years, retire_months):
assert f'Your full retirement age is {retire_years} and {retire_months} months.' in main(user_inputs["user_birthyear"], user_inputs["user_birthmonth"])
@then(parsers.parse("the text the program returns should include 'This will be in {month_name} of {retire_year}.'"), converters=CONVERTERS)
def check_return(user_inputs, retire_year, month_name):
assert f'This will be in {month_name} of {retire_year}.' in main(user_inputs["user_birthyear"], user_inputs["user_birthmonth"])
Feature: Shows Retirement Age and Time
A user will be able to enter their birth year and month,
and get back a string of text printed to the console
that tells them their retirement age as well as the
year and month that they will retire
Scenario Outline: Verify Correct Returns for Retirement Age
Given the user is using the full_retirement_age.py program
When the user enters <year> when prompted for their year of birth
And the user enters <month> when prompted for their month of birth
Then the text the program returns should include 'Your full retirement age is <retire_years> and <retire_months> months.'
# month should not effect the output of retirement age (but should for retirement time)
Examples:
| year | month | retire_years | retire_months |
| 1943 | 7 | 66 | 0 |
| 1954 | 12 | 66 | 0 |
| 1942 | 6 | 65 | 10 |
| 1920 | 4 | 62 | 2 |
| 1900 | 8 | 58 | 10 |
| 1955 | 9 | 66 | 2 |
| 1980 | 1 | 70 | 4 |
| 2021 | 11 | 77 | 2 |
Scenario Outline: Verify Correct Returns for Retirement Time
Given the user is using the full_retirement_age.py program
When the user enters <year> when prompted for their year of birth
And the user enters <month> when prompted for their month of birth
Then the text the program returns should include 'This will be in <month_name> of <retire_year>.'
# In order for these examples to return the correct date, the last scenario
# must work in its entirety as this scenario depends on the function the
# last scenario was testing
Examples:
| year | month | month_name | retire_year |
| 1943 | 7 | July | 2009 |
| 1954 | 12 | December | 2020 |
| 1942 | 6 | April | 2008 |
| 1920 | 4 | June | 1982 |
| 1900 | 8 | June | 1959 |
| 1955 | 9 | November | 2021 |
| 1980 | 1 | May | 2050 |
| 2021 | 11 | January | 2099 |