使用cython运行pytest-如何在pytest中编译cython模块?


问题内容

我有一个组织如下的项目:

project
├── project
│   ├── module1
│   │   ├── api.py
│   │   ├── _cpython_foo.py
│   │   └── _cython_foo.pyx
│   └── module2
├── setup.py
└── tests
    └── module1
        ├── test_cython_foo.py
        └── test_cpython_foo.py

其中,api.py进口cythonized扩展:

 """api.py""""
 from _cython_foo import cython_fun

我的安装脚本可以.pyx正确地就地构建源代码,并且可以cython_fun在已安装的软件包中使用它:

import project.module1.api as module1
module1.cython_fun()    # OK

但是,pytest它抱怨无法导入cython模块,因为在我调用安装程序之前,已编译的二进制文件不存在。

project/module1/api.py:2: in <module>
    from _cython_foo import cython_fun
E   ImportError: No module named _cython_foo

在我的项目目录中保留一堆pytest依赖的预编译二进制文件似乎是一种不好的风格,那么是否有常规方法让pytest临时构建cython模块仅用于我的单元测试?


问题答案:

我知道pytest与cythonized扩展结合的两种方式:

  1. 不要pytest直接通过调用测试;而是在安装脚本中使用就地测试命令。为此,请安装pytest-runner添加pytest命令的插件:
    $ pip install pytest-runner
    

现在,您应该可以pytest通过发出以下命令来调用测试

    $ python setup.py pytest

但是,这种方法将需要对传递命令行参数的方式进行一些更改:命令的挂件

    $ pytest --arg1 --arg2

将会

    $ python setup.py pytest --addopts "--arg1 --arg2"
  1. 如果要继续使用pytest命令:在开发模式下安装项目(最好在virtualenv中)。
    (myenv) $ pip install --editable dir/
    

dir/包含setup.py脚本的目录在哪里。现在,扩展将被预先构建,并且pytest能够解决它们。