Parameterizing tests is a good way to run the same test multiple times with different inputs. You might be thinking that this breaks the rule about a test only testing a single thing, but in fact the test does only test a single thing - we are just reusing the bulk of the code as the inputs/expected outputs are the only things that differ. This actually eliminates test smell and makes modifying the tests if the API changes in the future much faster as we are only modifying a single test.
@pytest.mark.parametrize('start, end, station, expected', [
# Single Digit Datetimes
(datetime.datetime(2018, 1, 5, 1), datetime.datetime(2018, 1, 9, 1),
'FSD',
'https://mesonet.agron.iastate.edu/request/asos/1min_dl.php?'
'station%5B%5D=FSD&tz=UTC&year1=2018&month1=01&day1=05&hour1=01'
'&minute1=00&year2=2018&month2=01&day2=09&hour2=01&minute2=00&'
'vars%5B%5D=tmpf&vars%5B%5D=dwpf&vars%5B%5D=sknt&vars%5B%5D=drct&'
'sample=1min&what=view&delim=comma&gis=yes')
])
@patch('meteogram.meteogram.current_utc_time', new=mocked_current_utc_time)
def test_build_asos_request_url(start, end, station, expected):
"""
Test URL building for requests.
"""
# Setup - Done by parameterized fixture
# Exercise
url = meteogram.build_asos_request_url(station, start, end)
# Verify
assert url == expected
# Cleanup - none necessary
@pytest.mark.parametrize('start, end, station, expected', [
# Single Digit Datetimes
(datetime.datetime(2018, 1, 5, 1), datetime.datetime(2018, 1, 9, 1),
'FSD',
'https://mesonet.agron.iastate.edu/request/asos/1min_dl.php?'
'station%5B%5D=FSD&tz=UTC&year1=2018&month1=01&day1=05&hour1=01'
'&minute1=00&year2=2018&month2=01&day2=09&hour2=01&minute2=00&'
'vars%5B%5D=tmpf&vars%5B%5D=dwpf&vars%5B%5D=sknt&vars%5B%5D=drct&'
'sample=1min&what=view&delim=comma&gis=yes'),
# Double Digit Datetimes
(datetime.datetime(2018, 10, 11, 12), datetime.datetime(2018, 10, 16, 15),
'MLI',
'https://mesonet.agron.iastate.edu/request/asos/1min_dl.php?'
'station%5B%5D=MLI&tz=UTC&year1=2018&month1=10&day1=11&hour1=12'
'&minute1=00&year2=2018&month2=10&day2=16&hour2=15&minute2=00&'
'vars%5B%5D=tmpf&vars%5B%5D=dwpf&vars%5B%5D=sknt&vars%5B%5D=drct&'
'sample=1min&what=view&delim=comma&gis=yes'),
# Defaults
(None, None,
'MLI',
'https://mesonet.agron.iastate.edu/request/asos/1min_dl.php?'
'station%5B%5D=MLI&tz=UTC&year1=2018&month1=03&day1=25&hour1=12'
'&minute1=00&year2=2018&month2=03&day2=26&hour2=12&minute2=00&'
'vars%5B%5D=tmpf&vars%5B%5D=dwpf&vars%5B%5D=sknt&vars%5B%5D=drct'
'&sample=1min&what=view&delim=comma&gis=yes'),
# Default Start Only
(None, datetime.datetime(2019, 3, 25, 12),
'MLI',
'https://mesonet.agron.iastate.edu/request/asos/1min_dl.php?'
'station%5B%5D=MLI&tz=UTC&year1=2019&month1=03&day1=24&hour1=12'
'&minute1=00&year2=2019&month2=03&day2=25&hour2=12&minute2=00&'
'vars%5B%5D=tmpf&vars%5B%5D=dwpf&vars%5B%5D=sknt&vars%5B%5D=drct'
'&sample=1min&what=view&delim=comma&gis=yes'),
# Default End Only
(datetime.datetime(2018, 3, 24, 12), None,
'MLI',
'https://mesonet.agron.iastate.edu/request/asos/1min_dl.php?'
'station%5B%5D=MLI&tz=UTC&year1=2018&month1=03&day1=24&hour1=12'
'&minute1=00&year2=2018&month2=03&day2=26&hour2=12&minute2=00&'
'vars%5B%5D=tmpf&vars%5B%5D=dwpf&vars%5B%5D=sknt&vars%5B%5D=drct'
'&sample=1min&what=view&delim=comma&gis=yes')
])
@patch('meteogram.meteogram.current_utc_time', new=mocked_current_utc_time)
def test_build_asos_request_url(start, end, station, expected):
"""
Test URL building for requests.
"""
# Setup - Done by parameterized fixture
# Exercise
url = meteogram.build_asos_request_url(station, start, end)
# Verify
assert url == expected
# Cleanup - none necessary