我有一个在相当大的django项目上使用Pytest的工作测试套件。问题是我无法使用覆盖率获得正确的结果,我想知道是否可能是因为项目目录结构。
考虑目录树的以下示例:
.
├── apps
│ ├── api
│ │ ├── __init__.py
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ └── views
│ │ │ ├── __init__.py
│ │ │ └── test_tickets.py
│ │ └── views
│ │ ├── __init__.py
│ │ ├── tickets.py
│ ├── support
│ │ ├── __init__.py
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── test_management_commands.py
│ │ ├── utils
│ │ │ ├── __init__.py
│ │ │ ├── management_commands.py
覆盖率报告的示例输出:
coverage run --source apps/ -m py.test apps/
coverage report
Name Stmts Miss Cover
---------------------------------------------------------------
apps/api/views/tickets.py 42 18 57%
apps/support/utils/management_commands.py 135 100 26%
查看html报告我可以看到测试执行的许多语句都不被视为涵盖,即使它们应该被覆盖。我认为这个覆盖率数据不完整,似乎只考虑了所涵盖的进口,定义和文档字符串。
无法确定覆盖率出现错误的原因,我尝试运行单个测试模块,结果为正:
coverage run --source apps/support/utils/management_commands.py -m py.test apps/support/tests/utils/test_management_commands.py
coverage report
Name Stmts Miss Cover
---------------------------------------------------------------
apps/support/utils/management_commands.py 135 68 50%
这是更准确的,HTML报告显示我已经测试过的语句在这次显示为覆盖。无法弄清楚为什么运行单个测试模块会产生准确的结果,我通过在单个父文件夹下移动测试来修改目录结构。
.
├── apps
│ ├── api
│ │ ├── __init__.py
│ │ └── views
│ │ ├── __init__.py
│ │ ├── tickets.py
│ ├── support
│ │ ├── __init__.py
│ │ ├── utils
│ │ │ ├── __init__.py
│ │ │ ├── management_commands.py
├── tests
│ │ ├── __init__.py
│ ├── api
│ │ ├── __init__.py
│ │ └── views
│ │ ├── __init__.py
│ │ └── test_tickets.py
│ ├── support
│ │ ├── __init__.py
│ │ ├── utils
│ │ │ ├── __init__.py
│ │ │ ├── test_management_commands.py
使用此目录结构重新运行覆盖率会产生更准确的结果:
coverage run --source apps/ -m py.test tests/
coverage report
Name Stmts Miss Cover
---------------------------------------------------------------
apps/api/views/tickets.py 42 0 100%
apps/support/utils/management_commands.py 135 68 50%
任何人都可以解释为什么在原始目录结构下使用py.test运行覆盖完全覆盖?目录结构实际上是问题还是我在这里遗漏了其他东西?
其他信息:
# pytest.ini
[pytest]
addopts = --nomigrations
markers =
slowtest: mark a test as being slow
integration: mark a test as being an integration test
INSTALLED_APPS += ('django_coverage', )
TEST_DISCOVER_PATTERN = 'test_*'
COVERAGE_MODULE_EXCLUDES = [
'settings',
'urls$',
'locale$',
'tests$',
'django',
'migrations',
'compressor',
'templates?$',
'fixtures$',
'static$',
]
ROOT_PATH = os.path.abspath('%s/' % os.path.dirname(__file__))
.coveragerc
[run]
source = apps
omit =
apps/*/templates?/*
apps/*/migrations/*
apps/*/factories/*
apps/*/tests/*
[html]
directory = coverage
模块版本(有些可能不相关):
pytest==2.9.0
pytest-cov==2.2.1
pytest-django==2.9.1
django-coverage==1.2.4
coverage==4.0.3
答案 0 :(得分:0)
我看到我参加聚会有点晚了(有3年历史的问题,尚未得到公认的答案),但是由于我刚遇到过同样的question,而且看似明显的{{3} }:coverage
仅报告实际运行的代码。因此,如果您的测试不调用任何代码,并且在正常加载应用程序期间未运行该代码,则coverage
将不会显示该代码的报告。不运行的代码不会导致错误:)