Какова эффективная стратегия тестирования для тестирования приложения с помощью имитации IP-сокетов, последовательного порта и общей библиотеки? - PullRequest
1 голос
/ 10 октября 2019

Я хочу написать несколько автоматических интеграционных тестов для приложения C ++, которое использует внешнюю разделяемую библиотеку, в частности WiringPi на Raspberry Pi. Эта библиотека используется для чтения / записи GPIO на RPi. В настоящее время я использую WiringPi-Sim на хосте Intel / AMD Linux, который представляет собой набор базовых заглушек, которые ничего не делают, но позволяют собирать и запускать приложение на хосте без RPi, чтогде я бы предпочел выполнить тесты.

Тестируемое приложение C ++ (AuT) создает несколько TCP-соединений с другими процессами и получает UDP-дейтаграммы от другого процесса. Он также записывает некоторые данные в последовательный TTY (обычно это внешний адаптер RS485).

Для тестов мне нужно проверить несколько вещей, рассматривая AuT как черный ящик и удаляя столько зависимостей от RPiпоследовательное устройство, внешние процессы и т. д., по возможности:

  • То, что AuT запускается правильно и инициализирует набор GPIO с конкретными значениями.
  • Что AuT изменяет наборGPIO во время выполнения с конкретными значениями.
  • что AuT реагирует на входящие данные на сокетах TCP и UDP.
  • что AuT записывает и читает конкретные данные на последовательном TTY.
  • что AuT правильно отключается при получении соответствующего сигнала (например, SIGINT), что конкретные данные отображаются на TTY в результате, и что для GPIO установлены конкретные конечные значения.

В настоящее время я думаю об использовании Python (например, pytest) для реализации тестов:

  • В тестовом приложении Python можно создать простые TCP-серверы, притворившись тПриложения внешнего сервера TCP, к которым может подключаться AuT,
  • Простой отправитель UDP в тестовом приложении Python может отправлять соответствующие данные в сокет UDP на AuT.
  • Может быть поддельный TTYсозданный для работы в качестве последовательного порта, и тестовое приложение Python может читать / записывать из него (может быть, через socat?), как может AuT,
  • Библиотека или общий объект на основе WiringPi-Sim могутбыть написано, что позволяет тестовому приложению Python контролировать и влиять на состояние GPIO (насколько видит AuT).
  • Затем приложение python может запустить основной процесс и отправить соответствующие сигналы для проверки поведения.

Бит, в котором я не так уверен, это "фиктивный" общий объект WiringPi. Я знаю, что его можно внедрить в процесс AuT с помощью LD_PRELOAD, но я не уверен, как связаться с фиктивным объектом из тестового приложения Python. Нужно ли использовать совместно используемую память или какой-либо другой IPC, чтобы экземпляр библиотеки в AuT мог обмениваться данными с тестовым приложением Python? Может ли тестовое приложение Python запустить TCP-сервер, и макет WiringPi подключается «за кулисами» для передачи данных / контроля в тестовое приложение? Может ли фиктивный объект каким-либо образом интегрироваться с Python дружественным для Python способом?

Может ли максифицированный общий объект связываться с тестовым приложением через сокет или канал UNIX, возможно?

У меня есть полныйисходный код для C ++ AuT, чтобы я мог реализовать большинство или все это на C ++, а не на Python, однако некоторые аспекты (например, простые TCP-серверы) было бы быстрее и проще писать на Python. Мне также нравится pyenv довольно хорошо.

Интересно, есть ли уже решение для такого рода тестовых проводов? Это не обязательно должно быть на основе Python, но это то, к чему я привык. Любые идеи?

РЕДАКТИРОВАТЬ: другая идея состоит в том, чтобы извлечь ядро ​​AuT и протестировать его, используя привязки языка C ++, с внедрением зависимостей и имитациями C ++. Однако важным требованием является тестирование встроенного приложения, а не модификация приложения на уровне источника, поскольку важно выполнить эти тесты в том же двоичном файле, который поставляется, в целях безопасности и аудита.

1 Ответ

1 голос
/ 24 октября 2019

Вот предложение, как это можно сделать. Это только идея - я не пробовал.

Во-первых, взаимодействие между Python и C описано в руководствах по Python: https://docs.python.org/3/extending/extending.html. Вы можете написать свою тестовую среду на Python, затем изнекоторые тестовые вызовы из Python AuT реализованы в C ++. И из этого кода C ++ вы можете снова вызвать некоторый код Python.

Таким образом, то, что может приблизиться к тому, что вы ищете, будет следующей цепочкой вызовов:

python-test-case -> AuT -> wiringPi-sim -> python-test-callbacks

Frompython-test-case вы должны настроить соответствующий python-test-callbacks на поведение, необходимое для этого конкретного теста. После этой настройки python-test-case вызовет AuT, который, в свою очередь, вызовет одну или несколько wiringPi-sim функций, каждая из которых вызывает свою соответствующую python-test-callback.

Проблема в том, что в данный момент wiringPi-sim реализует интерфейс очень простым способом, который не поддерживает внедрение определенного поведения. Например, функция digitalRead выглядит так:

int digitalRead(int pin) {
    return 1;
}
;

Чтобы сделать ее более полезной, вам нужно расширить ее функциональность, чтобы вместо выполнения return 1 вы вызывали некоторый Pythonобратный вызов для функции digitalRead, которую можно настроить из тестового примера Python. Для этого потребуется изменить wiringPi-sim или написать свой. Однако из того, что я видел, wiringPi-sim - это всего лишь небольшой объем кода, поэтому он может быть выполним для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...