Tutorial 5: Automated Testing / Linting
ASE WS 2023/24
Ziele
- Überblick Tools für Testing und Linting (Python)
- Praktische Anwendung der Tools
- Überblick Build Automation / Dokumentation / Testing
- Praktische Anwendung GitLab CI
Setup
Wir arbeiten dieses Mal mit einer lokalen Python-Installation
Alternativ kann man sich auch wie beim letzten Mal als Nutzer root
auf einem 'disposable root server' via segfault.net einloggen.
ssh root@segfault.net # Password is 'segfault'
Achtung: Der Server ist nicht sicher - keine vertraulichen Infos/Passwörter dort eintippen
Virtual Environments in Python
Es bietet sich an, für jedes Python-Projekt ein eigenes virtual environment zu verwenden.
Dazu wird in einem Unterverzeichnis des Projekts eine separate Python-Installation eingerichtet.
Ein Aktivierungs-Script setzt dann für die aktuelle Shell-Session die Pfade und Umgebungsvariablen so, dass nicht mehr die systemweite Python-Installation verwendet wird, sondern die im Unterverzeichnis installierte.
Wenn man mittels pip
neue Pakete installiert, werden diese auch nur im virtual environment (venv) installiert.
Das folgende Code-Beispiel installiert das venv-Modul, richtet ein venv im Unterverzeichnis “.env” ein und aktiviert dieses für den Rest der Session.
$ sudo apt install python3-venv [...] $ mkdir myproject; cd myproject $ python3 -m venv .myenv $ source .myenv/bin/activate
Alle folgenden Befehle verwenden jetzt die Python-Installation in .myenv
:
$ which python3 /home/me/myproject/.myenv/bin/python3
Meyer's Triangle Problem
Glenford J. Meyers, Corey Sandler, Tom Badgett (2015) The Art of Software Testing, John Wiley & Son, 1978/2004/2015
We want you to write a set of test cases—specific sets of data—to properly test a relatively simple program. Create a set of test data for the program—data the program must handle correctly to be considered a successful program. Here’s a description of the program:
The program reads three integer values from an input dialog. The three values represent the lengths of the sides of a triangle. The program displays a message that states whether the triangle is scalene (ungleichschenklig, ungleichseitig), isosceles (gleichschenklig), or equilateral (gleichseitig).Let's do it by hand
Erstelle eine Datei triangle.py
oder klone das Git Repo:
def triangle_shape(x, y, z): return None def triangle_circumference(x, y, z): return None def test_triangle(): # your code if __name__ == "__main__": import sys if sys.argv[1] == "--test": test_triangle() else: print(triangle_shape(sys.argv[1], sys.argv[1], sys.argv[3]))
(Achtung: es sind Syntax- und Logikfehler im Code)
- Bringe die Datei in einen lauffähigen Zustand.
- Wie können wir den Code robuster und testbarer machen?
Linting
Linter überprüfen den Code statisch auf Syntaxfehler und Verstöße gegen Style-Guides.
Hilfreich:
- pep8
- flake8
- mypy
Überprüfe den Code mit den Lintern und behebe Probleme
Testing
Ergänze test_triangle um notwendige Tests. Verwende dazu assert()
(siehe dieses Tutorial: https://realpython.com/python-assert-statement/)
pytest
pytest ist ein Test-Framework für Python
- Tests landen in einer separaten Datei, meist auch in einem separaten Unterverzeichnis:
mycode.py
→tests/test_mycode.py
pytest -v tests/test_mycode.py
führt alle Tests in der Datei aus.- Jeder Test wird als Funktion geschrieben:
def test_isoceles():
- Exception → fail
Beispiel:
def test_addition(): assert(1+1==2)
Wenn eine Exception erwartet wird:
def test_fails(): with pytest.raises(Exception): x = 1 / 0
Decorators sorgen dafür, dass Tests übersprungen werden:
@pytest.mark.skip("not yet finished") def test_something(): pass @pytest.mark.skipif(db is None, reason = "No database available") def test_db(): assert(db.status == 3)
Fixtures erlauben es, benötigten Code vorher auszuführen
@pytest.fixture def database(): db = DataBase(123) yield db db.close() def test_insert(database): database.insert(1)
Implementiere die notwendigen Tests und führe sie aus.
Weitere Ressourcen
- atinfo/awesome-test-automation - Sammlung von Ressourcen für verschiedene Programmiersprachen
- Selenium - Automatisierung von Interaktion mit Webseiten - nützlich für UI-Tests