Skip to content
ohinckel edited this page Jan 8, 2018 · 10 revisions

Tests

Um sicherzustellen, dass Funktionen innerhalb von SmartHomeNG während der Weiterentwicklung und evtl. Umstrukturierungen weiterhin funnktionieren, werden sogenannte Unittests geschrieben. Diese sind, ebenfalls wie alles andere in SmartHomeNG, in Python programmiert.

Bei der Weiterentwicklung von SmartHomeNG sollten die Tests nach jeder Änderung ausgeführt. Dadurch kann sichergestellt werden, dass bestehende Funktionalität weiterhin fehlerfrei funktioniert und eventuelle Fehler frühzeitig erkannt werden.

Ausführung

Die Ausführung der Tests basiert auf zwei Technologien:

  • pytest - Framework für die Testausführung
  • tox - Utility für unterschiedliche Testsläufe

pytest

Die Tests werden mittels pytest (siehe Doku) ausgeführt. Dies ist ein Framework mit dem Tests strukturiert abgelegt und in unterschiedliche Dateien verteilt werden koennen. Das Framework bietet weiterhin Funktionen an mit denen diverse Testszenarien geprüft werden können (Assertions).

tox

Das Utility tox wird verwendet um pytest auszuführen. Es unterstützt allerdings auch noch weitere Features: so kann z.B. ein sogenannter Build erzeugt werden in dem unterschiedliche "Environments" konfiguriert werden die unterschiedliche Aufgaben erledigen können. Ausserdem kann eingestellt werden, wie die Test-Discovery durchgeführt werden soll und für welche Python Versionen Tests ausgeführt werden sollen.

Damit ist es möglich die Ausführung so zu gestalten, dass einerseits eine Umgebung für die direkte Ausführung der Tests vorhanden ist, andererseits auch eine Umgebung für einen Syntax-Check (flake) oder sogar eine Umgebung um einen Dokumentationsbuild zu starten.

Bei SmartHomeNG wird allerdings nur die Ausführung der Tests sowie (bei bedarf, und daher auskommentiert in der Konfiguration) des Syntax-Checks (flake).

Ausführung in der Konsole

Möchte man die Tests nach einer Weiterentwicklung ausführen, so muss der Befehl tox ausgeführt werden. Damit wird das Utility tox gestartet, welches standardmäßig pytest ausführt.

Ein Testlauf sieht so aus:

$ tox
[...]
============================= test session starts ==============================
platform linux -- Python 3.3.6, pytest-2.9.2, py-1.5.2, pluggy-0.3.1 -- /home/travis/build/smarthomeNG/smarthome/.tox/py33/bin/python3.3
cachedir: .cache
rootdir: /home/travis/build/smarthomeNG/smarthome, inifile: tox.ini
plugins: cov-2.5.1, timeout-1.2.1, betamax-0.5.1
timeout: 30.0s method: signal
collected 219 items 
tests/test_config.py::TestConfigConf::test_confread_ignores_empty_name PASSED
tests/test_config.py::TestConfigConf::test_confread_lists_spaces PASSED
tests/test_config.py::TestConfigConf::test_confread_multiline PASSED
[...]
plugins/database/tests/test_single.py::TestDatabaseSingle::test_single_returns_last_value_outside_range PASSED
plugins/database/tests/test_single.py::TestDatabaseSingle::test_single_sum PASSED
==================== 218 passed, 1 skipped in 21.50 seconds ====================
___________________________________ summary ____________________________________
  py33: commands succeeded
  congratulations :)

Diese Ausführung verwenden den aktuell ausgecheckten Quellcode und Branch. D.h. befindet man sich aktuell in develop Branch, so werden die Tests darin ausgeführt.

Die Konfiguration wird in der Datei tox.ini:

  • Sektion pytest legt allgemeine Einstellungen fuer pytest fest: Pfade oder Namenschema für Test-Dateien, Test-Funktionen und Test-Klassen
  • Sektion testenv legt eine auszuführende Testumgebung fest: Umgebungsvariablen, pytest-Kommando, notwendige Dependencies

Aufteilung der Tests

