The test works differently when launched alone than with the test unit

I want to test my application

I have these two files (Not my real application but this presents the same problem).

File 1: testServer.py

import SocketServer
import SimpleHTTPServer

class ServerHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):

    def do_GET(self):
        f = self.wfile
        self.send_response(200)
        self.end_headers()
        f.write("ok")

def runServer(port):
    Handler = ServerHandler

    httpd = SocketServer.TCPServer(("", port), Handler)

    httpd.serve_forever()

if __name__ == "__main__":
    runServer(8000)

File 2: test_testServer.py

import testServer
from multiprocessing import Process
import httplib
import unittest

class Test(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.serverProcess = Process(target = testServer.runServer, args = (8000,))
        cls.serverProcess.daemon = True
        cls.serverProcess.start()

    @classmethod
    def tearDownClass(cls):
        cls.serverProcess.terminate()

    def test_Server(self):
        conn = httplib.HTTPConnection("localhost", 8000)
        conn.request("GET", "")
        response = conn.getresponse().read()
        self.assertTrue(response, "ok")

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

So my goal is to start the server I coded in a process and then test its replies to different requests.

When I launch the test alone, it works perfectly fine:

 C:\Users\r.bunel\workspace\Sandbox>python test_testServer.py
 127.0.0.1 - - [23/Dec/2013 09:23:50] "GET / HTTP/1.1" 200 -

 ----------------------------------------------------------------------
 Ran 1 test in 1.009s

 OK

But if I start it as a part of my all test suite, by using unittest's discover, it doesn't work:

C:\Users\r.bunel\workspace\Sandbox>python -m unittest discover
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Python27\lib\multiprocessing\forking.py", line 380, in main
    prepare(preparation_data)
  File "C:\Python27\lib\multiprocessing\forking.py", line 488, in prepare
    assert main_name not in sys.modules, main_name
AssertionError: __main__
E
======================================================================
ERROR: test_Server (test_testServer.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\r.bunel\workspace\Sandbox\test_testServer.py", line 22, in test_Server
    conn.request("GET", "")
  File "C:\Python27\lib\httplib.py", line 973, in request
    self._send_request(method, url, body, headers)
  File "C:\Python27\lib\httplib.py", line 1007, in _send_request
    self.endheaders(body)
  File "C:\Python27\lib\httplib.py", line 969, in endheaders
    self._send_output(message_body)
  File "C:\Python27\lib\httplib.py", line 829, in _send_output
    self.send(msg)
  File "C:\Python27\lib\httplib.py", line 791, in send
    self.connect()
  File "C:\Python27\lib\httplib.py", line 772, in connect
    self.timeout, self.source_address)
  File "C:\Python27\lib\socket.py", line 571, in create_connection
    raise err
error: [Errno 10061] Aucune connexion nÆa pu Ûtre Útablie car lÆordinateur cible lÆa expressÚment refusÚe

----------------------------------------------------------------------
Ran 1 test in 2.009s

FAILED (errors=1)

So, my question is whether or not there is a reason for unittest to behave this way and what are my options to make these tests work inside unittest?


Perhaps the unittest is trying to connect to the server before it has had time to start up properly in the second thread? Try adding time.sleep(1) after cls.serverProcess.start() in setupClass(cls) ?

@classmethod
def setUpClass(cls):
    cls.serverProcess = Process(target = testServer.runServer, args = (8000,))
    cls.serverProcess.daemon = True
    cls.serverProcess.start()
    time.sleep(1)