Reputation: 1375
How can I test a pandas function with a mutable argument? The function works in the program and test as shown but returns the None
type in the test. It needs to test against the pandas DataFrame <class 'pandas.core.frame.DataFrame'>
.
Two similar questions don't help much with writing the assert
function:
Note: This is not a mutable default issue.
prog.py
import pandas as pd
def new_year(df):
df.Class += 1
# print(".", df)
df = pd.DataFrame({'Name':['Jack', 'Jill'], 'Class':[4, 5]})
new_year(df)
print(df)
(tst) E:\venv\tst>python prog.py
Name Class
0 Jack 5
1 Jill 6
test_prog.py
import unittest
import pandas as pd
from pandas._testing import assert_frame_equal
from prog import new_year
def test_new_year():
df1 = pd.DataFrame({'Name':['Jack', 'Jill'], 'Class':[4, 5]})
df2 = pd.DataFrame({'Name':['Jack', 'Jill'], 'Class':[5, 6]})
assert_frame_equal(new_year(df1), df2)
(tst) E:\venv\tst>pytest -vv tests
=================================================== test session starts ===================================================
platform win32 -- Python 3.9.0, pytest-6.2.4, py-1.10.0, pluggy-0.13.1 -- e:\venv\tst\scripts\python.exe
cachedir: .pytest_cache
rootdir: E:\venv\tst
collected 1 item
tests/test_prog.py::test_new_year FAILED [100%]
======================================================== FAILURES =========================================================
______________________________________________________ test_new_year ______________________________________________________
def test_new_year():
df1 = pd.DataFrame({'Name':['Jack', 'Jill'], 'Class':[4, 5]})
df2 = pd.DataFrame({'Name':['Jack', 'Jill'], 'Class':[5, 6]})
> assert_frame_equal(new_year(df1), df2)
tests\test_prog.py:9:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
left = None, right = Name Class
0 Jack 5
1 Jill 6, cls = <class 'pandas.core.frame.DataFrame'>
def _check_isinstance(left, right, cls):
"""
Helper method for our assert_* methods that ensures that
the two objects being compared have the right type before
proceeding with the comparison.
Parameters
----------
left : The first object being compared.
right : The second object being compared.
cls : The class type to check against.
Raises
------
AssertionError : Either `left` or `right` is not an instance of `cls`.
"""
cls_name = cls.__name__
if not isinstance(left, cls):
> raise AssertionError(
f"{cls_name} Expected type {cls}, found {type(left)} instead"
)
E AssertionError: DataFrame Expected type <class 'pandas.core.frame.DataFrame'>, found <class 'NoneType'> instead
lib\site-packages\pandas\_testing.py:508: AssertionError
================================================= short test summary info =================================================
FAILED tests/test_parse_methods.py::test_clean_date - AssertionError: DataFrame Expected type <class 'pandas.core.frame.D...
FAILED tests/test_prog.py::test_new_year - AssertionError: DataFrame Expected type <class 'pandas.core.frame.DataFrame'>,...
=============================================== 1 failed in 0.91s ===============================================
Upvotes: 1
Views: 252
Reputation: 18316
You can try return
ing the df
in the new_year
function:
def new_year(df):
df.Class += 1
return df
As it stands, the new_year
function has no explicit return
statement so it returns None
and hence the AssertionError
.
Upvotes: 1