Wpis z mikrobloga

#naukaprogramowania #programowanie #python

Mam bardzo prostą metodę w klasie:

def save_to_file(self, path):
try:
with open(path, 'w') as file:
file.write(json.dumps(self.data, indent=4))
except PermissionError:
print(f"no permissions to save the file in {path}")

Chcę odpalić unit test:

def test_write_to_file_without_permissions(self):
d = data_getter(LoadFromFile=True, data_path='data.json')
self.assertRaises(PermissionError, d.save_to_file, 'no_permissions_to_write/data.json')

Problem jest taki, że jeżeli zostawię blok except w metodzie, to wtedy unit test go nie łapie. Jeżeli wyrzucę nowy error w bloku except, to zaliczam test, ale sam program wtedy się będzie wywalać.
W jaki sposób mogę zachować block except, żeby test case wykrywał że dostałem w ryj wyjątkiem nieobsłużonym?
  • 47
@RedveKoronny: jak testujesz jakiś kod to zakładasz, że jest on reużywalny. Czyli jest sens go użyć w różnych sytuacjach i miejscach. W takim wypadku najlepiej przepuścić wyjątek, bo dajesz maksymalną swobodę użytkownikowi przez co twój kod jest prostrzy i można z nim więcej zrobić.

Jak dana klasa ma nie być reużywalna to dobry znak, że nie warto jej testować. Spróbój przetestować poziom wyżej, czyli funkcję/klasę, która jej używa. Często pisze się
@RedveKoronny: zacznij szukac od 'mock exceptions python'. generalnie slowo kluczowe 'mock' to wazna czesc pisania testow, bo ciebie jako programiste niezbyt obchodzi np. czy dana implementacja bazy danych prawidlowo sie komunikuje. dostajesz specyfikacje/biblioteke do obslugi i jedziesz - zakladajac ze ta biblioteka/baza maja swoje testy i dzialaja tak jak powinny.
@dziekujemyzapraszamyponownie: @Saly: @CancerLight: @Gantzu:
A czy zrobienie czegoś takiego ma sens, jeżeli chcę poinformować użyszkodnika gdzie nastąpił, jaki błąd, czy wypieprzyc w ogóle ten block try-catch razem z logami?

try:
with open(path, 'w') as file:
file.write(json.dumps(self.data, indent=4))
except PermissionError:
logging.error(f"no permissions to save the file in {path}")
raise PermissionError
@RedveKoronny: nie rozmawiam w pythonie, ale wyglada w miare sensownie. poza tym, ze jak juz obslugujesz wyjatek, to nie rzucasz uzytkownikowi wyjatkiem ;) zapisz do loga, zapisz w tracking, ale uzytkownikowi zwroc 'ladnie' blad.

cos co spowoduje np. w aplikacji desktopowej wyskoczenie okienka/wyraznego powiadomienia, ze nie udalo sie zapisac pliku, bo costam - nie ma uprawnien, sciezka zapisu nie istnieje, plik nie istnieje, gwiazdy sa zle ustawione etc. tak, zeby uzytkownik
via Wykop Mobilny (Android)
  • 0
@RedveKoronny: zależy jeżeli chcesz mieć error w logach to zostaw (nie wiem jak na innym poziomie ten wyjątek traktujesz). Jak robisz raise w bloku except to nie dopisuj klasy wyjątku, wtedy oryginalny wyjątek razem ze stack tracem zostanie rzucony
@Gantzu: nie traktuje, zostawiałem żeby mi testy przechodziły ( ( ͡°( ͡° ͜ʖ( ͡° ͜ʖ ͡°)ʖ ͡°) ͡°) ). Teraz to troche rozsądniej dam, potem moge podesłać cały kod, tylko napisze od nowa testy z pytestem, i usune swoje klucze do api
@CancerLight: w tym bloku sprawdzam jedynie permisje. Spróbuje dodać jakiś dodatkowy system, który upewni sie że są wszystkie pliki, i że dane są w prawidłowej formie. Teraz robie prowizorke, ale sie potem refactor walnie