'python setup.py nosetests'报告包的__init__.py未被测试覆盖

时间:2012-07-01 02:14:17

标签: python code-coverage nose coverage.py

当我使用python setup.py nosetests测试https://bitbucket.org/petar/beam_integrals时,我得到 96%的覆盖率

----------------------------------------------------------------------
XML: nosetests.xml
Name                                             Stmts   Miss  Cover   Missing
------------------------------------------------------------------------------
beam_integrals                                       7      7     0%   1-24
beam_integrals.beam_types                           79      0   100%
beam_integrals.characteristic_equation_solvers      65      0   100%
beam_integrals.exceptions                            6      0   100%
beam_integrals.utils                                14      0   100%
------------------------------------------------------------------------------
TOTAL                                              171      7    96%
----------------------------------------------------------------------
Ran 634 tests in 178.245s

OK (SKIP=3)

但是,如果我使用nosetests测试相同的代码,我会完全覆盖

----------------------------------------------------------------------
XML: nosetests.xml
Name                                             Stmts   Miss  Cover   Missing
------------------------------------------------------------------------------
beam_integrals                                       7      0   100%
beam_integrals.beam_types                           79      0   100%
beam_integrals.characteristic_equation_solvers      65      0   100%
beam_integrals.exceptions                            6      0   100%
beam_integrals.utils                                14      0   100%
------------------------------------------------------------------------------
TOTAL                                              171      0   100%
----------------------------------------------------------------------
Ran 634 tests in 179.226s

OK (SKIP=3)

似乎python setup.py nosetests没有正确报告beam_integrals模块的测试覆盖率。

此问题已经过验证:

  1. 我们的continuous integration server正在运行的Ubuntu 10.04服务器32位
  2. 运行Ubuntu 12.04 Server 64bit的新创建的Rackspace Cloud Server,具有以下设置:

    $ sudo aptitude update
    $ sudo aptitude upgrade
    $ sudo reboot
    
    $ sudo aptitude install python-pip mercurial git-core python-gmpy python-dev
    $ hg clone https://bitbucket.org/petar/beam_integrals
    $ sudo pip install -r beam_integrals/requirements.txt
    $ sudo pip install -r beam_integrals/requirements-test.txt
    
    $ cd beam_integrals
    $ python setup.py nosetests
    $ nosetests
    

2 个答案:

答案 0 :(得分:4)

python setup.py nosetests在开始覆盖测试之前导入beam_integrals,因此在覆盖测量发生时已经导入了它。这是因为你的setup.py直接导入beam_integrals。这不是一件坏事,很多Python项目都是为了从代码本身获取版本信息而不是在setup.py中复制它。

当您使用nosetests时,它知道在导入任何内容之前开始覆盖测量。实际上,它可能会导入东西,无需输入,开始覆盖,然后运行代码,再次导入内容。

除了使用nosetests来运行测试之外,我不确定你能做些什么。

答案 1 :(得分:1)

要完成Ned的答案,我知道两种解决问题的方法,可以避免重复文件中的版本。

  1. 导入模块后从sys.modules中删除模块

    import beam_integrals
    for mod in [m for m in sys.modules.keys() if m.startswith('beam_integrals')]:
        del sys.modules[mod]
    

    覆盖率报告现在将包含所有文件 但是,在您的情况下,仍然需要安装sympy 这就是我转向下一个解决方案的原因。

  2. 读取模块版本而不导入它:

    def get_version():
        with open('beam_integrals/__init__.py') as f:
            for line in f:
                if line.startswith('__version__'):
                    return eval(line.split('=')[-1])
    
    setup(
        name='beam_integrals',
        version=get_version(),
    

    我在这里看到了这个:https://github.com/PyCQA/pycodestyle/blob/2.3.1/setup.py