2016-05-26 6 views
9

Das Problem:Mehrere Ausnahmen und Code-Coverage, wenn Unit-Tests Python

Hier ein künstliches Beispiel des im Test befindlichen Code ist:

from datetime import datetime 

def f(s): 
    try: 
     date = s.split(":")[1] 
     return datetime.strptime(date, "%Y%m%d") 
    except (ValueError, IndexError) as e: 
     # some code here 
     raise 

Hier ist eine Reihe von Tests I haben derzeit:

from datetime import datetime 
import unittest 

from test_module import f 

class MyTestCase(unittest.TestCase): 
    def test_valid_date(self): 
     self.assertEqual(f("1:20130101"), datetime(2013, 1, 1)) 

    def test_invalid_date(self): 
     self.assertRaises(ValueError, f, "1:invalid") 

der Test besteht, und wenn ich die Abdeckung mit dem --branch Flagge laufen, würde ich 100% -Linie erhalten und Zweigüberdeckung:

$ coverage run --branch -m unittest test 
.. 
---------------------------------------------------------------------- 
Ran 2 tests in 0.003s 

OK 
$ coverage report 
Name   Stmts Miss Branch BrPart Cover 
-------------------------------------------- 
test_module.py  7  0  0  0 100% 
-------------------------------------------- 
TOTAL    7  0  0  0 100% 

weist jedoch darauf hin, dass der Test derzeit nur zwei Fälle untersucht - wenn es keine Ausnahme ausgelöst, und es gibt eine ValueError Ausnahme ausgelöst.

Die Frage:

Gibt es eine Möglichkeit für coverage zu berichten, dass ich keinen Fall geprüft haben, wenn IndexError erhoben wird?

+0

Sie könnten einen anderen Ausnahmeblock für IndexError haben. Ich denke, die Berichterstattung zählt nur, welche Zeilen ausgeführt wurden. –

Antwort

8

Coverage.py kann nur messen, welche Ausführungspfade (Anweisungen oder Verzweigungen) ausgeführt wurden. Es gibt keine Möglichkeit zu verfolgen, welche Werte verwendet wurden, einschließlich welcher Ausnahmetypen ausgelöst wurden.

Wie ich es sehe, Ihre Optionen sind:

  1. Trennen Sie die Ausnahmeklauseln. In dem Code, den Sie gezeigt haben, könnten die zwei Ausnahmen trotzdem durch separate Zeilen ausgelöst werden, obwohl sie vielleicht in Ihrem echten Code nicht so trennbar sind.

  2. Mach dir keine Sorgen über die zwei Ausnahmen. Ihre Tests für diesen Code werden wahrscheinlich eine Reihe verschiedener Eingaben berücksichtigen, die entwickelt wurden, um verschiedene Randfälle auszuüben. Coverage.py kann Ihnen nicht dabei helfen, zwischen allen zu unterscheiden oder sicherzustellen, dass Sie genügend Fälle geschrieben haben. Verwenden Sie andere Kriterien, um zu entscheiden, dass Sie genügend Testfälle geschrieben haben.

+0

Okay, vielen Dank. Viel Glück mit deinem Vortrag auf PyCon! – alecxe

1

Ich denke, Sie können mit zwei separaten Ausnahmen für die zwei Ausnahmen versuchen. In diesem Fall zeigt die Linienabdeckung an, dass Sie keine Bedingung getestet haben.

from datetime import datetime 

def f(s): 
    try: 
     date = s.split(":")[1] 
     return datetime.strptime(date, "%Y%m%d") 
    except ValueError as e: 
     # some code here 
     raise 
    except IndexError as e: 
     # some code 
     raise 

Wenn Sie Ihren Code nicht wiederholen möchten, können Sie möglicherweise eine Funktion dafür verwenden.

+0

Das ist definitiv eine Option, aber meine Neugier hat immer noch diese Frage, wenn Coverage (oder ein anderes Paket) den nicht getesteten Ausführungspfad bestimmen würde, ohne den getesteten Code zu ändern. Vielen Dank! – alecxe