2016-05-26 17 views
9

Problem:Wiele wyjątki i pokrycie kodu podczas testów jednostkowych pyton

Oto sztuczny przykład kodu badanego:

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 

Oto zestaw testów Obecnie mam:

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") 

Test przechodzi, a jeśli biegnę pokrycia z flagą --branch, chciałbym uzyskać 100% linii i zasięg oddział:

$ 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% 

Należy jednak pamiętać, że test bada obecnie tylko dwa przypadki - gdy nie ma wyjątków rzucony, a tam jest ValueError wyjątek podniesiony.

Pytanie:

Czy istnieje sposób na coverage zgłosić, że nie testowałem przypadek kiedy IndexError jest podniesiona?

+0

Możesz mieć inny blok z wyjątkiem IndexError. Myślę, że zasięg właśnie policzy, które linie zostały wykonane. –

Odpowiedz

8

Coverage.py może tylko mierzyć, które ścieżki wykonania (instrukcje lub gałęzie) były uruchomione. Nie ma możliwości śledzenia, jakie wartości zostały użyte, w tym jakie typy wyjątków zostały podniesione.

Jak ja to widzę, opcje są:

  1. Oddzielne klauzule wyjątku. W kodzie, który pokazałeś, te dwa wyjątki można mimo to podnieść osobnymi liniami, chociaż być może w twoim prawdziwym kodzie nie są tak rozdzielne.

  2. Nie martw się o te dwa wyjątki. Twoje testy tego kodu będą prawdopodobnie uwzględniały wiele różnych danych wejściowych, zaprojektowanych do wykonywania różnych przypadków krawędzi. Coverage.py nie może Ci pomóc w rozróżnieniu wszystkich tych elementów lub sprawieniu, że napisałeś wystarczająco dużo przypadków. Użyj innych kryteriów, aby zdecydować, że napisałeś wystarczająco dużo przypadków testowych.

+0

OK, dziękuję bardzo. Powodzenia w rozmowie na PyCon! – alecxe

1

Myślę, że możesz spróbować z dwoma oddzielnymi wyjątkami dla dwóch wyjątków. W takim przypadku zasięg linii pokazuje, że nie przetestowano jednego warunku.

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 

Jeśli nie chcesz powtórzyć swojego kodu, możesz użyć funkcji do tego.

+0

Jest to zdecydowanie opcja, ale moja ciekawość nadal ma to pytanie, jeśli zasięg (lub inny pakiet) określają nie testowaną ścieżkę wykonania bez zmiany testowanego kodu. Dzięki! – alecxe

Powiązane problemy