Если расширение является частью дистрибутива, вам не нужно ничего делать, кроме того, что poetry install
- poetry
создаст расширения на месте как часть редактируемой установки вашего проекта.
В других случаях вы можете встроить вызывающие команды distutils
в свои тесты как часть установки / разрыва комплекта. Я не очень знаком с nose
, но вот простой пример. Представьте, что у меня есть fib.pyx
(это пример из книги по Cython):
def fib(long n):
'''Returns the nth Fibonacci number.'''
cdef long a=0, b=1, i
for i in range(n):
a, b = a + b, a
return a
test_fib.py
модуль, который создает библиотеку fib
и удаляет ее при успешном выполнении тестов:
from distutils.dist import Distribution
from distutils.core import Extension
from pathlib import Path
from Cython.Build import cythonize
fib_source = Path('fib.pyx')
# distutils magic. This is essentially the same as calling
# python setup.py build_ext --inplace
dist = Distribution(attrs={'ext_modules': cythonize(fib_source.name)})
build_ext_cmd = dist.get_command_obj('build_ext')
build_ext_cmd.ensure_finalized()
build_ext_cmd.inplace = 1
build_ext_cmd.run()
fib_obj = Path(build_ext_cmd.get_ext_fullpath(fib_source.stem))
# the lib was built, so the import will succeed now
from fib import fib
def teardown_module():
# remove built library
fib_obj.unlink()
# if you also want to clean the build dir:
from distutils.dir_util import remove_tree
remove_tree(build_ext_cmd.build_lib)
remove_tree(build_ext_cmd.build_temp)
# sample tests
def test_zero():
assert fib(0) == 0
def test_ten():
assert fib(10) == 55
Возможно, вы настраиваете setup_kwargs
в пользовательском build.py
. Чтобы повторно использовать этот код, адаптируйте инициализацию dist
, например:
from build import build
setup_kwargs = {}
build(setup_kwargs)
dist = Distribution(attrs=setup_kwargs)
...
pytest
пример
Все может быть организовано намного удобнее с помощью pytest
. Создайте файл с именем conftest.py
с кодом установки / разрыва, извлеченным для хуков:
# conftest.py
from distutils.core import Extension
from distutils.dist import Distribution
from distutils.dir_util import remove_tree
from pathlib import Path
from Cython.Build import cythonize
def pytest_sessionstart(session):
fib_source = Path('fib.pyx')
dist = Distribution(attrs={'ext_modules': cythonize(fib_source.name)})
build_ext_cmd = dist.get_command_obj('build_ext')
build_ext_cmd.ensure_finalized()
build_ext_cmd.inplace = 1
build_ext_cmd.run()
session.fib_obj = Path(build_ext_cmd.get_ext_fullpath(fib_source.stem))
def pytest_sessionfinish(session):
session.fib_obj.unlink()
Теперь тесты становятся намного чище, и код установки запускается один раз для всего сеанса тестирования. Приведенный выше пример тестирования, вновь:
from fib import fib
def test_zero():
assert fib(0) == 0
def test_ten():
assert fib(10) == 55