Spec-Zone.ru › NumPy 1.16

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

Введение

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

Для облегчения такого большого количества похожих модульных тестов используются некоторые высокоуровневые методы программирования, включая макросы C и SWIG, а также наследование в Python. Целью данного документа является описание инфраструктуры тестирования, используемой для проверки того, что typemaps 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 для применения предоставленных typemaps к подписям аргументов, найденных в Vector.h. Этот макрос затем реализуется для всех типов данных, поддерживаемых numpy.i. Затем он выполняет %include "Vector.h" для обертывания всех прототипов функций в Vector.h с помощью typemaps в 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–2019 NumPy Developers
Licensed under the 3-clause BSD License.
https://docs.scipy.org/doc/numpy-1.15.4/reference/swig.testing.html

Spec-Zone.ru

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