Seite 1 von 1

wie geht Pytest auf exception-handler ?

Verfasst: Dienstag 10. März 2020, 20:33
von HeinzBacker
Grüß dich!

Ich will gerade einen ersten Pytest ausführen und zwar soll auf eine ungültige Datei beim Dateiöffnen geprüft werden.
Normalerweise wird die FileNotFoundError-Exception geworfen, aber der Test schlägt trotzdem fehl.
Ich würde gern verstehen, warum es nicht geht (unten ist die Ausgabe).
Vielen Dank schonmal für Tipps!



Programm code:
file_handler.py

Code: Alles auswählen

class Filehandler():
    def __init__(self):
        pass

    def read_file(filename_str):
        lines = []
        try:
            with open(filename_str, 'r', encoding="utf8") as f_in:
                lines = f_in.readlines()
        except FileNotFoundError:
            pass



Pytest code:

Code: Alles auswählen

import pytest
from file_handler import Filehandler


def test_file_handler_0():
    with pytest.raises(FileNotFoundError):
        Filehandler.read_file("invalid_file.x")



Die Ausgabe ist dann :

plugins: html-2.0.1, metadata-1.8.0
collected 1 item

test_file_handler.py F [100%]

============================================================================================== FAILURES ===============================================================================================
___________________________________________________________________________________________ test_file_handler_0 ____________________________________________________________________________________________

def test_file_handler_0():
with pytest.raises(FileNotFoundError):
> Filehandler.read_file("invalid_file.x")
E Failed: DID NOT RAISE <class 'FileNotFoundError'>

test_file_handler.py
:19: Failed
---------------------------------------------------------------------------------------- Captured stdout call -----------------------------------------------------------------------------------------
------------------------------------------------------------------ generated html file: file://C:\py\report_test_file_handler.html ------------------------------------------------------------------
========================================================================================== 1 failed in 0.06s ==========================================================================================

Re: wie geht Pytest auf exception-handler ?

Verfasst: Dienstag 10. März 2020, 20:56
von Sirius3
`read_file` fängt die Exception ja ab, und ignoriert sie, die kann also pytest gar nicht erreichen.
Zur Klasse, das ist keine, erstens, weil sie nur aus einer Funktion besteht und keinen Zustand hat, zweitens, weil die eine Methode kein `self` enthält und weil Du drittens gar keine Instanz erzeugst, sondern die "Methode" direkt aufrufst. `lines` wird mit einem Wert initialisiert, der im Normalfall ignoriert wird, die leere Liste sollte aber nur im Ausnahmefall erzeugt werden (oder gar nicht, wenn die Methode die Exception werfen soll, wie in Deinem Test gefordert).
Datentypen haben in Variablennamen nichts verloren, weder das str in filename_str, noch das f in f_in.

Re: wie geht Pytest auf exception-handler ?

Verfasst: Dienstag 10. März 2020, 21:10
von __blackjack__
`handler` als Namensteil ist auch ein Warnzeichen das man etwas javaesques macht. In wenigen Fällen ist der Namenszusatz gerechtfertigt, hier eher nicht.

Re: wie geht Pytest auf exception-handler ?

Verfasst: Dienstag 10. März 2020, 21:49
von HeinzBacker
Sirius3 hat geschrieben: Dienstag 10. März 2020, 20:56 `read_file` fängt die Exception ja ab, und ignoriert sie, die kann also pytest gar nicht erreichen.
Zur Klasse, das ist keine, erstens, weil sie nur aus einer Funktion besteht und keinen Zustand hat, zweitens, weil die eine Methode kein `self` enthält und weil Du drittens gar keine Instanz erzeugst, sondern die "Methode" direkt aufrufst. `lines` wird mit einem Wert initialisiert, der im Normalfall ignoriert wird, die leere Liste sollte aber nur im Ausnahmefall erzeugt werden (oder gar nicht, wenn die Methode die Exception werfen soll, wie in Deinem Test gefordert).
Datentypen haben in Variablennamen nichts verloren, weder das str in filename_str, noch das f in f_in.
warum gibts dann Pytest wenn man sowas nicht testen kann. Oder wie soll man das sonst testen?

Wegen der Klasse: ja, du hast da recht. Soll hier nur auf das Wesentliche heruntergebrochen sein.

Datentypen: jeder, der den code im Nodepad anguckt soll auch verstehen, um welchen Datentyp es sich handelt. Daher das Postfix überall. Ich finds besser.

Re: wie geht Pytest auf exception-handler ?

