Spec-Zone.ru › NumPy 1.21

Тестирование typemap numpy.i

Введение

Написание тестов для файла интерфейса numpy.i SWIG является комбинаторной головной болью. В настоящее время поддерживается 12 различных типов данных, каждый с 74 различными сигнатурами аргументов, в общей сложности 888 typemap, поддерживаемые «из коробки». Каждый из этих typemap, в свою очередь, может потребовать несколько модульных тестов для проверки ожидаемого поведения как для правильных, так и для неправильных входных данных. В настоящее время это приводит к выполнению более 1000 отдельных модульных тестов при запуске make test в подкаталоге numpy/tools/swig.

Для облегчения такого количества аналогичных модульных тестов применяются некоторые высокоуровневые методы программирования, включая макросы C и SWIG, а также наследование Python. Цель данного документа – описать используемую инфраструктуру тестирования для проверки того, что typemap numpy.i работают как ожидается.

Организация тестирования

Поддерживаются три независимые тестовые среды для одномерных, двумерных и трехмерных массивов соответственно. Для одномерных массивов существуют два файла C++, заголовок и исходный код, с именами:

Vector.h
Vector.cxx

в которых содержатся прототипы и код для различных функций, имеющих одномерные массивы в качестве аргументов функции. Файл:

Vector.i

является файлом интерфейса SWIG, который определяет модуль python Vector, оборачивающий функции в Vector.h, используя typemaps в numpy.i для правильной обработки массивов C.

Makefile вызывает swig для генерации Vector.py и Vector_wrap.cxx, а также выполняет скрипт setup.py, который компилирует Vector_wrap.cxx и связывает расширенный модуль _Vector.so или _Vector.dylib, в зависимости от платформы. Этот расширенный модуль и файл-прокси Vector.py оба размещаются в подкаталоге каталога build.

Фактическое тестирование выполняется с помощью скрипта Python с именем:

testVector.py

который использует стандартный модуль Python-библиотеки unittest, который выполняет несколько тестов каждой функции, определенной в Vector.h для каждого поддерживаемого типа данных.

Двумерные массивы тестируются точно так же. Вышеописанное описание применимо, но с заменой Matrix на Vector. Для трехмерных тестов замените Tensor на Vector. Для четырехмерных тестов замените SuperTensor на Vector. Для тестов плоских массивов на месте замените Flat на Vector. В следующих описаниях мы будем ссылаться на тесты Vector, но та же информация применима к тестам Matrix, Tensor и SuperTensor.

Команда make test гарантирует сборку всего тестового программного обеспечения и запуск всех трех тестовых скриптов.

Файлы заголовков тестов

Vector.h - это файл заголовка C++, который определяет макрос C с именем TEST_FUNC_PROTOS, принимающий два аргумента: TYPE, который является именем типа данных, например unsigned int; и SNAME, которое является коротким именем того же типа данных без пробелов, например uint. Этот макрос определяет несколько прототипов функций с префиксом SNAME и по крайней мере одним аргументом, являющимся массивом типа TYPE. Функции, имеющие возвращаемые аргументы, возвращают значение TYPE.

TEST_FUNC_PROTOS затем реализуется для всех типов данных, поддерживаемых numpy.i.

  • signed char
  • unsigned char
  • short
  • unsigned short
  • int
  • unsigned int
  • long
  • unsigned long
  • long long
  • unsigned long long
  • float
  • double

Исходные файлы тестов

Vector.cxx - это файл исходного кода C++, реализующий компилируемый код для каждого из прототипов функций, указанных в Vector.h. Он определяет макрос C TEST_FUNCS, имеющий те же аргументы и работающий так же, как TEST_FUNC_PROTOS в Vector.h. TEST_FUNCS реализуется для каждого из 12 типов данных, как указано выше.

Файлы интерфейса SWIG для тестов

Vector.i - это файл интерфейса SWIG, который определяет модуль python Vector. Он следует соглашениям для использования numpy.i как описано в этой главе. Он определяет макрос SWIG %apply_numpy_typemaps, имеющий один аргумент TYPE. Он использует директиву SWIG %apply для применения указанных typemap к сигнатурам аргументов, найденным в Vector.h. Этот макрос затем реализуется для всех поддерживаемых типов данных numpy.i. Затем выполняется %include "Vector.h" для обертывания всех прототипов функций в Vector.h с использованием typemap в numpy.i.

Скрипты Python для тестов

После использования make для построения тестовых модулей расширения, можно запустить testVector.py для выполнения тестов. Как и в других скриптах, которые используют unittest для облегчения модульного тестирования, testVector.py определяет класс, наследуемый от unittest.TestCase:

class VectorTestCase(unittest.TestCase):

Однако этот класс не выполняется напрямую. Вместо этого он служит базовым классом для нескольких других классов Python, каждый из которых специфичен для определенного типа данных. Класс VectorTestCase хранит две строки с информацией о типе:

self.typeStr

Строка, соответствующая одному из префиксов SNAME используемых в Vector.h и Vector.cxx. Например, "double".

self.typeCode

Короткая (обычно односимвольная) строка, представляющая тип данных в numpy и соответствующая self.typeStr. Например, если self.typeStr является "double", тогда self.typeCode должно быть "d".

Каждый тест, определенный классом VectorTestCase, извлекает функцию Python, которую он пытается протестировать, обращаясь к словарю модуля Vector:

length = Vector.__dict__[self.typeStr + "Length"]

В случае тестов с двойной точностью это вернет функцию Python Vector.doubleLength.

Затем мы определяем новый класс тестовых случаев для каждого поддерживаемого типа данных с кратким определением, например:

class doubleTestCase(VectorTestCase):
    def __init__(self, methodName="runTest"):
        VectorTestCase.__init__(self, methodName)
        self.typeStr  = "double"
        self.typeCode = "d"

Каждый из этих 12 классов собирается в unittest.TestSuite, который затем выполняется. Ошибки и сбои суммируются и возвращаются в качестве аргумента выхода. Любой ненулевой результат указывает на то, что по крайней мере один тест не пройден.

© 2005–2021 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.20/reference/swig.testing.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API