Python: модульное тестирование кода на основе сокетов? - PullRequest
18 голосов
/ 29 октября 2010

Я пишу клиент + сервер Python, который использует gevent.socket для связи.Есть ли хорошие способы проверки работы кода на уровне сокетов (например, проверка того, что SSL-соединения с недействительным сертификатом будут отклонены)?Или просто spawn реальный сервер?

Edit : я не верю, что "наивного" насмешки будет достаточно для тестирования компонентов SSL из-за сложных взаимодействийучаствует.Я не прав в этом?Или есть лучший способ протестировать SSL?

Ответы [ 3 ]

16 голосов
/ 29 октября 2010

Вы можете легко запустить сервер и затем получить к нему доступ в тестовом примере. собственный набор тестов gevent делает именно это для тестирования встроенных серверов gevent .

Например:

class SimpleServer(gevent.server.StreamServer):

    def handle(self, socket, address):
        socket.sendall('hello and goodbye!')

class Test(unittest.TestCase):      

    def test(self):
        server = SimpleServer(('127.0.0.1', 0))
        server.start()
        client = gevent.socket.create_connection(('127.0.0.1', server.server_port))
        response = client.makefile().read()
        assert response == 'hello and goodbye!'
        server.stop()

Использование 0значение порта означает, что сервер будет использовать любой доступный порт.После запуска сервера фактическое значение, выбранное bind, становится доступным в качестве атрибута server_port.

StreamServer также поддерживает SSL, передает аргументы keyfile и certfile в конструктор, и он будетОберните каждый сокет SSLObject перед передачей его вашему обработчику.

Если вы не используете StreamServer и ваш сервер основан на Greenlet , тогда действительно нерест это то, что вы должны сделать.Не забудьте убить в конце тестового примера.

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

Я считаю, что нет необходимости издеваться над любым из Gevent API, гораздо проще просто использовать его, так как серверы и клиенты могут счастливожить в том же процессе.

7 голосов
/ 29 октября 2010

Есть еще один (лучше IMO) способ: вам надо издеваться над библиотекой, которую вы используете. Пример вспомогательного помощника для python: mox .

Вам не нужен набор серверов с действующим сертификатом, другой - с недействительным сертификатом, вообще без поддержки ssl, серверы, которые вообще не отвечают ни на какие пакеты, и т. Д. Вы можете смоделировать их поведение с помощью "фиктивного "клиентский сокет. То, как он работает с Mox, заключается в том, что вы сначала «учите», чего он должен ожидать и как он должен реагировать, а затем выполняете на нем свой реальный код, одновременно заменяя реальный gevent.socket на смоделированный. Требуется некоторая практика, чтобы овладеть этим, но оно того стоит.

6 голосов
/ 29 октября 2010

Насмешка и заглушка - это прекрасно, но иногда вам нужно поднять их на новый уровень интеграции.Поскольку порождение сервера, даже фальшивого, может занять некоторое время, подумайте о том, что отдельный набор тестов (назовите их интеграционными тестами) может быть в порядке.

"Протестируйте его так, как будто вы собираетесь его использовать", это мойруководящие указания, и если вы так много издеваетесь и заглушаете, что ваш тест становится тривиальным, это не так уж полезно (хотя почти любой тест лучше, чем ничего).Если вы беспокоитесь о работе с плохими сертификатами SSL, непременно создайте несколько плохих сертификатов и напишите тестовое устройство, к которому вы можете их добавить.Если это означает порождение сервера, пусть будет так.Может быть, если это вас задело, это приведет к рефакторингу, который сделает тестирование другим способом.

...