python单元测试结构-如何使用多个软件包和多个测试文件更好地构建项目?

时间:2018-07-25 17:42:50

标签: python unit-testing

我做了一些研究,似乎许多带有测试的python项目的结构如下:

my_project:
    - package_1
       - my_package_1_class_1.py
       - my_package_1_class_2.py
       - my_package_1_class_3.py

    - package_2
       - my_package_2_class_1.py
       - my_package_2_class_2.py
       - my_package_2_class_3.py
       - my_package_2_class_4.py

    - package_3
       - my_package_3_class_1.py
       - my_package_3_class_2.py

    - test
       - test_my_package_1_class_1.py
       - test_my_package_1_class_2.py
       - test_my_package_1_class_3.py
       - test_my_package_2_class_1.py
       - test_my_package_2_class_2.py
       - test_my_package_2_class_3.py
       - test_my_package_2_class_4.py
       - test_my_package_3_class_1.py
       - test_my_package_3_class_2.py

所有程序包的测试文件都位于同一测试文件夹中。这与普通的Java结构有所不同,后者的每个软件包都有一个对应的文件夹用于自己的测试。

当我们尝试将来自不同软件包的大量测试文件放到同一测试文件夹中时,我感到这个python结构变得混乱了。

经验丰富的python架构/程序员将如何使用许多软件包和测试文件来构建其项目?谢谢!

1 个答案:

答案 0 :(得分:0)

从一般(独立于语言)的角度来看,当涉及到将测试文件放在程序包结构中的位置这一问题时,我看到两个主要标准:

  1. 在生产代码和测试代码之间保持明确的障碍:应将生产代码与测试代码分开。对于某些类型的软件,这不仅是一项建议,而且是一个严格的要求(例如,在安全关键软件中)-即使生产代码中的测试代码将是无效代码或无法访问。但是,在设计测试时,明确的障碍也可能是有利的:分离有助于首先关注公共API上的测试。而且,有时您希望将生产代码交付给客户,而不是单元测试代码,反之亦然(取决于合同)。显然,这是更容易实现的,将更多的生产代码和测试代码分开。

  2. 生产代码和相关测试代码之间的相互可追溯性:将生产代码和测试代码一起版本化时,可追溯性很容易实现。然后,对存储库的典型提交可能包含生产代码更改和测试的相关更改。在这里将生产代码和测试放在不同的项目中将是一个缺点-除非您能以某种方式确保两个相关项目的版本都是一致的,以便始终清楚哪些版本属于同一版本。如果必须手动确保,则可能会失败。

您显示的解决方案显然支持标准1,但是将测试与它们各自的程序包分开可以使满足标准2的难度更大。对于Python,我发现将测试放入子包中的选项更具吸引力。例如参见https://python-packaging.readthedocs.io/en/latest/testing.html

project/
    package_1/
        __init__.py
        package_1_class_1.py
        package_1_class_2.py
        package_1_class_3.py
        tests/
            __init__.py
            test_package_1_class_1.py
            test_package_1_class_2.py
            test_package_1_class_3.py
    package_2/
        package_2_class_1.py
        package_2_class_2.py
        package_2_class_3.py
        package_2_class_4.py
        tests/
            __init__.py
            test_package_2_class_1.py
            test_package_2_class_2.py
            test_package_2_class_3.py
            test_package_2_class_4.py
    package_3/
        __init__.py
        package_3_class_1.py
        package_3_class_2.py
        tests/
            __init__.py
            test_package_3_class_1.py
            test_package_3_class_2.py
    setup.py
    ...

例如,这使您以后可以轻松地在不同项目中重用各个软件包,包括它们的测试:软件包的所有内容都在同一目录结构中。