代码之家  ›  专栏  ›  技术社区  ›  Anthon

如何使用tox+pytest启用deprecationwarning和pendingdeprecationwarning的测试

  •  1
  • Anthon  · 技术社区  · 6 年前

    多年来我一直在测试 ruamel.yaml 具有 tox pytest 对多个版本的python进行定期更新。在第一个python 3.7beta发布后不久,我就加入了它,并在发布时升级了针对3.7版本的测试。不过,我仍然在使用python 3.6(必要时使用2.7)完成大部分日常工作。

    因此,我很惊讶在bitbucket上记录了一个问题,因为 DeprecationWarning 因为 卢米尔 仍在从 collections python 2.x方式(从3.8开始 从…进口 collections.abc ,他们已经住在那里)。我本以为 托克斯 运行,这是我的工具链中强制的先决条件,可以将新版本推送到pypi中,几个月前就发现了这一点。

    从命令行中,您可以看到警告,例如,当您执行以下操作时:

    python3.7 -W always -c "import ruamel.yaml"
    

    经过研究,我补充道:

    [pytest]
    filterwarnings =
        error::DeprecationWarning
        error::PendingDeprecationWarning
    

    对我 tox.ini ,但未更改目标的测试结果 py37 (321次传球/2次跳过/7次传球)。

    然后我补充道:

    塞滕夫 pythonwarnings=错误

    默认值( [testenv] )目标。这使测试结果发生了一些有趣的变化,因为在 托克斯 / 脓包 / virtualenv 工具链本身。

    我手工修复了那些(打算在清理后自动完成 tox -r 运行),看看这样做是否至少会导致 卢米尔 它本身,但它没有。如果你加上:

    setenv =
        PYTHONWARNINGS=always::DeprecationWarning
    

    [特斯滕夫] 您将看到工具链具有:

    deprecationwarning:“u”模式已弃用
    deprecationwarning:imp模块已弃用,取而代之的是importlib
    不推荐警告:不推荐使用“collections.abc”,而是从“collections.abc”中使用或导入abc,在3.8中它将停止工作

    最后一个实际上是我要找的,但是那些错误是因为tox依赖pyparsing中的代码…

    然后我新文件 test_import.py 一次测试:

    def test_import():
        from ruamel.yaml
    

    再检查一遍 托克斯 执行测试(322个测试通过), 但不显示任何消息或警告 ,即使添加 -ra 脓包 .

    我一直在期待 托克斯 帮助我在早期找到贬义词,但实际上似乎根本不可能让它们触发。我当然可以添加上面所示的命令行,作为 毒素Ⅰ . 但有些抨击可能不会那么容易触发,我不想重复我的测试工作,只是为了捕捉潜在的抨击。

    我怎么能触发 弃用警告 在我的代码中使用 托克斯 ?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Anthon    6 年前

    如果你从一个最小的开始 test_one.py

    def test_one():
        from collections import Hashable
    

    简单的 setup.py :

    from setuptools import setup, find_packages
    
    if __name__ == '__main__':
        setup(
            name="depwarntest",
            version="0.0.1",
            description="test to get DeprecationWarning in code on 3.7",
            long_description = "more details soon",
            author_email="a.van.der.neut@ruamel.eu",
            author="Anthon van der Neut",
            license="MIT",
            url="",
            packages=find_packages(),
        )
    

    一个基本 tox.ini :

    [tox]
    envlist = py37,py36,py27
    
    [testenv]
    commands =
        /bin/bash -c 'pytest test_*.py'
    deps =
        pytest
    
    [pytest]
    filterwarnings =
        error::DeprecationWarning
        error::PendingDeprecationWarning
    

    并运行 tox ,您将得到一个很好的干净异常,因为 import :

    ==================================================================================== FAILURES =====================================================================================
    ____________________________________________________________________________________ test_one _____________________________________________________________________________________
    
        def test_one():
    >       from collections import Hashable
    
    test_one.py:6: 
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    <frozen importlib._bootstrap>:1032: in _handle_fromlist
        ???
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    
    name = 'Hashable'
    
        def __getattr__(name):
            # For backwards compatibility, continue to make the collections ABCs
            # through Python 3.6 available through the collections module.
            # Note, no new collections ABCs were added in Python 3.7
            if name in _collections_abc.__all__:
                obj = getattr(_collections_abc, name)
                import warnings
                warnings.warn("Using or importing the ABCs from 'collections' instead "
                              "of from 'collections.abc' is deprecated, "
                              "and in 3.8 it will stop working",
    >                         DeprecationWarning, stacklevel=2)
    E           DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
    
    .tox/py37/lib/python3.7/collections/__init__.py:52: DeprecationWarning
    ============================================================================ 1 failed in 0.31 seconds =============================================================================
    

    py37 py36 py27 运行良好。

    有趣的是,如果将测试文件更改为

    from collections import Hashable    
    
    def test_one():
        from collections import Hashable
    

    运行 托克斯 会很顺利的 PY37 也。 如果将模块级导入移到另一个 test_XYZ.py 文件 .

    为了 ruamel.yaml 这意味着所有的模块级导入 卢米尔 在测试文件中需要移动到方法/函数;测试中依赖于 ruamel.yaml.YAML() 需要使用生成器;并且模块级 yaml_object() 也需要用特殊的方式来处理。

    额外的 托克斯 target通过进行一致性测试来帮助测试逐步移动:

    # deprecation warning fail
    [testenv:dwf]
    basepython = python3.7
    commands =
        /bin/sed 's/collections.abc/collections/' -i .tox/dwf/lib/python3.7/site-packages/ruamel/yaml/comments.py
        /bin/bash -c 'pytest --maxfail=2 _test/test_[a-cz]*.py'
    

    这里是已经更正的来源 comments.py 恢复,仅对已调整的模块进行测试。 ted -e py37,dwf 应通过第一个(再次通过321个测试)并在第二个目标上失败。