Pytest:如何在失败时对Pandas DataFrame进行快照测试

jv4diomz  于 2023-05-21  发布在  其他
关注(0)|答案(1)|浏览(165)

我有两个 Dataframe :

  • df1:它来自一个csv文件,并且已经通过删除不需要的数据进行了清理。
  • df2:它是来自先前成功结果的经验证的 Dataframe 。我们将其保存到一个文件中,并在测试时将其加载回来。

现在我们写一个测试:

import pandas as pd

def test_data_cleaning_process():
    df1 = pd.read_csv('df1.csv')
    df2 = pd.read_csv('df2.csv')
    # execute target function
    df1 = cleanup(df1)

    # compare dfs
    assert df1.equals(df2)

只要我们通过测试就可以了。当测试失败时,控制台输出很难找出不匹配的数据。
举个例子

def test_for_failure():
    import pandas as pd
    data1 = {
        'A': [1,2,3,4],
        'B': [1,2,3,4],
        'C': [1,2,3,4],
        'D': [1,2,3,4],
        'E': [1,2,3,4],
        'F': [1,2,3,4],
        'G': [1,2,3,4],
    }
    data2 = {
        'A': [1,2,3,4],
        'B': [1,2,3,9], # We change 4 to 9 for failure
        'C': [1,2,3,4],
        'D': [1,2,3,4],
        'E': [1,2,3,4],
        'F': [1,2,3,4],
        'G': [1,2,3,4],
    }
    df1 = pd.DataFrame(data1)
    df2 = pd.DataFrame(data2)

    assert df1.equals(df2)

pytest的控制台输出:

...
        df1 = pd.DataFrame(data1)
        df2 = pd.DataFrame(data2)
    
>       assert df1.equals(df2)
E       assert False
E        +  where False = <bound method NDFrame.equals of    A  B  C  D  E  F  G\n0  1  1  1  1  1  1  1\n1  2  2  2  2  2  2  2\n2  3  3  3  3  3  3  3\n3  4  4  4  4  4  4  4>(   A  B  C  D  E  F  G\n0  1  1  1  1  1  1  1\n1  2  2  2  2  2  2  2\n2  3  3  3  3  3  3  3\n3  4  9  4  4  4  4  4)
E        +    where <bound method NDFrame.equals of    A  B  C  D  E  F  G\n0  1  1  1  1  1  1  1\n1  2  2  2  2  2  2  2\n2  3  3  3  3  3  3  3\n3  4  4  4  4  4  4  4> =    A  B  C  D  E  F  G\n0  1  1  1  1  1  1  1\n1  2  2  2  2  2  2  2\n2  3  3  3  3  3  3  3\n3  4  4  4  4  4  4  4.equals

Dataframe :

# df1
    A   B   C   D   E   F   G
0   1   1   1   1   1   1   1
1   2   2   2   2   2   2   2
2   3   3   3   3   3   3   3
3   4   4   4   4   4   4   4
# df2
    A   B   C   D   E   F   G
0   1   1   1   1   1   1   1
1   2   2   2   2   2   2   2
2   3   3   3   3   3   3   3
3   4   9   4   4   4   4   4

只有一行是不匹配的,但是当 Dataframe 很大时,pytest会打印出失败案例的无用信息。

常见问题

1.如何在失败时只打印出不匹配的行(本例中为行索引3)?或者生成一个比较文件以供查看。
1.是否有任何工具可以让我覆盖到快照文件,即使它失败了当前的数据?
1.测试清理过程以确保重构不会改变结果的最佳实践是什么?

dnph8jn4

dnph8jn41#

使用pandas.testing.assert_frame_equal编写pandas Dataframe 测试,如下所示

df1 = pd.DataFrame(data1)
df2 = pd.DataFrame(data2)

assert_frame_equal(df1, df2)

它可以通过索引以及两个 Dataframe 中不匹配的内容来进行更清晰的追溯

AssertionError:

DataFrame.iloc[:, 1] (column name="B") values are different (25.0 %)
[index]: [0, 1, 2, 3]
[left]:  [1, 2, 3, 4] 
[right]: [1, 2, 3, 9]

相关问题