Using wsgiref.simple_server in unittests

I have some functions like this:


URL = 'http://localhost:8080'
def func():
    response = urlopen(URL)
    return process(response)

And I want to test it with unittest.

I did something like this:


from wsgiref.simple_server import make_server
def app_200_hello(environ,start_response):
    stdout = StringIO('Hello world')
    start_response("200 OK", [('Content-Type','text/plain')])
    return [stdout.getvalue()]

s = make_server('localhost', 8080, app_200_hello)

class TestFunc(unittest.TestCase):
    def setUp(self):
        s.handle_request()

    def test1(self):
        r = func()
        assert r, something

if __name__ == '__main__':
    unittest.main()

In setUp (), my tests stop because s.handle_request () is waiting for a request. How can I get around this? Run s.handle_request () in another thread? or maybe there is another solution?

EDIT: I want to test the function "func", not "app_200_hello"

+3
source share
5 answers

If you are testing a WSGI application, I can highly recommend werkzeug.test , which circumvents these problems by testing the application itself without a server

from werkzeug.test import Client

# then in your test case
def test1(self):
    client = Client(app_200_hello)
    appiter, status, headers = client.open()
    assert ''.join(appiter) == 'Hello World'
    assert status == '200 OK'

WSGI- .

, , , , . , , , , - , wsgiref, , , , -STOP .

+7

setUp - :

self.port = 8000
server = make_server('', self.port, make_my_wsgi_ap())
self.server_process = multiprocessing.Process(target=server.serve_forever)
self.server_process.start()

tearDown do:

self.server_process.terminate()
self.server_process.join()
del(self.server_process)

, del(), .

+4

.

subprocess.Popen()

Python 2.6, tearDown.

def setUp( self ):
    self.server= subprocess.Popen( "python","myserver","etc." )
def tearDown( self ):
    self.server.kill()

Python 2.6, .

+3

urlopen, .

, mycode.py, - :



import mycode

class TestFunc(unittest.TestCase):
    def setUp(self):
        # patch mycode, to use mock version of urlopen
        self._original_urlopen = mycode.urlopen
        mycode.urlopen=self.mock_urlopen

    def tearDown(self):
        # unpatch urlopen
        mycode.urlopen=self._original_urlopen

    def mock_urlopen(self,url):
        # return whatever data you need urlopen to return

    def test1(self):
        r = func()
        assert r, something

if __name__ == '__main__':
    unittest.main()


" ", , , , .

+2
source

My decision:


URL = 'http://localhost:8085'
def func():
    response = urlopen(URL)
    return response.read()

import unittest
from wsgiref.simple_server import WSGIServer, WSGIRequestHandler
import threading
from urllib2 import urlopen
from cStringIO import StringIO

def app_200_hello(environ,start_response):
    stdout = StringIO('Hello world')
    start_response("200 OK", [('Content-Type','text/plain')])
    return [stdout.getvalue()]

server = WSGIServer(('localhost', 8085), WSGIRequestHandler)
server.set_app(app_200_hello)

t = threading.Thread(target=server.serve_forever)
t.start()

class TestFunc(unittest.TestCase):
    def setUp(self):
        pass

    def test1(self):
        r = func()
        self.assertEqual(r, 'Hello world')

    def __del__(self):
        server.shutdown()

if __name__ == '__main__':
    unittest.main()


I start the "server" in another thread and end it in the TestFunc destructor.

0
source

Source: https://habr.com/ru/post/1704579/


All Articles