From d2430aba9846d91bc93273b320ead5022836e1ce Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Tue, 20 Nov 2018 16:22:03 -0700 Subject: [PATCH 1/2] test compat with pytest 4.0. minor clean up --- docs/sphinx/source/whatsnew/v0.6.1.rst | 1 + pvlib/test/test_clearsky.py | 8 ++-- pvlib/test/test_forecast.py | 21 ++++------- pvlib/test/test_irradiance.py | 5 +-- pvlib/test/test_modelchain.py | 14 ++++--- pvlib/test/test_singlediode.py | 26 ++++++++----- pvlib/test/test_solarposition.py | 51 ++++++++++++++------------ 7 files changed, 66 insertions(+), 60 deletions(-) diff --git a/docs/sphinx/source/whatsnew/v0.6.1.rst b/docs/sphinx/source/whatsnew/v0.6.1.rst index e53c374d3a..8bce89ac3f 100644 --- a/docs/sphinx/source/whatsnew/v0.6.1.rst +++ b/docs/sphinx/source/whatsnew/v0.6.1.rst @@ -55,6 +55,7 @@ Bug fixes Testing ~~~~~~~ * Add test for :func:`~pvlib.solarposition.hour_angle` (:issue:`597`) +* Update tests to be compatible with pytest 4.0. (:issue:`623`) Contributors diff --git a/pvlib/test/test_clearsky.py b/pvlib/test/test_clearsky.py index 34ff2c5166..39aa431046 100644 --- a/pvlib/test/test_clearsky.py +++ b/pvlib/test/test_clearsky.py @@ -279,8 +279,8 @@ def test_haurwitz(): 487.894132885425, 778.766689344363, 1035.09203253450]), - columns=['ghi'], - index=apparent_solar_zenith) + columns=['ghi'], + index=apparent_solar_zenith) out = clearsky.haurwitz(data_in['apparent_zenith']) assert_frame_equal(expected, out) @@ -293,7 +293,7 @@ def test_simplified_solis_scalar_elevation(): out = clearsky.simplified_solis(80) for k, v in expected.items(): - yield assert_allclose, expected[k], out[k] + assert_allclose(expected[k], out[k]) def test_simplified_solis_scalar_neg_elevation(): @@ -304,7 +304,7 @@ def test_simplified_solis_scalar_neg_elevation(): out = clearsky.simplified_solis(-10) for k, v in expected.items(): - yield assert_allclose, expected[k], out[k] + assert_allclose(expected[k], out[k]) def test_simplified_solis_series_elevation(): diff --git a/pvlib/test/test_forecast.py b/pvlib/test/test_forecast.py index d336f574ca..a1ccde870a 100644 --- a/pvlib/test/test_forecast.py +++ b/pvlib/test/test_forecast.py @@ -1,10 +1,7 @@ from datetime import datetime, timedelta -import inspect -from math import isnan from pytz import timezone import warnings -import numpy as np import pandas as pd import pytest @@ -14,13 +11,8 @@ pytestmark = pytest.mark.skipif(not has_siphon, reason='requires siphon') -from pvlib.location import Location if has_siphon: - import requests - from requests.exceptions import HTTPError - from xml.etree.ElementTree import ParseError - from pvlib.forecast import GFS, HRRR_ESRL, HRRR, NAM, NDFD, RAP # setup times and location to be tested. Tucson, AZ @@ -31,15 +23,16 @@ _end = _start + pd.Timedelta(days=1) _modelclasses = [ GFS, NAM, HRRR, NDFD, RAP, - skip_windows( - pytest.mark.xfail( - pytest.mark.timeout(HRRR_ESRL, timeout=60), - reason="HRRR_ESRL is unreliable"))] + pytest.param( + HRRR_ESRL, marks=[ + skip_windows, + pytest.mark.xfail(reason="HRRR_ESRL is unreliable"), + pytest.mark.timeout(HRRR_ESRL, timeout=60)])] _working_models = [] _variables = ['temp_air', 'wind_speed', 'total_clouds', 'low_clouds', - 'mid_clouds', 'high_clouds', 'dni', 'dhi', 'ghi',] + 'mid_clouds', 'high_clouds', 'dni', 'dhi', 'ghi'] _nonnan_variables = ['temp_air', 'wind_speed', 'total_clouds', 'dni', - 'dhi', 'ghi',] + 'dhi', 'ghi'] else: _modelclasses = [] diff --git a/pvlib/test/test_irradiance.py b/pvlib/test/test_irradiance.py index 43e4d531de..5bde6a262a 100644 --- a/pvlib/test/test_irradiance.py +++ b/pvlib/test/test_irradiance.py @@ -10,9 +10,8 @@ from pandas.util.testing import assert_frame_equal, assert_series_equal -from pvlib import atmosphere, irradiance, solarposition +from pvlib import irradiance from pvlib._deprecation import pvlibDeprecationWarning -from pvlib.location import Location from conftest import (fail_on_pvlib_version, needs_numpy_1_10, pandas_0_22, requires_ephem, requires_numba) @@ -102,7 +101,7 @@ def test_deprecated_07(): (timestamp, value) ]) @pytest.mark.parametrize('method', [ - 'asce', 'spencer', 'nrel', requires_ephem('pyephem')]) + 'asce', 'spencer', 'nrel', pytest.param('pyephem', marks=requires_ephem)]) def test_get_extra_radiation(input, expected, method): out = irradiance.get_extra_radiation(input) assert_allclose(out, expected, atol=1) diff --git a/pvlib/test/test_modelchain.py b/pvlib/test/test_modelchain.py index 703c3879b2..be7b331223 100644 --- a/pvlib/test/test_modelchain.py +++ b/pvlib/test/test_modelchain.py @@ -55,9 +55,9 @@ def cec_dc_snl_ac_system(sam_data): @pytest.fixture -def pvsyst_dc_snl_ac_system(sam_data): +def pvsyst_dc_snl_ac_system(sam_data, pvsyst_module_params): module = 'PVsyst test module' - module_parameters = pvsyst_module_params() + module_parameters = pvsyst_module_params module_parameters['b'] = 0.05 inverters = sam_data['cecinverter'] inverter = inverters['ABB__MICRO_0_25_I_OUTD_US_208_208V__CEC_2014_'].copy() @@ -446,12 +446,16 @@ def test_bad_get_orientation(): @fail_on_pvlib_version('0.7') def test_deprecated_07(): # explicit system creation call because fail_on_pvlib_version - # does not support decorators - system = cec_dc_snl_ac_system(sam_data()) + # does not support decorators. + # does not matter what the parameters are, just fake it until we make it + module_parameters = {'R_sh_ref': 1, 'a_ref': 1, 'I_o_ref': 1, + 'alpha_sc': 1, 'I_L_ref': 1, 'R_s': 1} + system = PVSystem(module_parameters=module_parameters) with pytest.warns(pvlibDeprecationWarning): mc = ModelChain(system, location, dc_model='singlediode', # this should fail after 0.7 - aoi_model='no_loss', spectral_model='no_loss') + aoi_model='no_loss', spectral_model='no_loss', + ac_model='snlinverter') @requires_scipy diff --git a/pvlib/test/test_singlediode.py b/pvlib/test/test_singlediode.py index 3d659eb450..4ff7bc445f 100644 --- a/pvlib/test/test_singlediode.py +++ b/pvlib/test/test_singlediode.py @@ -129,8 +129,7 @@ def test_brentq_fs_495(): return isc, voc, imp, vmp, pmp, i, v, pvs -@pytest.fixture -def pvsyst_fs_495(): +def get_pvsyst_fs_495(): """ PVsyst parameters for First Solar FS-495 module from PVSyst-6.7.2 database. @@ -156,16 +155,23 @@ def pvsyst_fs_495(): @pytest.mark.parametrize( - 'poa, temp_cell, expected, tol', - [(pvsyst_fs_495()['irrad_ref'], pvsyst_fs_495()['temp_ref'], - {'pmp': pvsyst_fs_495()['I_mp_ref'] * pvsyst_fs_495()['V_mp_ref'], - 'isc': pvsyst_fs_495()['I_sc_ref'], 'voc': pvsyst_fs_495()['V_oc_ref']}, - (5e-4, 0.04)), - (POA, TCELL, {'pmp': 76.26, 'isc': 1.387, 'voc': 79.29}, (1e-3, 1e-3))] + 'poa, temp_cell, expected, tol', [ + ( + get_pvsyst_fs_495()['irrad_ref'], + get_pvsyst_fs_495()['temp_ref'], + { + 'pmp': (get_pvsyst_fs_495()['I_mp_ref'] * + get_pvsyst_fs_495()['V_mp_ref']), + 'isc': get_pvsyst_fs_495()['I_sc_ref'], + 'voc': get_pvsyst_fs_495()['V_oc_ref'] + }, + (5e-4, 0.04) + ), + (POA, TCELL, {'pmp': 76.26, 'isc': 1.387, 'voc': 79.29}, (1e-3, 1e-3))] ) # DeSoto @(888[W/m**2], 55[degC]) = {Pmp: 72.71, Isc: 1.402, Voc: 75.42) -def test_pvsyst_recombination_loss(pvsyst_fs_495, poa, temp_cell, expected, - tol): +def test_pvsyst_recombination_loss(poa, temp_cell, expected, tol): """test PVSst recombination loss""" + pvsyst_fs_495 = get_pvsyst_fs_495() # first evaluate PVSyst model with thin-film recombination loss current # at reference conditions x = pvsystem.calcparams_pvsyst( diff --git a/pvlib/test/test_solarposition.py b/pvlib/test/test_solarposition.py index 481f2fde7d..82818fd56e 100644 --- a/pvlib/test/test_solarposition.py +++ b/pvlib/test/test_solarposition.py @@ -39,6 +39,12 @@ def golden_mst(): @pytest.fixture() def expected_solpos(): + return _expected_solpos_df() + + +# hack to make tests work without too much modification while avoiding +# pytest 4.0 inability to call features directly +def _expected_solpos_df(): return pd.DataFrame({'elevation': 39.872046, 'apparent_zenith': 50.111622, 'azimuth': 194.340241, @@ -483,15 +489,14 @@ def test_get_solarposition_error(golden): method='error this') -@pytest.mark.parametrize( - "pressure, expected", [ - (82000, expected_solpos()), +@pytest.mark.parametrize("pressure, expected", [ + (82000, _expected_solpos_df()), (90000, pd.DataFrame( np.array([[ 39.88997, 50.11003, 194.34024, 39.87205, 14.64151, 50.12795]]), - columns=['apparent_elevation', 'apparent_zenith', 'azimuth', 'elevation', - 'equation_of_time', 'zenith'], - index=expected_solpos().index)) + columns=['apparent_elevation', 'apparent_zenith', 'azimuth', + 'elevation', 'equation_of_time', 'zenith'], + index=['2003-10-17T12:30:30Z'])) ]) def test_get_solarposition_pressure(pressure, expected, golden): times = pd.date_range(datetime.datetime(2003,10,17,13,30,30), @@ -507,15 +512,14 @@ def test_get_solarposition_pressure(pressure, expected, golden): assert_frame_equal(this_expected, ephem_data[this_expected.columns]) -@pytest.mark.parametrize( - "altitude, expected", - [(golden().altitude, expected_solpos()), +@pytest.mark.parametrize("altitude, expected", [ + (1830.14, _expected_solpos_df()), (2000, pd.DataFrame( np.array([[ 39.88788, 50.11212, 194.34024, 39.87205, 14.64151, 50.12795]]), columns=['apparent_elevation', 'apparent_zenith', 'azimuth', 'elevation', 'equation_of_time', 'zenith'], - index=expected_solpos().index)) + index=['2003-10-17T12:30:30Z'])) ]) def test_get_solarposition_altitude(altitude, expected, golden): times = pd.date_range(datetime.datetime(2003,10,17,13,30,30), @@ -531,17 +535,18 @@ def test_get_solarposition_altitude(altitude, expected, golden): assert_frame_equal(this_expected, ephem_data[this_expected.columns]) -@pytest.mark.parametrize( - "delta_t, method, expected", [ - (None, 'nrel_numpy', expected_solpos_multi()), - (67.0, 'nrel_numpy', expected_solpos_multi()), - pytest.mark.xfail( +@pytest.mark.parametrize("delta_t, method", [ + (None, 'nrel_numpy'), + (67.0, 'nrel_numpy'), + pytest.param( + None, 'nrel_numba', + marks=[pytest.mark.xfail( raises=ValueError, - reason='spa.calculate_deltat not implemented for numba yet') - ((None, 'nrel_numba', expected_solpos_multi())), - (67.0, 'nrel_numba', expected_solpos_multi()) + reason='spa.calculate_deltat not implemented for numba yet')]), + (67.0, 'nrel_numba') ]) -def test_get_solarposition_deltat(delta_t, method, expected, golden): +def test_get_solarposition_deltat(delta_t, method, expected_solpos_multi, + golden): times = pd.date_range(datetime.datetime(2003,10,17,13,30,30), periods=2, freq='D', tz=golden.tz) ephem_data = solarposition.get_solarposition(times, golden.latitude, @@ -550,7 +555,7 @@ def test_get_solarposition_deltat(delta_t, method, expected, golden): delta_t=delta_t, temperature=11, method=method) - this_expected = expected.copy() + this_expected = expected_solpos_multi this_expected.index = times this_expected = np.round(this_expected, 5) ephem_data = np.round(ephem_data, 5) @@ -673,10 +678,8 @@ def test_analytical_azimuth(): decl, zenith) idx = np.where(solar_zenith < np.pi/2) - assert np.allclose(azimuth_1[idx], solar_azimuth.as_matrix()[idx], - atol=0.01) - assert np.allclose(azimuth_2[idx], solar_azimuth.as_matrix()[idx], - atol=0.017) + assert np.allclose(azimuth_1[idx], solar_azimuth.values[idx], atol=0.01) + assert np.allclose(azimuth_2[idx], solar_azimuth.values[idx], atol=0.017) # test for NaN values at boundary conditions (PR #431) test_angles = np.radians(np.array( From 801414a9886d89c62960d8480a253a7331c7aec8 Mon Sep 17 00:00:00 2001 From: Will Holmgren Date: Tue, 20 Nov 2018 16:40:40 -0700 Subject: [PATCH 2/2] fix timeout args --- pvlib/test/test_forecast.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pvlib/test/test_forecast.py b/pvlib/test/test_forecast.py index a1ccde870a..622e007a4c 100644 --- a/pvlib/test/test_forecast.py +++ b/pvlib/test/test_forecast.py @@ -27,7 +27,7 @@ HRRR_ESRL, marks=[ skip_windows, pytest.mark.xfail(reason="HRRR_ESRL is unreliable"), - pytest.mark.timeout(HRRR_ESRL, timeout=60)])] + pytest.mark.timeout(timeout=60)])] _working_models = [] _variables = ['temp_air', 'wind_speed', 'total_clouds', 'low_clouds', 'mid_clouds', 'high_clouds', 'dni', 'dhi', 'ghi']