Rozwój testowy w Pythonie przy użyciu Pytest

May 29, 2025
14 min read
Loading the Elevenlabs Text to Speech AudioNative Player...

Wprowadzenie

Testowanie kodu jest bardzo ważnym krokiem podczas tworzenia oprogramowania. Kiedy programista przesyła projekt, musi mieć pewność, że stworzone przez niego oprogramowanie działa poprawnie. Rozwój testowy w Pythonie przy użyciu Pytest to potężne podejście, które pomaga zapewnić jakość kodu i zapobiegać błędom. Istnieje wiele błędów, które mogą pojawić się podczas korzystania z oprogramowania, takich jak zły typ danych wejściowych, nieprawidłowy plik wejściowy, nieprawidłowy interfejs API lub nieprawidłowe działanie użytkownika. Testy pomagają przewidzieć możliwe scenariusze użycia kodu i zapobiegają pojawianiu się błędów

Czym jest TDD (Test Driven Development)?

TDD (Test-powered development) to technika tworzenia oprogramowania, która przedstawia wymagania oprogramowania poprzez testy. Podczas pisania testów programista zapisuje wymagania, które powinno spełniać końcowe oprogramowanie. Test można zdać tylko wtedy, gdy ostateczny kod spełnia wszystkie warunki. Dzięki temu podczas tworzenia oprogramowania kod jest wielokrotnie testowany i gromadzone są wszystkie wymagania, które określają, że końcowe oprogramowanie zostało napisane poprawnie i nie zawiera błędów. Podejście TDD można przedstawić w trzech etapach:

  1. Napisz testy zawierające wszystkie przyszłe wymagania dotyczące oprogramowania. Wszystkie testy powinny się nie powieść.
  2. Opracuj minimalne oprogramowanie i sprawdź jego poprawność, uruchamiając testy. Ten krok powinien zakończyć się po przejściu wszystkich testów.
  3. Refaktoryzuj i ulepsz swój kod. Ponownie przeprowadź testy pamiętając, że powinny przejść.

Co to jest framework Pytest?

Pytest jest jednym z najpopularniejszych frameworków do testowania kod Pythona. Istnieje wiele zalet, które sprawiają, że ludzie lubią korzystać z Pytest. Zdecydowanie jedną z nich jest łatwość obsługi, wśród dodatkowych wtyczek i bardzo dobrze napisana dokumentacja. Pytest obsługuje testy jednostkowe i umożliwia pisanie prostych skalowalnych zestawów testowych. Ponadto Pytest umożliwia programistom korzystanie z urządzeń, parametryzację i daje możliwość pominięcia wybranych testów podczas wykonywania. Ponadto jest to open source, aw Internecie jest wiele artykułów i samouczków na temat testowania kodu Pythona za pomocą Pytest. Ze względu na te wszystkie zalety wielu programistów decyduje się na pisanie testów przy użyciu tego frameworka.

Podstawowy przypadek testowy Pytest, Test Driven Developoment w Pythonie

Przede wszystkim musimy zastanowić się, jak powinna wyglądać struktura naszego projektu. Istnieje kilka podejść, ale moim zdaniem najlepiej oddzielić testy od kodu, który ma być testowany. Proponuję, aby nasz projekt miał następującą strukturę. └── projekt
▢ Źródła
│ └── code.py
│ └── __init__.py
└── testy
── test_code.py
└── __init__.py
 

  • W pakiecie źródeł zachowamy logikę projektu.
  • W pakiecie testowym będziemy przechowywać testy sprawdzające poprawność logiki projektu.

Zapamiętaj! Jeśli chcesz, aby Pytest znalazł plik testowy bez umieszczania go na liście podczas wykonywania, musisz dodać prefiks „test” lub przyrostek w nazwie pliku.Napiszmy prostą funkcję, która zwróci liczbę liter „a” (wielkie i małe litery) w danym słowie. Jak widać, funkcja ma ochronę (cast to string) przed określeniem argumentu „word”, który jest innym typem danych niż string.# project/sources/code.py

