Вопрос или проблема
Я разрабатываю плагин поиска для Ansible и тестовый код для него. Как плагин поиска, так и тестовый код для плагина работают нормально.
Для тестирования я использую pytest с pytest-ansible, и тестовая функция использует фикстуру ansible_module, предоставленную pytest-ansible, чтобы вызвать встроенный модуль set_fact для выполнения поиска. Тестовая функция выглядит так (упрощенно):
import pytest
from pytest_ansible.fixtures import ansible_module
@pytest.mark.ansible(host_pattern='localhost', connection='local')
def test_mylookup(ansible_module):
expr = "lookup('myorg.mycoll.mylookup', 'someterm')"
contacted = ansible_module.set_fact(result=f"{{{{ {expr} }}}}")
contacted_host = contacted['localhost']
result = contacted_host['ansible_facts']['result']
# утверждения к результату
Обновление: я обнаружил, что импорт ansible_module не обязателен для того, чтобы pytest находил фикстуры.
Проблема в том, что этот тест не добавляет покрытие тестами (0%). Другие модули Python в проекте добавляют покрытие тестами, только тесты для плагинов Ansible этого не делают.
Я предполагаю, что объект ansible_module в какой-то момент использует механизмы Ansible для выполнения модуля, и это, вероятно, позволяет моему коду поиска выполняться в другом потоке или процессе. Но это только предположение.
Я использую пакеты pytest-cov и coverage, чтобы заставить pytest считать покрытие, и запускаю тест, вызывая pytest с опциями –cov*.
Соответствующие версии пакетов Python (на Python 3.9):
ansible 8.7.0
ansible-core 2.15.13
pytest 7.4.4
pytest-ansible 4.1.1
pytest-cov 6.0.0
coverage 7.6.4
Я хотел бы узнать, как мне правильно учесть покрытие тестами при тестировании плагина поиска Ansible с помощью pytest.
Ответ или решение
Чтобы получить отчет о покрытии при тестировании плагина поиска Ansible с использованием pytest, необходимо учитывать несколько ключевых аспектов вашей текущей настройки. Вы уже правильно используете pytest с плагином pytest-ansible, однако тесты для Ansible, как вы заметили, могут не учитывать покрытие из-за особенностей их исполнения. Вот подробный подход к решению вашей проблемы.
1. Понимание проблемы с покрытием
Тестирование плагинов Ansible, таких как lookup-плагины, часто происходит в контексте выполнения модулей Ansible, что может происходить в другом процессе или потоке. Поэтому код, который вы хотите покрыть, может не учитываться инструментами для анализа покрытия, такими как pytest-cov
, поскольку они отслеживают исполнение только в пределах одного процесса.
2. Настройка pytest-cov
Убедитесь, что вы правильно настраиваете соединение между pytest и pytest-cov. Запуск pytest с опцией --cov
должен выглядеть примерно так:
pytest --cov=myorg/mycoll --cov-report=term-missing
Здесь myorg/mycoll
— это путь до вашего плагина. Опция term-missing
предоставляет более подробный вывод, указывая, какие строки не были покрыты.
3. Обработка среды выполнения Ansible
Чтобы корректно отследить покрытие, можно создать собственный тестовый контекст. Создайте тестовый класс или модуль, который будет исполнять ваш код в том же процессе:
import pytest
from ansible.module_utils.basic import AnsibleModule
@pytest.mark.ansible(host_pattern='localhost', connection='local')
def test_mylookup(ansible_module):
# Параметры для инициализации модуля
module_args = {'result': "dummy_value"}
ansible_module = AnsibleModule(argument_spec={}, bypass_checks=True)
# Прямое выполнение вашего lookup
result = ansible_module.lookup('myorg.mycoll.mylookup', 'someterm')
assert result is not None
4. Включение логирования
Рекомендуется также включить логирование на уровень DEBUG для Ansible, чтобы лучше понять, что происходит в процессе выполнения:
# файл ansible.cfg
[defaults]
log_path = ansible.log
Эта запись поможет вам понять, какие действия выполняются внутри тестируемого плагина.
5. Альтернативные инструменты для покрытия
Если проблема сохраняется, рассмотрите возможность использования дополнительных инструментов для анализа покрытия, таких как pytest-cov
и coverage.py
, которые могут обеспечить большую гибкость. Например, настройка конфигурации coverage
файла (.coveragerc
) может помочь, указав правильные пути к вашим модулям и игнорируя некоторые элементы.
Заключение
Тестирование плагинов Ansible может быть сложной задачей из-за их способа выполнения и взаимодействия с главной петлёй Ansible. Однако с правильной настройкой инструментов тестирования, таких как pytest
, pytest-cov
, и правильным управлением контекстом тестирования, вы сможете получать точные отчеты о покрытии для своих плагинов. Кроме того, не забывайте следить за обновлениями ваших библиотек, так как разработчики могут улучшать функциональность и исправлять ошибки, касающиеся покрытия кода.