Comment testez-vous différentes versions de Python avec Tox de l'intérieur Travis-CI ?
J'ai un tox.ini
:
[tox]
envlist = py{27,33,34,35}
recreate = True
[testenv]
basepython =
py27: python2.7
py33: python3.3
py34: python3.4
py35: python3.5
deps =
-r{toxinidir}/pip-requirements.txt
-r{toxinidir}/pip-requirements-test.txt
commands = py.test
qui exécute mes Python unittests dans plusieurs Python versions et fonctionne parfaitement).
Je veux configurer une build dans Travis-CI pour l'exécuter automatiquement lorsque je pousse des modifications vers Github, j'ai donc un .travis.yml
:
language: python
python:
- "2.7"
- "3.3"
- "3.4"
- "3.5"
install:
- pip install tox
script:
- tox
Cela semble techniquement fonctionner, mais il exécute de manière redondante tous mes tests dans chaque version de Python ... à partir de chaque version de Python. Donc, une construction qui prend 5 minutes prend maintenant 45 minutes.
J'ai essayé de supprimer la liste python
de mon fichier yaml, donc Travis n'exécutera qu'une seule Python, mais cela entraîne l'échec de mes tests Python3.5 car l'interpréteur 3.5 peut Apparemment, c'est un limitation connue car Travis-CI n'installera pas Python3.5 sauf si vous spécifiez cette version exacte dans votre configuration ... mais il ne le fait pas pour le autres versions.
Existe-t-il un moyen de contourner cela?
Pour cela, j'envisagerais d'utiliser tox-travis. Il s'agit d'un plugin qui permet d'utiliser les multiples versions de Travis CI python et la pleine configurabilité de Tox. Pour ce faire, vous allez configurer le fichier .travis.yml pour tester avec Python:
Sudo: false
language: python
python:
- "2.7"
- "3.4"
install: pip install tox-travis
script: tox
Cela exécutera les tests appropriés, qui sont tout env déclaré avec py27 ou py34 comme facteurs du nom par défaut. Py27 ou py34 seront utilisés comme solution de repli si aucun environnement ne correspond au facteur donné.
Pour plus de contrôle et de flexibilité, vous pouvez définir manuellement votre matrice afin que la version Python et l'environnement tox correspondent:
language: python
matrix:
include:
- python: 2.7
env: TOXENV=py27
- python: 3.3
env: TOXENV=py33
- python: 3.4
env: TOXENV=py34
- python: 3.5
env: TOXENV=py35
- python: pypy
env: TOXENV=pypy
- env: TOXENV=flake8
install:
- pip install tox
script:
- tox
Dans le cas où ce n'est pas évident, chaque entrée de la matrice commence sur une ligne qui commence par un trait d'union (-
). Tous les éléments suivant cette ligne qui sont en retrait sont des lignes supplémentaires pour cet élément unique.
Par exemple, toutes les entrées, à l'exception de la dernière, comportent deux lignes. la dernière entrée est une seule ligne et ne contient pas de paramètre python
; par conséquent, il utilise simplement la version par défaut Python (Python 2.7 selon la documentation de Travis). Bien sûr, une version spécifique Python n'est pas aussi importante pour cela). Si vous souhaitez exécuter un tel test sur les deux Python 2 et 3 (une fois chacun), il est recommandé d'utiliser les versions installées par défaut par Travis (2.7 et 3.4) afin que le les tests se terminent plus rapidement car ils n'ont pas besoin d'installer une version non standard Python en premier. Par exemple:
- python: 2.7
env: TOXENV=flake8
- python: 3.4
env: TOXENV=flake8
La même chose fonctionne avec pypy
(avant-dernière entrée sur la matrice) et pypy3
(non illustré) en plus de Python versions 2.5-3.6.
Bien que les diverses autres réponses fournissent des raccourcis qui vous donnent ce résultat à la fin, il est parfois utile de définir la matrice manuellement. Ensuite, vous pouvez définir des éléments spécifiques pour les environnements individuels au sein de la matrice. Par exemple, vous pouvez définir des dépendances pour un seul environnement et éviter le temps perdu à installer cette dépendance dans chaque environnement.
- python: 3.5
env: TOXENV=py35
- env: TOXENV=checkspelling
before_install: install_spellchecker.sh
- env: TOXENV=flake8
Dans la matrice ci-dessus, le install_spellchecker.sh
le script n'est exécuté que pour l'environnement concerné, mais pas pour les autres. Le before_install
a été utilisé (plutôt que install
), car l'utilisation du paramètre install
aurait remplacé le paramètre global install
. Cependant, si c'est ce que vous voulez (pour remplacer/remplacer un paramètre global), redéfinissez-le simplement dans l'entrée de la matrice. Il ne fait aucun doute que divers autres paramètres peuvent également être définis pour des environnements individuels au sein de la matrice.
La définition manuelle de la matrice peut offrir beaucoup de flexibilité. Cependant, si vous n'avez pas besoin de la flexibilité supplémentaire, l'un des divers raccourcis dans les autres réponses gardera votre fichier de configuration plus simple et plus facile à lire et à modifier plus tard.
Travis fournit la version python pour chaque test sous la forme TRAVIS_PYTHON_VERSION
, mais sous la forme '3.4'
, tandis que tox
attend 'py34'
.
Si vous ne voulez pas compter sur une bibliothèque externe (tox-travis) pour faire la traduction, vous pouvez le faire manuellement:
language: python
python:
- "2.7"
- "3.3"
- "3.4"
- "3.5"
install:
- pip install tox
script:
- tox -e $(echo py$TRAVIS_PYTHON_VERSION | tr -d .)
Recherchez ce modèle dans un moteur de recherche et vous trouverez de nombreux projets l'utilisant.
Cela fonctionne également pour Pypy:
tox -e $(echo py$TRAVIS_PYTHON_VERSION | tr -d . | sed -e 's/pypypy/pypy/')
Source: flask-mongoengine . Travis.yml .
TOXENV
La variable d'environnement peut être utilisée pour sélectionner un sous-ensemble de tests pour chaque version de Python via la matrice spécifiée:
language: python
python:
- "2.7"
- "3.4"
- "3.5"
env:
matrix:
- TOXENV=py27-Django-19
- TOXENV=py27-Django-110
- TOXENV=py27-Django-111
- TOXENV=py34-Django-19
- TOXENV=py34-Django-110
- TOXENV=py34-Django-111
- TOXENV=py35-Django-19
- TOXENV=py35-Django-110
- TOXENV=py35-Django-111
install:
- pip install tox
script:
- tox -e $TOXENV
Dans la configuration de tox, spécifiez pour ignorer les versions manquantes de Python:
[tox]
skip_missing_interpreters=true