Coverage - Frage

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
skylake87
User
Beiträge: 7
Registriert: Sonntag 24. Januar 2021, 13:46

Hallo,

ich habe ein Verständnisproblem mit Coverage.py. Ich habe zwei .py Dateien (eine mit einer einfachen Addition und eine test_x.py, die verschiedene Testfälle beinhaltet).

Wenn ich jetzt Coverage run und Report ausführe, erscheint bei cov lediglich 25% und ich habe keine Ahnung, warum. In Java beispielsweise bezieht sich die Coverageanzeige auf die durchgeführten Testfälle in der test_x. Datei. Dort kann ich direkt nachvollziehen, dass diese Datei als Grundlage verwendet wird. Bei Python sehe ich keine Systematik, wie dieser Coveragetest eigentlich funktioniert.

Könnte mir das jemand erklären?

Der Inhalt der Dateien ist folgender:
addition.py
def addition(a,b):
if a < 0:
return 0 # nur zum testen, ob Coverage die Zweige beachtet.
return a+b

test_addition.py
import unittest
from app import addition

class TestAddition(unittest.TestCase):
def test_addition(self):
self.assertEqual(addition(1,2),3)
def test_addition2(self):
self.assertEqual(addition(0,2),0)


Nach meinem Java-Verständnis müsste der Coveragetest durch den zweiten Testfall 100% sein. Er ist aber lediglich bei 25%

Name Stmts Miss Cover
----------------------------
app.py 4 3 25%
Benutzeravatar
__blackjack__
User
Beiträge: 13069
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@skylake87: Kann ich nicht nachvollziehen. Gezählt werden Anweisungen („statements“) und bei mir werden 3 der 4 Anweisungen abgedeckt:

Code: Alles auswählen

Name         Stmts   Miss  Cover
--------------------------------
forum23.py       4      1    75%
Was fehlt ist das ``return 0`` weil in keinem der Testfälle ein negatives `a` übergeben wird.

Apropos Testfälle: Java ist doof. Und damit auch das `unittest`-Modul. Das ist Java als Python verkleidet. In Python hat sich `pytest` durchgesetzt.

Damit sähe der Code so aus:

Code: Alles auswählen

from forum23 import addition


def test_addition():
    assert addition(1, 2) == 3


def test_addition2():
    assert addition(0, 2) == 0
Und da die beide im Grunde das gleiche machen, kann man eine Testfunktion parametrisieren:

Code: Alles auswählen

import pytest

from forum23 import addition


@pytest.mark.parametrize("a, b, expected", [(1, 2, 3), (0, 2, 0)])
def test_addition(a, b, expected):
    assert addition(a, b) == expected
Ausgabe des Testrunners:

Code: Alles auswählen

$ pytest test.py                                
============================= test session starts ==============================
platform linux -- Python 3.6.9, pytest-5.4.3, py-1.6.0, pluggy-0.13.1
rootdir: /home/bj
plugins: cov-2.10.0, hypothesis-4.43.5
collected 2 items                                                              

test.py .F                                                               [100%]

=================================== FAILURES ===================================
_____________________________ test_addition[0-2-0] _____________________________

a = 0, b = 2, expected = 0

    @pytest.mark.parametrize("a, b, expected", [(1, 2, 3), (0, 2, 0)])
    def test_addition(a, b, expected):
>       assert addition(a, b) == expected
E       assert 2 == 0
E        +  where 2 = addition(0, 2)

test.py:8: AssertionError
=========================== short test summary info ============================
FAILED test.py::test_addition[0-2-0] - assert 2 == 0
========================= 1 failed, 1 passed in 0.09s ==========================
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten