2013-12-23 2 views
1

Я хочу проверить мое заявление,Тест работает по-другому, когда запущен один, чем с UnitTest

У меня есть эти два файла (не мое реальное приложение, но это представляет ту же проблему).

Файл 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) 

Файл 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() 

Так что моя цель состоит в том, чтобы запустить сервер я закодированный в процессе, а затем проверить свои ответы на разные Запросы.

Когда я запускаю тест в одиночку, он отлично работает:

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 

Но если я начну это как часть моих всех тестов, с помощью UnitTest обнаружат, он не работает:

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) 

Итак, мой вопрос в том, есть ли причина, по которой unittest ведет себя таким образом, и каковы мои возможности, чтобы эти тесты работали внутри unittest?

ответ

1

Ok, после реализации с помощью @Alo Сарв, что проблема заключалась в модуле многопроцессорной, я нашел решение.

Вот оно в случае кто-то сталкивается с той же проблемой:

файл 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) 

файл 2: test_testServer.py

from testServer import ServerHandler 
import SocketServer 
from threading import Thread 
import httplib 
import unittest 

class serverThread(Thread): 

    def __init__(self, port): 
     self.Handler = ServerHandler 
     self.httpd = SocketServer.TCPServer(("", port), self.Handler) 
     Thread.__init__(self) 

    def run(self): 
     self.httpd.serve_forever() 


class Test(unittest.TestCase): 

    @classmethod 
    def setUpClass(cls): 
     cls.serverThread = serverThread(8000) 
     cls.serverThread.daemon = True 
     cls.serverThread.start() 

    @classmethod  
    def tearDownClass(cls): 
     cls.serverThread.httpd.__shutdown_request = True 


    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() 

Короче говоря, решение заключалось в замене использования многопроцессорности с использованием потоков. Затем, адаптируя сервер, чтобы иметь возможность правильно остановить поток (потому что нить не может быть убита так же легко, как процесс)

1

Возможно, unittest пытается подключиться к серверу, прежде чем он успел нормально запустить во втором потоке? Попробуйте добавить time.sleep(1) после cls.serverProcess.start() в setupClass(cls)?

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

Хорошее предложение, возможно, это было какое-то состояние гонки. К сожалению, это не так. Я попытался, и это ничего не изменило. –

+1

Действительно, стоило попробовать. Я думаю, что это имеет какое-то отношение к http://bugs.python.org/issue10845 - проблема с многопроцессорностью в Windows. –

+0

Я тоже смотрел на него. Таким образом, решение, вероятно, будет заключаться в том, чтобы избежать использования многопроцессорной обработки ... –

Смежные вопросы