Verfasst: Dienstag 10. März 2020, 22:25
von sparrow
Man braucht keine Namenszusätze, wenn man seinen Variablen vernünftige Namen gibt. 'f_in' kann niemand einordnen, 'file' hingegen schon.
Und was soll denn ein 'filename' anderes sein als eine Zeichenkette?
Da solltest du dich von Dingen lösen, die du möglicherweise von anderen Sprachen kennst.

Wie soll Pytest denn etwas testen, das du absichtlich ignorierst? Wenn du willst, dass ein Fehler gefunden wird, dann darfst du ihn nicht abfangen oder musst ihn mit raise weiterreichen. Aber den Fehler zu fangen und dann einfach nichts zu tun lässt den Fehler logischerweise verschwinden.

Re: wie geht Pytest auf exception-handler ?

Verfasst: Dienstag 10. März 2020, 22:38
von HeinzBacker
sparrow hat geschrieben: Dienstag 10. März 2020, 22:25

Wie soll Pytest denn etwas testen, das du absichtlich ignorierst? Wenn du willst, dass ein Fehler gefunden wird, dann darfst du ihn nicht abfangen oder musst ihn mit raise weiterreichen. Aber den Fehler zu fangen und dann einfach nichts zu tun lässt den Fehler logischerweise verschwinden.
achso, das

Code: Alles auswählen

except FileNotFoundError
verhält sich also wie ein else-Pfad in den gesprungen wird.
Darin sollte man dann etwas unternehmen... (eine Fehlerausgabe mit print?).
ich dachte es gäbe im System noch sowas wie einen Interrupt auf eine Exception-Hook, die der Pytest dann registrieren kann - also davon Notiz bekommt.

Danke

Re: wie geht Pytest auf exception-handler ?

Verfasst: Dienstag 10. März 2020, 22:47
von sparrow
Das offizielle Tutorial hat einen Abschnitt zu Exceptions.

Wenn du eine Ausnahme fängst, musst du sie so abarbeiten, dass das Programm hinterher stabil bzw. kontrolliert weiter läuft. Wenn du das nicht tust oder kannst (weil der Programmfluss es nicht zulässt) dann kannst du dir das fangen der Exception auch sparen. Dann tritt die Aufnahme auf, wird nach oben gereicht und das Programm bricht ab.

Re: wie geht Pytest auf exception-handler ?

Verfasst: Dienstag 10. März 2020, 22:50
von __blackjack__
@HeinzBacker: Wenn Du keine Ahnung hast was Du in der Ausnahmebehandlung eigentlich machen willst, dann lass doch um Himmels willen die Ausnahmebehandlung einfach bleiben. Denn eine `print()`-Ausgabe ist hier sicher keine sinnvolle “Behandlung“, denn wie soll der Aufrufer denn dann wissen das da etwas nicht geklappt hat und darauf reagieren?

`str` ist ein sehr komischer Namenszusatz für ein `bytes`-Objekt. Oder ein `bytearray`-Objekt. Oder ein `pathlib.Path`-Objekt. Oder ein `os.PathLike`-Objekt. Oder irgendein anderes Objekt mit einer `__fspath__()`-Methode. Grunddatentypen in Namen sind oder werden halt sehr schnell *falsch* und damit irreführend. Wenn Du „duck typing“ nicht magst, nimm halt kein Python…

Re: wie geht Pytest auf exception-handler ?

Verfasst: Mittwoch 11. März 2020, 08:23
von Sirius3
HeinzBacker hat geschrieben: Dienstag 10. März 2020, 21:49 warum gibts dann Pytest wenn man sowas nicht testen kann. Oder wie soll man das sonst testen?
Testen muß man ja nur das, was der Anwender auch zu Gesicht bekommt, Du „behandelst“ aber den Fehler, und der Nutzer bekommt nichts mehr davon mit, also kann und muß man das auch nicht testen.
HeinzBacker hat geschrieben: Dienstag 10. März 2020, 21:49Datentypen: jeder, der den code im Nodepad anguckt soll auch verstehen, um welchen Datentyp es sich handelt. Daher das Postfix überall. Ich finds besser.
Vom Datentyp allein kann ein Nutzer nicht wissen, was gemeint ist. Wenn `filename` nicht ausreicht, um den richtigen Inhalt an die Funktion zu übergeben, dann braucht es bessere Variablennamen oder bessere Dokumentation. Wenn man sich zu sehr auf Datentypen konzentriert, dann kann man kein Verständnis für das Programm entwickeln.