Package: pytest-compare
pytest-comparexWhat is it?Thepytest-comparehelps validate method call arguments when testing python code.pytest-compareis designed to work withassert methods. While python native variables can be easily compared, a more complicated structures sometimes do not. For example validating apd.DataFramewill raise an exception. This is wherepytest-comparecomes in. It allows this kind of structures to be easily compared.How to installTo installpytest-comparefrom PyPi, run the command:pipinstallpytest-compareOptional dependenciesSome compare modules may require additional packages to be installed.PandasTo comparepandasmodule, add thepandasoption to the installation:pipinstallpytest-compare[pandas]How to useThe comparation modules are design to be used withassert methods. When validating patched method call argumentsdf=pd.DataFrame({"a":[1,2,3],"b":[4,5,6]})withpatch.object(ProductionClass,'method',return_value=None)asmock_method:thing=ProductionClass()thing.method(df)# will raise an exceptionmock_method.assert_called_once_with(df)# the correct waymock_method.assert_called_once_with(CompareDataFrame(df))Multiple arguments in a callWhen a method is called using multiple arguments, all of them must be addressed in the test. while python native variables can be easily compared,pytest-compareis designed to compare a more complicated structures and do custom compares.withpatch.object(ProductionClass,'method',return_value=None)asmock_method:thing=ProductionClass()thing.method(1,"str",df1,df2)# the correct waymock_method.assert_called_once_with(1,"str",CompareDataFrame(df1),CompareDataFrame(df2))Args and KwargsWhen validating the call, the expected values must be passed in the exact same mix of args and kwargs as when they were called.withpatch.object(ProductionClass,'method',return_value=None)asmock_method:thing=ProductionClass()thing.method(df1,dataframe=df2)# the correct waymock_method.assert_called_once_with(CompareDataFrame(df1),dataframe=CompareDataFrame(df2))Actual and Expected conventionactual: The values that the method was originally called with.expected: Test values to see if the method was called with.For example here,arg_actualis the actual value whilearg_expectedis the expected value.mock_method=Mock()mock_method(arg_actual)mock_method.assert_called_once_with(arg_expected)Ifarg_actualis not equal toarg_expected, an exception will be raised.DevelopmentSetupVirtual EnvironmentCreate a virtual environment and install the dependencies:$ python3 -m venv venv
$ source venv/bin/activate
$ pip install -e ".[pandas]" -r requirements-dev.txt -r requirements-quality.txtPre-commit HooksStart by installing the pre-commit hooks which will runblack,mypy,flake8, andcodespellon every commit.:$ hooks/autohook.sh installCreating testsRunning testsTo test the code, run the following command:$ pytestWriting testsTests are written using thepytestframework. To create a test for a newComparemodule, create two files in thetestsdirectory:conftest.pyand the test file witch must start withtest_.
Theconftest.pyfile must implement the following fixtures:@pytest.fixturedefactual_call_args()->Tuple[Any]:raiseNotImplementedError("`actual_call_args` must be implemented")@pytest.fixturedefactual_call_kwargs()->Dict[str,Any]:raiseNotImplementedError("`actual_call_kwargs` must be implemented")@pytest.fixturedefexpected_call_args()->Tuple[Any]:raiseNotImplementedError("`expected_call_args` must be implemented")@pytest.fixturedefexpected_call_kwargs()->Dict[str,CompareBase]:raiseNotImplementedError("`expected_call_kwargs` must be implemented")The test file must implement a test class that inherits fromBaseTest.That way two base tests will be run for eachComparemodule that wil test theargsandkwargsof the method call.