def count_a (słowo = Brak):
return str (word) .lower () .count ('a') Następnie napiszmy test, który potwierdzi, że funkcja zwraca poprawny wynik. Musisz wiedzieć, że metoda testowa powinna mieć podciąg „test” na początku lub na końcu nazwy. Dopiero wtedy Pytest znajdzie metodę testowania i wykona ją. Najpierw musimy zaimportować funkcję count_a. Aby sprawdzić poprawność funkcji, używamy instrukcji assert, która sprawdza, czy wynik funkcji jest równy oczekiwanemu wynikowi. Chcielibyśmy omówić wszystkie możliwe przypadki, w których mogą pojawić się błędy. Spójrzmy na następujący przykład: # project/tests/test_code.py

z sources.code import count_a

def test_count_a ():
assert count_a ('aA') == 3
potwierdzić count_a (2) == 0
assert count_a (3.14) == 0
assert count_a ('arbuz') == 1
assert count_a () == 0Aby uruchomić Pytest musisz po prostu napisać „pytest” w konsoli. Używamy flagi werbose, aby zobaczyć bardziej szczegółowe dane wyjściowe: $ pytest -vUruchamianie testu daje następujący wynik:

Logos of Azure Data Factory and Apache Airflow, representing a comparison between the two data orchestration tools

Jak widać nasz test przeszedł, funkcja count_a działa poprawnie, Test Driven Development w Pythonie.

Co jeśli usuniemy ochronę przed podaniem argumentu innego typu niż ciąg znaków? Usuńmy cast z funkcji i uruchom ponownie test.# project/sources/code.py
def count_a (słowo = brak):
return word.lower () .count ('a')
$ pytest -v

Bar chart displaying the count of unique values in a categorical column, providing insights into the dataset.

Test nie powiódł się z powodu AttributeError. Pytest zaznaczył, które stwierdzenie assert zwróciło fałsz, a gdzie wyjątek pojawił się w testowanej funkcji.

TDD w Pythonie przy użyciu Pytest

Od teraz wiesz, jak napisać prosty test z Pytest. Najwyższy czas przedstawić, jak korzystać z pakietu Pytest w technice TDD.Wyobraźmy sobie, że chcemy zaimplementować klasę UserDatabase. Do bazy danych można dodać tylko takie informacje, jak imię, nazwisko, wiek i numer identyfikacyjny. Wiek nie może być wartością ujemną i musi być niższy niż 120. Imię i nazwisko oczywiście muszą być ciągiem, a numer identyfikacyjny musi być niepowtarzalny. Użytkownik może zostać usunięty z bazy danych po podaniu numeru identyfikacyjnego. Ponadto klasa powinna umożliwić wyświetlanie nazwy najstarszego użytkownika dodanego do bazy danych.

Napisz test

Zgodnie z metodą TDD rozpoczynamy pracę od napisania testu, który sprawdzi wszystkie przypadki użycia i historie użytkowników. W poniższym przykładzie użyliśmy metody raise z biblioteki Pytest, aby sprawdzić, czy pojawi się oczekiwany wyjątek. # project/tests/test_code.py
import pytest
z sources.code import UsersDatabase

def test_user_database ():
# Tworzenie obiektu bazy danych użytkownika
baza danych = UsersDatabase ()

# Dodaj nowych użytkowników
database.add_user ('John', 'Smith', 29, 'e31sf')
database.add_user ('Emily', 'Taylor', 12, 'd24da')
database.add_user ('Lilia', 'Thomas', 66, 'd33fw')
asertuj bazę danych.get_number_of_users () == 3

# Dodaj dwóch użytkowników z tym samym identyfikatorem
z pytest.raise (ValueError):
database.add_user ('John', 'Smith', 29, 'e31sf')

# Usuń użytkownika
bazy danych.delete_user_by_id ('d24da')
asertuj bazę danych.get_number_of_users () == 2

# Co jeśli wiek jest ciągiem
z pytest.raise (TypeError):
database.add_user ('John', 'Thomas', 'wiek', 'dc33s')

