在travis中安装和测试python项目

时间:2018-12-01 13:58:26

标签: python pip travis-ci

我有这样的文件结构:

./
    project_name/
        __init__.py
    setup.py
    tests/
    .travis.yml

所以我在.travis.yml中运行py.test。根据我安装软件包的方式,它可能会起作用,或者会遇到错误。

如果我使用pip install -e .安装软件包,那一切都很好,但是这样做的缺点是不是现实的安装方案。

如果我使用pip install .安装该软件包,则该软件包的安装方式与在非dev模式下的另一台计算机上的安装方式相同。但是,会出现问题:运行pytest时,我的测试使用import project_name。然后,python从目录本地导入而不是使用已安装的软件包,从而导致ImportMismatchError

解决这个问题的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

一种解决方案可能是在顶层创建一个名为tox.ini的文件以与tox一起使用。这是一个负责构建环境的工具-类似于make,但更特定于python工具。如果您创建tox.ini

[tox]
envlist = py

[testenv]
commands = pytest tests
deps =
    pytest

然后使用tox安装pip3 install tox,然后在命令行中仅使用命令tox,它将负责安装软件包并在隔离的虚拟环境中运行测试。

然后,您可以在travis.yml内部进行此操作:

language: python
python:
  - 3.6
install:
  - pip install tox
script:
  - tox

Travis将使用tox以更可重复的方式运行测试。

答案 1 :(得分:1)

如果要对已安装的代码运行测试,则需要一个包含所有将要安装的源代码的中间目录(而不是软件包)。其通用名称就是src。示例布局:

project_root
├── src
│   ├── spam
│   │   ├── __init__.py
│   │   └── eggs.py
│   └── ...
├── tests
│   ├── test_spam.py
│   └── ...
└── setup.py

调整设置脚本以遵守src目录:

# setup.py

from setuptools import setup, find_packages

setup(
    name='spam',
    ...
    packages=find_packages('src'),
    package_dir={'': 'src'},
    ...
)

采用这种布局,尽管当前目录(project_root)仍添加到sys.path,但是所有软件包都无法导入。这样,您被迫安装软件包以能够调用测试,并且始终在测试已安装的代码。通常,您在编写代码时通过pip install --editable .在本地计算机上以开发模式安装软件包,然后通过pip install .在CI服务器上安装软件包,然后将在实际的软件包安装中执行测试。另一个优点是,这种布局不允许您在安装脚本中导入软件包的源代码,并且在安装时不会遇到鸡问题(要安装代码,必须已经安装代码)。

如果您有松散的模块,我更喜欢使用pathlib

py_modules=[p.name for p in pathlib.Path('src').glob('*.py')]

如果您仍然需要Python 2兼容性,则解决方案应如下所示:

py_modules=[os.path.splitext(os.path.basename(p))[0] for p in glob.glob("src/*.py")]