Ответ 1
Попробуйте использовать подкласс TCPServer с allow_reuse_address
установить True:
class TestServer(SocketServer.TCPServer):
allow_reuse_address = True
...
httpd = TestServer(("", PORT), handler)
Я пишу модуль Python, который обертывает определенный API веб-сервисов. Все это REST, поэтому относительно просто реализовать.
Однако я обнаружил проблему, когда дело доходит до модульного тестирования: поскольку я не запускаю службы, для которых я создал этот модуль, я не хочу их забивать, но в то же время мне нужно получить данные для выполнения моих тестов. Я посмотрел на SimpleHTTPServer, и все будет в порядке.
Я решил часть проблемы, которую я имел, но теперь, поскольку я не могу прекратить поток, я получаю проблемы с "адресом, который уже используется" при запуске тестового приложения более одного раза.
Вот пример кода
PORT = 8001
handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), handler)
httpd_thread = threading.Thread(target=httpd.serve_forever)
httpd_thread.setDaemon(True)
httpd_thread.start()
api_data = urllib.urlopen("http://localhost:8001/post/index.json")
print "Data start:"
print json.load(api_data)
Где "index.json" - это mock файл JSON, который я создал, который заменяет реальную вещь. Как я могу чистить вещи изящно после завершения программы?
Попробуйте использовать подкласс TCPServer с allow_reuse_address
установить True:
class TestServer(SocketServer.TCPServer):
allow_reuse_address = True
...
httpd = TestServer(("", PORT), handler)
Мы используем сервер, построенный на wsgiref
. http://docs.python.org/library/wsgiref.html
Очень легко добавлять функции на этот сервер, когда мы добавляем модульные тесты.
Мы запускаем сервер с subprocess
. http://docs.python.org/library/subprocess.html?highlight=subprocess#module-subprocess
Мы не используем потоки для такого тестирования. Зачем? (1) Наш сервер unit test довольно сложный, и мы хотели бы полностью изолировать его от клиентских приложений. (2) Наши клиентские приложения будут отдельными процессами на отдельном оборудовании, мы должны быть уверены, что у нас есть реалистичные ожидания производительности для этой конфигурации. (3) Это проще. (4) Он переносится на всех платформах. (5) Тривиальным является переход от автономного модульного тестирования к интеграционному тестированию с уже имеющимся на производстве сервером.
На самом деле у нас есть небольшое приложение WSGI, которое заставляет серверы работать с контролируемым образом, чтобы журналы были корректно завершены.
Старый поток, но ответы здесь мне не помогли, я использую HTTPServer и закрываю после каждого unit test (по умолчанию HTTPServer имеет allow_reuse_address = 1 набор). Однако я все еще получил адрес, уже использующий проблему после вызова shutdown. Я исправил использование:
from BaseHTTPServer import HTTPServer
class MyHTTPServer(HTTPServer):
def shutdown(self):
self.socket.close()
HTTPServer.shutdown(self)
Не знаете, почему это не происходит по умолчанию? Может быть, это не оптимально?