# Co jeśli wiek równa się 200
z pytest.raise (ValueError):
database.add_user ('Ava', 'Brązowy', 200, 'dsd2f')

# Co jeśli wiek jest wartością ujemną
z pytest.raise (ValueError):
database.add_user ('Ava', 'Brązowy', -10, 'dsdw3')

# Co jeśli nazwa jest liczbą całkowitą
z pytest.raise (TypeError):
database.add_user (2323, 'Smith', 23, 'd3ff2')

# Co jeśli nazwisko jest pływakiem
z pytest.raise (TypeError):
database.add_user ('Jan', 3.14, 19, 'd31xe')

# Co jeśli nowy użytkownik nie ma identyfikatora
z pytest.raise (TypeError):
database.add_user (nazwa='John', nazwisko='Wilson', wiek = 19)

Napisz kod

Teraz nadszedł czas, aby napisać kod pamiętając o teście, który powinien zostać zdany po zakończeniu! Końcowy kod może wyglądać jak wycinek poniżej: # project/sources/code.py

klasa UsersDatabase:
def __init__ (self):
self.database = []

def add_user (siebie, imię, nazwisko, wiek, numer identyfikacyjny):
jeśli nie jestinstance (wiek, int):
podnieść typeError

jeśli nie jestinstancja (nazwa, str):
podnieść typeError

jeśli nie jestinstancja (nazwisko, str):
podnieść typeError

jeśli wiek nie mieści się w przedziale (1, 120):
podnieść wartośćError

jeśli istnieje (user.id_number == id_number dla użytkownika w self.database):
podnieść wartośćError

self.database.append (Użytkownik (imię, nazwisko, wiek, numer identyfikacyjny))

def delete_user_by_id (self, id_number):
dla użytkownika w self.database:
jeśli numer_id_użytkownika == numer id_użytkownika:
self.database.remove (użytkownik)

def get_oldest_user_name (self):
oldest_user = posortowane (self.database, key=lambda x: x.age, reverse=true) [0]
zwróć najstarszej_nazwa_użytkownika_użytkownika

def get_number_of_users (self):
return len (self.database)

klasa Użytkownik:
def __init__ (ja, imię, nazwisko, wiek, numer identyfikacyjny):
self.name = nazwa
self._name = nazwisko
self.age = wiek
self.id_number = numer id_id

Uruchom test

Uruchom Pytest i sprawdźmy wynik testu.$ pytest -v

Pareto analysis chart illustrating the 80-20 rule, highlighting the most significant values in a dataset.

Test przeszedł. Nasz kod jest gotowy.

Wniosek

Testowanie kodu może pomóc uniknąć wielu błędów, które czasami nie są widoczne na pierwszy rzut oka, Test Driven Development. Pisanie testów wymaga trochę pracy i może być czasochłonne, ale pozwala uniknąć sytuacji, w których musimy ciągle ulepszać kod, ponieważ użytkownicy znajdują więcej błędów. TDD to technika, w której testy są pisane jako pierwsze, aby obejmować wszystkie możliwe błędy i niewłaściwe użycie kodu. Następnie kod jest pisany na podstawie testów i tylko wtedy, gdy wszystkie testy przejdą, kod można uznać za zakończony. Ta technika pomaga programistom bardziej skupić się na wymaganiach projektu i możliwych przypadkach, gdy coś może być błędne.PyTest to najpopularniejszy framework do testowania kodu Pythona. Ma wiele zalet i to jest powód, dla którego ludzie bardzo często używają Pytest. Zastosowanie techniki TDD z frameworkiem Pytest daje możliwość poprawy jakości kodu Pythona i satysfakcji użytkowników.Skontaktuj się z nami jeśli potrzebujesz pomocy, wprowadzając to po swojej stronie.

Co to jest visual search i jak działa

Różnice miedzy airflow 1-10-x-a-2-0

Poprawa kodu python przeglad linterow

Share this post
Nauka o danych
MORE POSTS BY THIS AUTHOR

Curious how we can support your business?

TALK TO US