[英]Why does my Python unittest test case with threads hang?
I have the following test case. 我有以下测试用例。 Note that the following test case is not trying to test anything but only trying to demonstrate the hanging issue I am encountering.
请注意,以下测试用例不是试图测试任何东西,只是试图证明我遇到的悬挂问题。
import http.server
import urllib.request
import threading
import unittest
class FooTest(unittest.TestCase):
def setUp(self):
print('---- setup start')
self.httpd = http.server.HTTPServer(('', 8080), http.server.SimpleHTTPRequestHandler)
thread = threading.Thread(target=self.httpd.serve_forever)
thread.start()
print('---- setup complete')
def tearDown(self):
print('---- teardown start')
self.httpd.shutdown()
print('---- teardown complete')
def test1(self):
print('---- test1 start')
print(threading.current_thread())
urllib.request.urlopen('http://127.0.0.1:8080/foo')
print('---- test1 complete')
def test2(self):
print('---- test2 start')
print(threading.current_thread())
urllib.request.urlopen('http://127.0.0.1:8080/foo')
print('---- test2 complete')
if __name__ == '__main__':
unittest.main()
I expect 2 errors when I try to execute this test case. 当我尝试执行此测试用例时,我预计会出现2个错误。 Instead, the test case hangs after the following output.
相反,测试用例在以下输出后挂起。
C:\lab>python foo.py -v
test1 (__main__.FooTest) ... ---- setup start
---- setup complete
---- test1 start
<_MainThread(MainThread, started 12980)>
127.0.0.1 - - [24/Mar/2014 21:53:57] code 404, message File not found
127.0.0.1 - - [24/Mar/2014 21:53:57] "GET /foo HTTP/1.1" 404 -
---- teardown start
---- teardown complete
ERROR
test2 (__main__.FooTest) ... ---- setup start
---- setup complete
---- test2 start
<_MainThread(MainThread, started 12980)>
If I remove test2
from the code, then I expect only 1 error and sure enough I see it. 如果我从代码中删除
test2
,那么我预计只有1个错误,而且我确实看到了它。
C:\lab>python foo.py -v
test1 (__main__.FooTest) ... ---- setup start
---- setup complete
---- test1 start
<_MainThread(MainThread, started 15720)>
127.0.0.1 - - [24/Mar/2014 21:55:12] code 404, message File not found
127.0.0.1 - - [24/Mar/2014 21:55:12] "GET /foo HTTP/1.1" 404 -
---- teardown start
---- teardown complete
ERROR
======================================================================
ERROR: test1 (__main__.FooTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "foo.py", line 22, in test1
urllib.request.urlopen('http://127.0.0.1:8080/foo')
File "C:\Python34\lib\urllib\request.py", line 153, in urlopen
return opener.open(url, data, timeout)
File "C:\Python34\lib\urllib\request.py", line 461, in open
response = meth(req, response)
File "C:\Python34\lib\urllib\request.py", line 574, in http_response
'http', request, response, code, msg, hdrs)
File "C:\Python34\lib\urllib\request.py", line 499, in error
return self._call_chain(*args)
File "C:\Python34\lib\urllib\request.py", line 433, in _call_chain
result = func(*args)
File "C:\Python34\lib\urllib\request.py", line 582, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 404: File not found
----------------------------------------------------------------------
Ran 1 test in 0.032s
FAILED (errors=1)
Why does the test case hang if there are 2 tests with errors? 如果有2个测试有错误,为什么测试用例会挂起?
Add a call to server_close
to close the socket: 添加对
server_close
的调用以关闭套接字:
def setUp(self):
print('---- setup start')
handler = http.server.SimpleHTTPRequestHandler
self.httpd = http.server.HTTPServer(('', 8080), handler)
threading.Thread(target=self.serve).start()
print('---- setup complete')
def serve(self):
try:
self.httpd.serve_forever()
finally:
self.httpd.server_close()
I found another way to run httpd in TestCase 我找到了另一种在TestCase中运行httpd的方法
import unittest
import threading
from http.server import HTTPServer, BaseHTTPRequestHandler
class TestHttpRequests(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.httpd = HTTPServer(handler=BaseHTTPRequestHandler)
threading.Thread(target=cls.httpd.serve_forever).start()
@classmethod
def tearDownClass(cls):
cls.httpd.shutdown()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.