[PYTHON] Start a temporary http server locally with Pytest

By setting up a local server when executing a unit test, it is possible to perform tests that do not depend on the outside.

Convenient for API and crawler development.

The flow is like this

--Describe http server start / end processing as fixture in conftest.py --Call a fixture in a test function

Implementation

conftest.py


import pytest
from http.server import (
    HTTPServer as SuperHTTPServer,
    SimpleHTTPRequestHandler
)
import threading


class HTTPServer(SuperHTTPServer):
    """
Class for wrapper to run SimpleHTTPServer on Thread.
    Ctrl +Only Thread remains dead when terminated with C.
Keyboard Interrupt passes.
    """
    def run(self):
        try:
            self.serve_forever()
        except KeyboardInterrupt:
            pass
        finally:
            self.server_close()


@pytest.fixture()
def http_server():
    host, port = '127.0.0.1', 8888
    url = f'http://{host}:{port}/index.html'
    # serve_Run forever under thread
    server = HTTPServer((host, port), SimpleHTTPRequestHandler)
    thread = threading.Thread(None, server.run)
    thread.start()
    yield url  #Transition to test here
    #End thread
    server.shutdown()
    thread.join()

Transfer control to the test function with the yield statement. The setUp and tearDown in the unit test are before and after the yield statement, respectively.

Place the content in the execution directory.

index.html


<html>Hello pytest!</html>

Use fixture (http_server) in test function

test_httpserver.py


import requests


def test_index(http_server):
    url = http_server
    response = requests.get(url)
    assert response.text == '<html>Hello pytest!</html>'

Execution result

$ pytest --setup-show test_httpserver.py
========================================= test session starts =========================================platform linux -- Python 3.8.1, pytest-5.3.3, py-1.8.1, pluggy-0.13.1
rootdir: /home/skokado/workspace/sandbox
collected 1 item

test_httpserver.py
        SETUP    F http_server
        test_httpserver.py::test_index (fixtures used: http_server).
        TEARDOWN F http_server

========================================== 1 passed in 0.60s ==========================================

You can trace the generation of fixtures with the --setup-show option. You can see that the test_index function uses the fixture http_server.

Other

Bankushi (@vaaaaanquish), I used it as a reference.

Reference-Write a unit test for web scraping using Python's http.server

Recommended Posts

Start a temporary http server locally with Pytest
Start a simple Python web server with Docker
Build a CentOS Linux 8 environment with Docker and start Apache HTTP Server
Create a "Hello World" (HTTP) server with Tornado
Easy HTTP server with Python
Creating a Flask server with Docker
Set up a Samba server with Docker
Build a local server with a single command [Mac]
Set up a simple HTTPS server with asyncio
Install Windows 10 from a Linux server with PXE
Set up a local server with Go-File upload-
Start Django in a virtual environment with Pipenv
Pretend to be a server with two PCs
Start a process with a scheduling policy on Linux
Set up a local server with Go-File download-
Launch a web server with Python and Flask
Mount a directory on another server with sshfs
Load a package created locally with Go Module
[Mac] I want to make a simple HTTP server that runs CGI with Python
I made a ready-to-use syslog server with Play with Docker
A simple Python HTTP server that supports Range Requests
A server that echoes data POSTed with flask / python
Create a home music server with Centos8 + Universal Media Server
Create a web server in Go language (net / http) (1)
Create a fake Minecraft server in Python with Quarry
[Vagrant] Set up a simple API server with python