Как один модуль тестирует обработку условий ошибки для API-интерфейсов Python / C, таких как PyType_Ready и PyObject_New? - PullRequest
6 голосов
/ 13 февраля 2012

Довольно просто (если утомительно) модульное тестирование модулей расширения Python, написанных на C, включая случаи ошибок для многих API-интерфейсов Python / C, таких как PyArg_ParseTuple. Например, идиоматический способ запуска функции C, которая реализует функцию или метод Python, выглядит следующим образом:

    if (!PyArg_ParseTuple(args, "someformat:function_name")) {
        return NULL;
    }

Успешный случай этого может быть проверен модулем путем вызова функции с правильным числом и типом аргументов. Случаи сбоев также можно проверить, вызвав функцию с неправильным числом аргументов, а затем с правильным количеством аргументов, но передавая значения неправильного типа. Это приводит к полному покрытию ветвящимся тестом кода C.

Однако не ясно, как использовать отрицательные пути для других API-интерфейсов Python / C. Идиоматический способ начать инициализацию модуля в расширении C выглядит следующим образом:

    if (PyType_Ready(&Some_Extension_Structure) < 0) {
        return 0;
    }

Как заставить PyType_Ready потерпеть неудачу? Аналогично, функция C для выделения нового экземпляра типа расширения часто использует API-интерфейс, такой как PyObject_New:

    self = PyObject_New(Some_Structure, &Some_Extension_Structure);
    if (self == NULL) {
        return NULL;
    }

Как может один модульный тестировать этот отрицательный случай (особенно если учесть, что PyObject_New, вероятно, используется много-много раз в ходе выполнения метода одиночного модульного тестирования)?

Кажется возможным построить общее решение, опираясь на уловки динамического компоновщика, такие как LD_PRELOAD, чтобы обеспечить подделки этих API-интерфейсов C, которые могут быть направлены на сбой правильным способом в нужное время. Однако стоимость создания такой системы кажется недостижимой. Кто-то уже сделал это и сделал результат доступным?

Существуют ли уловки, специфичные для Python / C, которые могли бы облегчить это тестирование?

Должен ли я думать совсем по-другому?

1 Ответ

2 голосов
/ 13 февраля 2012

Это очевидный случай для двойников теста (например, насмешка).Поскольку Python C API не предлагает никаких средств для имитации состояния нехватки памяти, вам придется сделать это самостоятельно.

Создайте свой собственный слой, который обеспечивает PyType_Ready и PyObject_New.Пусть они перейдут к функциям C API, если какой-то элемент управления, вероятно, переменная среды, не проинструктирует их об этом.Они могут вызвать любой беспорядок, который вы пожелаете, и проверить реакцию вашего кода.

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