您如何测试更复杂的功能?

时间:2018-08-23 14:36:16

标签: python pandas testing pytest

我是一个业余爱好者的综合开发人员,她试图了解有关测试所编写软件的更多信息。虽然我了解测试的核心概念,但是随着功能变得越来越复杂,我觉得这似乎是变化,结果,条件等的小洞。

下面的函数将文件从目录读取到Pandas DataFrame中。在将数据传递到最终将数据导入到我们的数据库的其他函数之前,需要进行几列调整。

我已经为convert_date_string函数编写了一个测试代码。但是整个功能如何呢?如何为它编写测试?在我看来,大多数Pandas库都已经过测试-因此确保那里的核心功能与我的设置一起使用似乎是一种浪费。但是,也许不是。或者,也许这是一个重构问题,可以将其分解为更小的部分?

无论如何,这是代码……任何见解将不胜感激!

def process_file(import_id=None):
    all_files = glob.glob(config.IMPORT_DIRECTORY + "*.txt")

    if len(all_files) == 0:
        return []

    import_data = (pd.read_csv(f, sep='~', encoding='latin-1',
                               warn_bad_lines=True, error_bad_lines=False,
                               low_memory=False) for f in all_files)

    data = pd.concat(import_data, ignore_index=True, sort=False)
    data.columns = [col.lower() for col in data.columns]
    data = data.where((pd.notnull(data)), None)

    data['import_id'] = import_id
    data['date'] = data['date'].apply(lambda x: convert_date_string(x))

    insert_data_into_database(data=data, table='sales')
    return all_files

2 个答案:

答案 0 :(得分:0)

通常,我不会去测试熊猫或任何其他依赖项。从我的角度来看,重要的是要确保我使用的程序包得到良好的开发和良好的支持,然后对其进行测试将是多余的。熊猫是一个非常受支持的软件包。

关于一般测试的特定功能和兴趣的问题,我强烈建议您检出Hypothesis python软件包(您很幸运-目前仅适用于python)。它提供模拟数据并生成用于测试目的的边缘案例。

他们的文档中的示例:

from hypothesis import given
from hypothesis.strategies import text

@given(text())
def test_decode_inverts_encode(s):
    assert decode(encode(s)) == s

在这里您告诉它该函数需要接收文本作为输入,并且程序包将使用不同的变量(满足条件)多次运行它。它还将尝试各种边缘情况。

实施后可以做的更多。

答案 1 :(得分:0)

主要有两种测试-适当的单元测试和集成测试。

单元测试,顾名思义,是独立测试程序(功能,类...)的“单元”(不考虑它们如何与其他单元交互)。当然,这需要 可以单独进行测试。例如,一个纯函数(从输入中计算结果的函数,其中结果仅取决于输入,并且对于相同的输入将始终相同,而没有任何输入副作用)非常容易测试,而从文件系统上的硬编码路径读取数据,向硬编码url发出http请求并更新数据库(其连接数据也经过硬编码)的功能几乎是不可能单独测试的(几乎无法测试)。

因此,第一点是编写具有可测试性的代码:优先考虑具有单一明确责任和尽可能少的依赖性的小型,重点突出的单元(最好将它们的依赖性作为参数,以便您可以通过模拟代替)。这当然是柏拉图式的理想,但这仍然是一个值得追求的目标。作为最后的选择,当您不能摆脱依赖关系或对其进行参数化时,可以使用mock之类的程序包,该程序包将使用具有类似接口的伪造对象替换您的依赖关系。

集成测试是从更高的级别测试整个子系统-例如,对于一个网站项目,您可能需要测试是否以电子邮件形式发送给指定地址的“联系人”表单以及数据是还存储在数据库中。您显然想要使用一次性测试数据库和一次性测试邮箱来完成此操作。

您发布的函数可能做的太多了-它读取文件,构建熊猫数据框,进行一些处理并将内容存储在数据库中。您可能需要尝试将其分解为更多功能-一个用于获取文件列表,一个用于从文件中收集数据,一个用于处理数据,等等,您已经有一个将数据存储在数据库中-然后重写“ process_files”(实际上比处理要做的更多)来调用这些函数。这样可以更容易地独立测试每个零件。完成此操作后,您可以使用mock测试“ process_file”函数,并检查其是否使用期望的参数调用其他函数,或者针对测试目录和测试数据库运行该函数,并检查测试结果。数据库。