Przypadki testowe, dane brzegowe, debugowanie, technika print debugging
ð Podstawa programowa: II.1+I.3Testowanie to proces sprawdzania, czy program dziala poprawnie dla roznych danych wejsciowych. Nawet jesli program kompiluje sie bez bledow i wydaje sie dzialac prawidlowo, moze zawierac ukryte bledy (bugi), ktore ujawnia sie dopiero dla pewnych specyficznych danych.
Kazdy profesjonalny programista testuje swoj kod. Szacuje sie, ze okolo 40-50% czasu pracy programisty to wlasnie testowanie i naprawianie bledow!
Dobrze dobrane testy powinny obejmowac rozne kategorie danych:
def silnia(n):
wynik = 1
for i in range(1, n + 1):
wynik *= i
return wynik
# Przypadki testowe:
print(silnia(0)) # Oczekiwane: 1 (0! = 1)
print(silnia(1)) # Oczekiwane: 1 (1! = 1)
print(silnia(5)) # Oczekiwane: 120 (5! = 120)
print(silnia(10)) # Oczekiwane: 3628800
# A co z silnia(-1)? Program powinien to obslugiwac!
Najprostsza metoda szukania bledow to print debugging - dodawanie instrukcji print() w kluczowych miejscach kodu, aby sledzic wartosci zmiennych i przebieg programu.
# Program z bledem - szukamy go za pomoca print()
def srednia(lista):
suma = 0
for i in range(len(lista)):
suma += lista[i]
print(f"DEBUG: i={i}, lista[i]={lista[i]}, suma={suma}")
wynik = suma / len(lista)
print(f"DEBUG: suma={suma}, len={len(lista)}, wynik={wynik}")
return wynik
# Testujemy
print(srednia([10, 20, 30])) # Oczekiwane: 20.0
Oto najczestsze bledy, ktore napotkasz jako poczatkujacy programista:
range(1, n) zamiast range(1, n+1))# print(f"DEBUG: ...") do tymczasowego wylaczenia.
Ponizszy program ma obliczac srednia z listy liczb, ale zawiera blad. Znajdz go i napraw:
def srednia(lista):
suma = 0
for i in range(1, len(lista)):
suma += lista[i]
return suma / len(lista)
# Blad: range zaczyna od 1, a powinien od 0!
# Przez to pomijamy pierwszy element listy.
def srednia(lista):
suma = 0
for i in range(0, len(lista)): # POPRAWKA: start od 0
suma += lista[i]
return suma / len(lista)
# Lub jeszcze lepiej:
def srednia_v2(lista):
return sum(lista) / len(lista)
Dla ponizszej funkcji czy_parzysta(n) napisz co najmniej 6 przypadkow testowych obejmujacych dane typowe, brzegowe i specjalne:
def czy_parzysta(n):
return n % 2 == 0
def czy_parzysta(n):
return n % 2 == 0
# Przypadki testowe:
print(czy_parzysta(4)) # True - typowa parzysta
print(czy_parzysta(7)) # False - typowa nieparzysta
print(czy_parzysta(0)) # True - brzegowa (zero)
print(czy_parzysta(1)) # False - brzegowa (jeden)
print(czy_parzysta(-2)) # True - ujemna parzysta
print(czy_parzysta(-3)) # False - ujemna nieparzysta
print(czy_parzysta(1000000)) # True - duza liczba
Ponizszy program zawiera dwa bledy. Uzyj techniki print debugging, zidentyfikuj je i napraw:
def znajdz_max(lista):
maks = 0
for i in range(len(lista)):
if lista[i] > maks:
maks = i
return maks
# Blad 1: maks = 0 - co jesli wszystkie liczby sa ujemne?
# Blad 2: maks = i - zapisujemy indeks zamiast wartosci!
def znajdz_max(lista):
maks = lista[0] # POPRAWKA 1: inicjujemy pierwszym elementem
for i in range(1, len(lista)):
if lista[i] > maks:
maks = lista[i] # POPRAWKA 2: zapisujemy wartosc
return maks
# Test
print(znajdz_max([3, 7, 2, 9, 1])) # 9
print(znajdz_max([-5, -2, -8])) # -2
Poznaj instrukcje assert - automatyczne sprawdzanie warunkow. Napisz funkcje potega(a, n) obliczajaca a^n (bez uzycia **) i przetestuj ja za pomoca assert.
def potega(a, n):
if n == 0:
return 1
wynik = 1
for _ in range(abs(n)):
wynik *= a
if n < 0:
return 1 / wynik
return wynik
# Testy z assert
assert potega(2, 0) == 1, "2^0 powinno byc 1"
assert potega(2, 1) == 2, "2^1 powinno byc 2"
assert potega(2, 10) == 1024, "2^10 powinno byc 1024"
assert potega(5, 3) == 125, "5^3 powinno byc 125"
assert potega(1, 100) == 1, "1^100 powinno byc 1"
print("Wszystkie testy przeszly!")