04.21 Тестирование
Разбор примера (клонируем его)
Не забываем про pipenv
Написать функцию решения квадратного уравнения sqroots(coeffs:str) -> str, которая интерпретирует строку как три числа a b c (через пробел) и возвращает строку из 0, 1 или 2 корней уравнения ax²+bx+c=0 (через пробел). В случае неразборчивой строки, неправильного количества параметров (или если a==0) функция вызывает исключение.
Написать к этой функции testcase из четырёх тестов (на 0, 1 и 2 корня и на исключение)
Проверить работоспособность вот такого сервера (это практически копипаста сетевого сервиса из лекций, но в 2024 году быстро превратить её в нижеследующий текст мало кто смог):
1 import asyncio 2 3 async def echo(reader, writer): 4 while data := await reader.readline(): 5 res = data.strip().decode() 6 writer.write(f"{res.swapcase()}\n".encode()) 7 writer.close() 8 await writer.wait_closed() 9 10 async def main(): 11 server = await asyncio.start_server(echo, '0.0.0.0', 1337) 12 async with server: 13 await server.serve_forever() 14 15 asyncio.run(main())
Написать сетевой сервис, который принимает строку, обрабатывает её с помощью sqroots() и возвращает строку-результат. Исключения сервер игнорирует, возвращая в этом случае пустую строку. Не забывайте про то, что в конце строки должен быть символ перевода строки. Перед передачей строки с ней нужно сделать encode(), а после приёма - decode().
Проверить работоспособность сервера с помощью netcat (или socat)
Написать функцию-клиент sqrootnet(coeffs, s), которая передаёт в сокет s строку коэффициентов, получает результат (пример тут) и возвращает его
Дальнейший разбор примера (setup/teardown и мокеры)
Написать ещё два testcase:
- Сервера
В setUpClass() сервер запускается
- Например, так:
где sqroo.serve() — это asyncio.run(сервер)
- Например, так:
- Затем следует четыре тех же теста
В setUp() открывается сокет s и устанавливается соединение,
тесты просто вызывают sqrootnet() (
не забываем про encode()/decode())
а в tearDown() этот сокет закрывается.
В tearDownClass() сервер останавливается
Функции sqrootnet()
В setUp() вместо сокета создаётся мокер s
У этого мокера есть метод s.sendall(), который не посылает строку, а сам вызывает sqroots()и запоминает результат (по аналогии с Moo.curses.wrapper в примере)
У этого мокера есть метод s.recv(), который возвращает результат, сохранённый с помощью s.sendall()
- Далее следует четыре теста ☺
- Сервера
посмотреть coverage
Д/З
Задача_1. Тестирование отработки сервером команд от клиента (проверяется связка клиент+сервер)
Скопировать решение Задачи_2 с предыдущего занятия. Сделать коммит. Работать на ветке work.
модифицировать архитектуру проекта таким образом, чтобы в нём была отдельная функция для запуска сервера
- написать набор тестов для отработки сервером команд от клиента, организованный следующим образом:
setup:
- запуск сервера на локальном хосте
пример запуска: proc = multiprocessing.Process(target=функция_для_запуска_сервера([её, параметры]))
- подключение к этому серверу
- запуск сервера на локальном хосте
teardown: закрытие соединения и прерывание работы сервера (proc.terminate())
каждый тест запускается на клиенте и имеет вид: <отправка команды; ожидание и проверка ответа>; команда - фиксированное сообщение в формате протокола клиент->сервер
- проверяются команды:
- установка монстра (недалеко от начального положения игрока)
- подход к монстру; ожидаемый ответ: "появление" монстра и произнесение им приветствия
- атака на монстра
Задача_2. Тестирование клиента с использованем мокеров
Скопировать решение Задачи_2 с предыдущего занятия. Сделать коммит. Работать на ветке work.
написать набор тестов для преобразования клиентом команд из формата пользовательского ввода в формат протокола клиент->сервер
- сервер не запускается, работает только клиент
- для пользовательского ввода и для отправки сообщений к серверу используются мокеры (так можно протестировать всю цепочку действий от ввода до отправки)
- мокер пользовательского ввода при последовательных обращениях возвращает заданную последовательность пользовательских команд
выбрать две команды, у каждой из которых формат пользовательского ввода НЕ совпадает с форматом протокола клиент->сервер
для каждой из этих команд протестировать преобразование правильной команды в формат протокола клиент->сервер (для двух разных значений параметров команды; если команда - движение, то для двух разных направлений)
- хотя бы для одной команды протестировать обработку неправильно заданных параметров