Mein Name ist @giginet und ich bin verantwortlich für den 25. Tag des Python-Adventskalenders. Es ist der letzte Tag, also habe ich es geschafft, es zu schreiben, um nicht zu spät zu kommen.
Neulich habe ich ein einfaches Plug-In für Django entwickelt. Als ich eine CI-Umgebung erstellte, um die Unterschiede zwischen Python 2 und 3 auszugleichen und das implementierte Plug-In in mehreren Umgebungen zu testen, gab es viele süchtig machende Punkte, daher werde ich es bei dieser Gelegenheit zusammenfassen.
In diesem Artikel werde ich Ihnen zeigen, wie Sie mit Travis CI Tests in mehreren Python-Versionen ausführen, um die Abdeckung zu messen.
Implementieren Sie zunächst das einfache Modul, das Sie testen möchten. Dieses Mal habe ich calculator.py
in das Modul calculator
gestellt und die Klasse Calculator
implementiert.
Dieses Mal wird davon ausgegangen, dass der gesamte Code in Python3 implementiert wird.
calculator/calculator.py
class Calculator(object):
@staticmethod
def power(number):
return number * number
Implementieren Sie als Nächstes den Testfall. Hier testen wir einfach, ob Calculator # power
funktioniert.
tests/test_calculator.py
from unittest import TestCase
from calculator.calculator import Calculator
class CalculatorTestCase(TestCase):
def setUp(self):
self.calculator = Calculator()
def test_power(self):
self.assertEqual(self.calculator.power(12), 144)
Untersuchen Sie nun den Testfall, den Sie geschrieben haben, und schreiben Sie ein Skript, um den Test auszuführen.
Wenn Sie über Python 2.7 oder höher verfügen, können Sie problemlos nach Testfällen suchen und Tests wie folgt ausführen.
$ python -m unittest discover
Wenn Sie auch Python 2.6 und niedriger testen, enthält das Standardmodul "unittest" kein "Discover", um nach Testfällen zu suchen. Daher müssen Sie stattdessen ein Paket namens "unittest2" installieren.
requirements-test.txt
unittest2
$ pip install -r requirements-test.txt
Mit unittest2
habe ich ein Skript implementiert, das Testfälle wie folgt sucht und ausführt.
runtest.py
#!/usr/bin/env python
import unittest2 as unittest
if __name__ == "__main__":
suite = unittest.TestLoader().discover('tests', pattern = "test_*.py")
unittest.TextTestRunner().run(suite)
Wenn Sie dies tun, wird der Test wie unten gezeigt ausgeführt.
$ chmod +x runtest.py
$ ./runtest.py
.
----------------------------------------------------------------------
Ran 1 tests in 0.001s
OK
Lassen Sie uns als Nächstes diesen Testfall in mehreren Umgebungen ausführen.
** tox ** ist eine bekannte einfache Möglichkeit, eine Quelle mit mehreren Versionen von Python oder Django zu testen.
Welcome to the tox automation project — tox 2.3.1 documentation
tox ist ein Tool, mit dem Sie eine Testumgebung erstellen können, indem Sie verschiedene Bedingungen ändern und Tests in mehreren Umgebungen gleichzeitig ausführen.
Sie können eine Testumgebung erstellen, indem Sie eine Einstellungsdatei mit dem Namen "tox.ini" definieren. Dieses Mal definieren wir sie wie folgt.
tox.ini
[tox]
skipsdist = True
envlist =
py26,
py27,
py33,
py34,
py35
[testenv]
deps=
-rrequirements-test.txt
commands=
./runtest.py
Weitere Informationen finden Sie in der Dokumentation.
tox configuration specification — tox 2.3.1 documentation
Schließlich können Sie mit "tox" alle Testumgebungen gleichzeitig ausführen.
Dieses Mal werde ich den Test nur mit Python 3.5 ausführen, um den Vorgang zu überprüfen.
$ tox -r -e 'py35'
Sie haben jetzt eine Testumgebung erstellt, die mehrere Python-Versionen unterstützt.
Lassen Sie uns dies nun auf Travis CI ausführen.
Dieses Mal werden wir ein Modul namens "tox-travis" verwenden.
Mit dieser Option können Sie die Einstellungen für die Ausführung von Tox auf Travis CI weglassen.
Sie können den Test beispielsweise in mehreren Umgebungen ausführen, indem Sie ".travis.yml" wie unten gezeigt vorbereiten.
yaml:.travis.yml
sudo: false
language: python
python:
- 2.6
- 2.7
- 3.3
- 3.4
- 3.5
install:
- pip install tox tox-travis
- pip install coverage coveralls
script:
- tox -r
Wenn Sie dies auf Travis CI tun, werden mehrere Container zum einfachen Testen gestartet, wie unten gezeigt. Es ist bequem.
Um den für Python3 geschriebenen Code auf Python2 auszuführen, müssen Sie das Modul __future__
usw. verwenden und abwärtskompatibel schreiben.
Weitere Informationen finden Sie in der Dokumentation, da dieser Artikel nicht im Detail behandelt wird.
Easy, clean, reliable Python 2/3 compatibility — Python-Future documentation
Wenn Sie mit Mock oder Stub testen möchten, enthält Python 3 ein Mock-Modul in der Standardbibliothek.
26.5. unittest.mock — mock object library — Python 3.5.1 documentation
Andererseits kann Mock vor Python2 nicht standardmäßig in der Umgebung verwendet werden.
Es gibt ein Paket, das das Python3-Mock-Modul vor 2 zurückportiert. Lassen Sie uns es also vorstellen.
requirements-test.txt
mock
Versuchen Sie zunächst zu prüfen, ob "unittest.mock" importiert werden kann. Wenn es nicht in der Standardbibliothek enthalten ist, importieren Sie es aus der "mock" -Bibliothek.
from unittest import TestCase
try:
from unittest.mock import MagicMock
except ImportError:
from mock import MagicMock
class CalcTestCase(TestCase):
def test_mock(self):
mock_object = MagicMock()
mock_object.__str__.return_value = 'hello'
self.assertEqual(str(mock_object), 'hello')
Auf diese Weise können Sie Mock-Tests sowohl für Python 2 als auch für Python 3 durchführen.
Einzelheiten zur Verwendung von Mock finden Sie im Folgenden.
Python --Mock Mock ~ unittest.mock, mock.mock revisit ~ --Qiita
Wenn der Test in allen Umgebungen erfolgreich ist, messen Sie schließlich die Abdeckung und verwalten Sie sie mit coverails.
Messen Sie zunächst die Abdeckung, indem Sie "Abdeckung" in "tox.ini" wie folgt ausführen.
tox.ini
deps=
-rrequirements-test.txt
coverage
commands=
{envbindir}/coverage run --append --source=calculator runtest.py
Wenn Sie zu diesem Zeitpunkt eine Datei mit dem Namen ".coveragerc" definieren, können Sie die Regeln für die Abdeckungsmessung festlegen. Im Folgenden werden Dateien und Zeilen definiert, für die keine Abdeckungsmessung durchgeführt wird.
Siehe unten für Details.
Configuration files — Coverage.py 4.0.3 documentation
.coveragerc
[report]
include =
calculator/*.py
omit =
calculator/__init__.py
exclude_lines =
pragma: no cover
if __name__ == .__main__.:
Fügen Sie abschließend Folgendes zu ".travis.yml" hinzu, damit das Protokoll nach Abschluss des Tests an "coveralls" gesendet wird.
yaml:.travis.yml
install:
- pip install tox tox-travis
- pip install coverage coveralls
after_success:
- coverage report
- coveralls
Sie können die Berichterstattung jetzt in Overalls aufzeichnen.
In diesem Artikel habe ich kurz zusammengefasst, wie Python-Bibliotheken mit mehreren Versionen getestet werden.
Die diesmal eingeführte Testsuite wird im folgenden Repository kurz zusammengefasst.
https://github.com/giginet/python-ci-suite
Sie können tox
auch gut verwenden, um eine Bibliothek in mehreren Versionen zu testen.
Die folgenden Django-Plugins werden mit mehreren Versionen von Python- und Django-Kombinationen getestet. Wenn Sie interessiert sind, beziehen Sie sich bitte darauf.