我正在为一个项目编写集成测试,我正在进行HTTP调用并测试它们是否成功。
由于我没有导入任何模块而没有直接调用函数,因此coverage.py报告为0%。
我想知道如何为此类集成HTTP请求测试生成覆盖率报告?
答案 0 :(得分:5)
配方就是这样:
示例:
想象一下,你有一个虚拟的后端服务器,它响应了一个" Hello World"关于GET请求的页面:
# backend.py
from http.server import BaseHTTPRequestHandler, HTTPServer
class DummyHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.end_headers()
self.wfile.write('<html><body><h1>Hello World</h1></body></html>'.encode())
if __name__ == '__main__':
HTTPServer(('127.0.0.1', 8000), DummyHandler).serve_forever()
发出HTTP请求并验证响应的简单测试包含&#34; Hello World&#34;:
# tests/test_server.py
import requests
def test_GET():
resp = requests.get('http://127.0.0.1:8000')
resp.raise_for_status()
assert 'Hello World' in resp.text
# tests/conftest.py
import os
import signal
import subprocess
import time
import coverage.data
import pytest
@pytest.fixture(autouse=True)
def run_backend(cov):
# 1.
env = os.environ.copy()
env['COVERAGE_FILE'] = '.coverage.backend'
serverproc = subprocess.Popen(['coverage', 'run', 'backend.py'], env=env,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
preexec_fn=os.setsid)
time.sleep(3)
yield # 2.
# 3.
serverproc.send_signal(signal.SIGINT)
time.sleep(1)
# 4.
backendcov = coverage.data.CoverageData()
with open('.coverage.backend') as fp:
backendcov.read_fileobj(fp)
cov.data.update(backendcov)
cov
是pytest-cov
(docs)提供的工具。
运行测试会将backend.py
的覆盖范围添加到整体覆盖范围,但只选择了tests
:
$ pytest --cov=tests --cov-report term -vs
=============================== test session starts ===============================
platform linux -- Python 3.6.5, pytest-3.4.1, py-1.5.3, pluggy-0.6.0 --
/data/gentoo64/usr/bin/python3.6
cachedir: .pytest_cache
rootdir: /data/gentoo64/home/u0_a82/projects/stackoverflow/so-50689940, inifile:
plugins: mock-1.6.3, cov-2.5.1
collected 1 item
tests/test_server.py::test_GET PASSED
----------- coverage: platform linux, python 3.6.5-final-0 -----------
Name Stmts Miss Cover
------------------------------------------
backend.py 12 0 100%
tests/conftest.py 18 0 100%
tests/test_server.py 5 0 100%
------------------------------------------
TOTAL 35 0 100%
============================ 1 passed in 5.09 seconds =============================
答案 1 :(得分:0)
使用Coverage 5.1,基于"Measuring sub-processes" section of the coverage.py docs,您可以设置COVERAGE_PROCESS_START
env-var,在代码中的某个位置调用coverage.process_startup()
。如果您在parallel=True
中设置了.coveragerc
在过程中的某个地方,调用以下代码:
import coverage
coverage.process_startup()
这可以在全局sitecustomize.py
中完成,但就我而言,很容易将其添加到应用程序的__init__.py
中,我在其中添加了
import os
if 'COVERAGE_PROCESS_START' in os.environ:
import coverage
coverage.process_startup()
为了安全起见,我在此if
语句中添加了另一项检查(检查是否还设置了MYAPP_COVERAGE_SUBPROCESS
)
在测试用例中,将COVERAGE_PROCESS_START
设置为.coveragerc
文件的路径(如果不需要此配置,则为空字符串),例如:
import os
import subprocess
env = os.environ.copy()
env['COVERAGE_PROCESS_START'] = '.coveragerc'
cmd = [sys.executable, 'run_my_app.py']
p = subprocess.Popen(cmd, env=env)
p.communicate()
assert p.returncode == 0 # ..etc
最后,您创建包含以下内容的.coveragerc
[run]
parallel = True
source = myapp # Which module to collect coverage for
这可确保由每个进程创建的.coverage文件进入一个唯一文件,该文件pytest-cov似乎会自动合并(或可以通过coverage combine
手动完成)。它还描述了要收集数据的模块(--cov=myapp
arg不会传递给子进程)
要运行测试,只需调用pytest --cov=