I am writing integration tests for a project in which I am making HTTP calls and testing whether they were successful or not.
Since I am not importing any module and not calling functions directly coverage.py report for this is 0%.
I want to know how can I generate coverage report for such integration HTTP request tests?
The recipe is pretty much this:
- Ensure the backend starts in code coverage mode
- Run the tests
- Ensure the backend coverage is written to file
- Read the coverage from file and append it to test run coverage
Example:
backend
Imagine you have a dummy backend server that responds with a "Hello World" page on GET requests:
# backend.py
from http.server import BaseHTTPRequestHandler, HTTPServerclass 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()
test
A simple test that makes an HTTP request and verifies the response contains "Hello World":
# tests/test_server.py
import requestsdef test_GET():resp = requests.get('http://127.0.0.1:8000')resp.raise_for_status()assert 'Hello World' in resp.text
Recipe
# 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
is the fixture provided by pytest-cov
(docs).
Running the test adds the coverage of backend.py
to the overall coverage, although only tests
selected:
$ 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 itemtests/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 =============================