Spec-Zone.ru › NumPy 1.14

Тестирование 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, который затем выполняется. Ошибки и сбои суммируются и возвращаются в качестве аргумента выхода. Любое ненулевое значение указывает на то, что по крайней мере один тест не прошел.

© 2008–2016 NumPy Developers
Licensed under the NumPy License.
https://docs.scipy.org/doc/numpy-1.10.1/reference/swig.testing.html

Spec-Zone.ru

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