SmartHomeNG besteht aus zwei Bereichen: Code und Plugins. Für beide Bereiche gibt es bzw. kann es Tests geben, die getrennt voneinander abgelegt werden.

Tests für Core

Die Tests für den SmartHomeNG Core liegen direkt im Hauptverzeichnis im Verzeichnis tests. Das Verzeichnis hat folgende Struktur:

  • mock - Verzeichnis in dem Teile des Core als Mocks (keine reale Implementierung von Klassen, sondern nur leere Hülsen)
  • resources - Verzeichnis in denen Dateien abgelegt werden die für die Ausfürhung von Tests notwendig sind (z.B. eigene items.yaml).
  • test_XXXX.py - Dateien in denen Tests für XXX implementiert sind (z.B. test_config.py)

Wenn Teile des Cores getestet werden sollen, empfiehlt es sich diese in einer entsprechenden Datei abzulegen. So sind Tests fuer das einlesen der Konfiguraton (Implementierung in lib/config.py) in einer Datei mit dem Namen test_config.py abgelegt. Oder Tests für Funktionen aus lib/utils.py liegen demnach in test_util.py.

Bei der Ausfürhung der Tests werden dort alle Tests berücksichtig, die im tests/ Verzeichnis liegen und dem Namensschema test_XXX.py entsprechen. Die eigentlichen Testfunktionen muessen dem Schema test_XXX() entsprechen.

Beispiel:

import unittest

class ExampleTests:

    def test_XXX(self):
        # execute some code, an verify results
        self.assertEqual(1, ...)
        self.assertFalse('123' in ...)

Tests für Plugins

Genauso wie es sich auch für Core Tests verhält, verhält es sich auch bei den Plugin-Tests. Diese Tests werden in das Plugin-Verzeichnis in tests abgelegt. Sobald auch hier Tests vorhanden sind, werden diese automatisch ausgeführt. Auch die Namenskonvention ist identisch (Dateien nach dem Schema test_XXX.py, Funktionen nach dem Schnema test_XXX()) und die Verzeichnisstruktur sollte beibehalten werden (mock, resources - falls notwendig).

Werden die Tests für Plugins umfangreicher, empfiehlt es sich diese in separate Dateien aufzuteilen um den Überblick zu vereinfachen. Gleicher Code kann auch in eine eigene Datei oder Module ausgelagert und in den jeweiligen Testdateien eingebunden werden.

Travis-CI

Damit die Tests automatisch bei jeder Änderung des Codes ausgeführt werden, ohne dass dies manuell angestoßen werden muss, wird Travis-CI verwendet. Dort sind beide Bereiche von SmartHomeNG eingebunden um die Tests automatisiert auszuführen:

Konfiguration

Damit Travis-CI weiss, was zur Ausführung der Tests ausgeführt werden soll, gibt es in jedem Repository eine Konfigurationsdatei mit dem Namen .travis.yml. Dort ist beispielsweise hinterlegt, dass die Tests mit tox ausgeführt werden sollen, dass sie mit bestimmten Python Versionen ausgeführt werden sollen, oder dass es sich um ein Python-Projekt handelt (Travis-CI kann prinzipiell alle Arten von Projekten und Programmiersprachen unterstützen).

Einstellungen in .travis.yml (und deren Wert):

  • language - legt die Programmiersprache fest (python)
  • python - enthät eine Liste von Python-Versionen die ausgeführt werden sollen (Liste mit 3.3 bis 3.5)
  • before_install - konfiguriert ein oder mehrere Befehle die vor install ausgeführt werden (git Kommando um Submodule zu initialisieren)
  • install - konfiguriert ein oder mehrere Befehle die vor der eigentlichen Ausführung ausgeführt werden (pip Kommando um Requirements zu installieren, tox-travis, virtualenv)
  • script - definiert das eigentlich auszuführende Skript (Ausführung von tox)

Travis-CI für damit die Tests für alle angegebenen Python-Versionen aus. Durch die Angabe von mehreren Python-Versionen wird eine Ausführungsmatrix bei Travis-CI erzeugt, die alle Versionen beinhalten. Eine solche Ausführungsmatrix kann auch durch andere Parameter (wie z.B. Definition von Umgebungsvariablen) erzeugt werden.