P. *_*eri 12 python unit-testing cython
我有一个.pyx文件,我在其中定义了一些函数,例如
cdef double foo(double a) nogil:
return 3. * a
Run Code Online (Sandbox Code Playgroud)
我怎样才能在pyx文件之外对这些函数的行为进行单元测试?由于它们是cdef'd,我无法简单地导入它们......
ead*_*ead 11
要测试cdef功能,你需要在Cython中编写测试.人们可以尝试使用cpdef-functions,但是并不是所有的签名可以在这种情况下使用(使用像指针例如签名int *,float *等等).
要访问cdef函数,您需要通过pxd文件"导出"它们:
#my_module.pyx:
cdef double foo(double a) nogil:
return 3. * a
#my_module.pxd:
cdef double foo(double a) nogil
Run Code Online (Sandbox Code Playgroud)
现在可以在Cython测试器中进行功能和测试:
#test_my_module.pyx
cimport my_module
def test_foo():
assert my_module.foo(2.0)==6.0
print("test ok")
test_foo()
Run Code Online (Sandbox Code Playgroud)
现在
>>> cythonize -i my_module.pyx
>>> cythonize -i test_my_module.pyx
>>> python -c "import test_my_module"
test ok
Run Code Online (Sandbox Code Playgroud)
从哪里开始取决于您的测试基础设施.
例如,如果你使用unittest-module,那么你可以使用pyximport来cythonize /加载测试模块检查它并将所有测试用例转换为unittest-test情况或unittest直接在你的cython代码中使用(可能是一个更好的解决方案).
以下是对以下内容的概念证明unittest:
#test_my_module.pyx
cimport my_module
import unittest
class CytTester(unittest.TestCase):
def test_foo(self):
self.assertEqual(my_module.foo(2.0),6.0)
Run Code Online (Sandbox Code Playgroud)
现在我们只需要翻译并在纯python中导入它就可以了unittest:
#test_cy.py
import pyximport;
pyximport.install(setup_args = {"script_args" : ["--force"]},
language_level=3)
from test_my_module import *
import unittest
Run Code Online (Sandbox Code Playgroud)
现在:
>>> python -m unittest test_cy.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Run Code Online (Sandbox Code Playgroud)
顺便说一下,没有必要明确地对pyx-modules进行cython化 - pyximport自动为我们做.
一句警告:将 pyximport cythonized c-files缓存~/.pyxbld(或类似于其他操作系统),只要test_my_module.pyx没有更改,扩展就不会重建.这可能是一个问题,当my_module更改并导致二进制不兼容时(幸运的是python警告,如果是这种情况).
必须确保在测试环境中重建pyx文件(它是基于时间戳的)或者删除缓存文件(可以使用临时目录,例如使用setup_args = {"script_args" : ["--force"]}via 创建tempfile.TemporaryDirectory()).
如果您使用虚拟环境并通过pyximport.install(build_dir=...)(或类似的工作流程)安装cython-package ,则需要确保language_level文件也包含在安装中,即您的安装文件需要增加:
from setuptools import setup, find_packages, Extension
# usual stuff for cython-modules here
...
kwargs = {
# usual stuff for cython-modules here
...
#ensure pxd-files:
'package_data' : { 'my_module': ['*.pxd']},
'include_package_data' : True,
'zip_safe' : False #needed because setuptools are used
}
setup(**kwargs)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1068 次 |
| 最近记录: |