我想测试我的应用程序
我有这两个文件(不是我真正的应用程序,但这会出现同样的问题)。
文件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)
所以,我的问题是单元测试是否有理由以这种方式运行,我有什么选择让这些测试在单元测试中运行?
答案 0 :(得分:1)
也许单元测试是在第二个线程中有时间正确启动之前尝试连接服务器?尝试在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)
答案 1 :(得分:1)
好的,在@Alo Sarv的帮助下意识到问题出现在多处理模块中后,我找到了一个解决方案。
这是以防有人遇到同样的问题:
文件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()
简而言之,解决方案是使用线程替换多处理的使用。然后,调整服务器以便能够正确地停止线程(因为线程不能像进程一样容易被杀死)