webentwicklung-frage-antwort-db.com.de

Wie verwende ich coverage.py in Python richtig?

Ich habe gerade mit der Verwendung des Coverage.py Moduls begonnen und mich daher entschlossen, einen einfachen Test durchzuführen, um zu überprüfen, wie es funktioniert.

Sample.py

def sum(num1, num2):
    return num1 + num2


def sum_only_positive(num1, num2):
    if num1 > 0 and num2 > 0:
        return num1 + num2
    else:
        return None

test.py

from sample import sum, sum_only_positive

def test_sum():
    assert sum(5, 5) == 10

def test_sum_positive_ok():
    assert sum_only_positive(2, 2) == 4

def test_sum_positive_fail():
    assert sum_only_positive(-1, 2) is None

Wie Sie sehen, ist mein gesamter Code mit Tests bedeckt und py.test sagt, dass alle bestanden wurden. Ich erwarte, dass Coverage.py eine 100% ige Abdeckung aufweist. Nun, nein.

Coverage.py results

Nun, Coverage.py kann die Datei test.py möglicherweise nicht sehen, also habe ich die Testfunktionen in die Datei sample.py Kopiert und Coverage erneut ausgeführt:
enter image description here

Dann habe ich diesen Codeblock hinzugefügt:

if __name__ == "__main__":
    print(sum(2, 4))
    print(sum_only_positive(2, 4))
    print(sum_only_positive(-1, 3))

und entfernte alle Testfunktionen. Danach zeigt Coverage.py 100%:

enter image description here

Wieso ist es so? Sollte Coverage.py nicht Code-Testabdeckung zeigen, nicht nur Ausführungsabdeckung? Ich habe ein offizielles F.A.Q. für Coverage.py gelesen, kann aber keine Lösung finden.
Da viele SO Benutzer mit Codetests und Codeabdeckung vertraut sind, hoffe ich, dass Sie mir sagen können, wo ich mich irre.

Ich habe hier nur einen Gedanken: Coverage.py kann einfach beobachten, welche Codezeilen nicht ausgeführt werden, also sollte ich Tests für diese Zeilen schreiben. Es gibt jedoch Zeilen, die bereits ausgeführt werden, aber nicht mit Tests abgedeckt sind, sodass Coverage.py hier fehlschlägt.

32
Groosha

Coverage sucht nach einer Coverage-Datei, um diesen Bericht zu lesen und für Sie zu generieren. Py.test alleine erstellt keine. Sie benötigen das py.test-Plugin für die Berichterstattung:

pip install pytest-cov

Wenn Sie es bereits haben, können Sie beide auf einmal wie folgt ausführen:

py.test test.py --cov=sample.py

Was bedeutet, dass Sie das Testmodul test.py Ausführen und den Abdeckungsbericht auf sample.py Aufzeichnen/anzeigen.

Wenn Sie mehrere Testläufe durchführen und deren aufgezeichnete Abdeckung sammeln und dann einen Abschlussbericht anzeigen müssen, können Sie diesen folgendermaßen ausführen:

py.test test.py --cov=sample.py --cov-report=
py.test test.py --cov=sample2.py --cov-report=
py.test test.py --cov=sample3.py --cov-report=

Das heißt, Testmodul test.py Ausführen und (nur) Berichterstattung auf sample.py Aufzeichnen - keinen Bericht anzeigen.

Jetzt können Sie den Coverage-Befehl separat für einen vollständigen Bericht ausführen:

coverage report -m

Der obige Befehl zeigt einfach einen formatierten Abdeckungsbericht an, der auf der akkumulierten .coverage-Datendatei aus früheren Testläufen basiert. -m Bedeutet, dass verpasste Zeilen angezeigt werden, d. H. Zeilen, die nicht von Tests abgedeckt werden:

Name        Stmts   Miss  Cover   Missing
-----------------------------------------
sample.py       6      0   100%  

Coverage unterstützt weitere Optionen wie --include Und --omit, Um Dateien mithilfe von Pfadmustern ein- oder auszuschließen. Weitere Informationen finden Sie in den zugehörigen Dokumenten: https://coverage.readthedocs.io/en/coverage-4.5.1/cmd.html#reporting

18
fips

Es ist etwas schwierig, Ihre Experimente zu analysieren, und Sie haben nicht die Befehlszeilen angegeben, die Sie bei jedem Experiment verwendet haben. Aber: wenn Sie die Tests ausführen mit:

python -m py.test test.py

dann kannst du sie unter coverage.py ausführen mit:

coverage run -m py.test test.py
10
Ned Batchelder