10.2023 | faker | testowanie | python
Dostępna w Pythonie, biblioteka Faker, to proste w obsłudze rozwiązanie programistyczne, które pozwala nam na generowanie danych testowych wg naszych potrzeb. Niniejszy artykuł opisuje podstawowe metody i przypadki użycia, związane z biblioteką Faker.
Tworzenie i wykorzystanie danych testowych, jest nieodłączną częścią procesu poznawania narzędzi analitycznych, takich jak Microsoft Power BI, czy też testowania i nauki bibliotek programistycznych z rodziny Data Science.
Ręczne “tworzenie” danych testowych może być czasochłonne i podatne na błędy, dlatego warto korzystać z narzędzi, które umożliwiają generowanie danych testowych automatycznie. Jednym z popularnych narzędzi w tym zakresie jest biblioteka Faker, udostępniona w ramach Pythona.
W tym artykule sprawdzimy, jak można używać biblioteki Faker do generowania danych testowych pod narzędzia/biblioteki analityczne. Przeprowadzimy przykład generowania danych pod zestaw typu e-commerce.
Zaczynamy….
Zanim zaczniemy korzystać z biblioteki Faker, musimy ją zainstalować. Możemy to zrobić za pomocą menedżera pakietów dla języka Python. Wystarczy wpisać poniższą komendę w terminalu:
pip install faker
Po zainstalowaniu biblioteki Faker, jesteśmy gotowi do rozpoczęcia generowania danych testowych.
Biblioteka Faker oferuje mnogość funkcji, które umożliwiają generowanie danych testowych w różnych formatach.
Tip. Aby wygenerować listę dostępnych metod w danej bibliotece, można wykorzystać funkcję dir()
. Poniżej ilustruje to przykład dla omawianej biblioteki Faker:
from faker import Faker
fake = Faker(['pl-PL'])
Faker.seed(12)
# Pobierz listę wszystkich metod dostępnych dla obiektu `fake`
methods = dir(fake)
# Wydrukuj listę metod
for method in methods:
print(method)
Warto zwrócić uwagę na fragment:
fake = Faker(['pl-PL'])
Czyli kod, który inicjalizuje instancję biblioteki Faker z językiem polskim.
Wykorzystując konkretny język, jak w tym przypadku pl-PL, dane będą generowane w formacie właściwym dla danego kraju i będą miały charakterystykę typową dla tego języka/regionu. W skrócie, ten kod pozwala generować dane w języku polskim np. Polskie nazwisko czy nazwę ulicy.
Kolejny fragment wymagający wyjaśnienia to:
Faker.seed(12)
Metoda Faker.seed()
jest używana do inicjalizacji globalnego generatora liczb pseudolosowych w bibliotece Faker. Dzięki temu, gdy podamy konkretną wartość jako ziarno (seed), generator Faker będzie produkować te same pseudolosowe dane za każdym razem, gdy jest używany z tym samym ziarnem.
Jest to przydatne, gdy chcemy uzyskać powtarzalne wyniki podczas generowania fałszywych danych, co może być szczególnie użyteczne w testach jednostkowych czy w innych sytuacjach, gdzie powtarzalność jest ważna.
Przykład
Faker.seed(1234)
fake = Faker()
# Za każdym razem, gdy uruchomimy ten kod, z tym samym ziarnem, dostaniemy to samo imię
print(fake.name())
Zacznijmy zatem od przeglądu metod, pozwalających nam wygenerować dane osobowe.
Lista dostępnych metod:
Identyfikacja
Kontakt
Adres
Zatrudnienie
Inne
W kolejnych punktach, przyjrzyjmy się zatem wybranym przypadkom użycia.
name = fake.name()
print(name)
Przykładowe rezultaty:
Wyniki generowane przez metodę name()
mają jednak pewną wadę, która dla mnie dyskwalifikuje tą metodę. Otóż, jak można zobaczyć wyżej, do niektórych osób jest doczepiany przedrostek typu pan / pani.
Dlatego aby wygenerować zestaw typu imię + nazwisko, polecam wykorzystać poniższy kod, który generuje zestawienie bez zbędnych tytułów i z uwzględnieniem płci:
# definicja metody, generującej dane bez prefixu pan / pani
def get_name_without_prefix():
name = fake.name()
name_parts = name.split(' ')
if len(name_parts) > 1:
if name_parts[0].lower() in ['pan', 'pani']:
name_parts = name_parts[1:] # remove prefix
return ' '.join(name_parts)
# przykładowa lista
for _ in range(10):
print(get_name_without_prefix())
Przykładowe wyniki:
Biblioteka Faker pozwala nam nie tylko wygenerować email, ale nawet wybrać jaki typ emaila chcemy wygenerować:
fake.company_email()
=> generuje adres email w domenie "jak firmowa" np. Pphu.org, chylak.plfake.free_email()
=> generuje adresy email w domenach typowych dla darmowych kont email np. Interia.pl, gmail.com, yahoo.comPrzykład. Wygenerowanie listy emaili firmowych
# adres email => firmowy
for _ in range(8):
print(fake.company_email())
Przykładowa lista wygenerowanych emaili firmowych:
Przykład. Wygenerowanie listy emaili darmowych
# adres email => personalny (w darmowej domenie)
for _ in range(8):
print(fake.free_email())
Przykładowa lista wygenerowanych emaili darmowych:
Przykład generowania listy numerów telefonów:
# numer telefonu
for _ in range(5):
print(fake.phone_number())
Przykładowe, wygenerowane numery:
Jeżeli jednak chcemy wygenerować tylko pewien typ numerów np. Numery komórkowe, charakterystyczne dla naszego kraju, to musimy napisać trochę więcej kodu.
Poniżej przykład wygenerowanie numerów testowych - komórkowych - charakterystycznych dla Polski:
def generate_polish_mobile_number(fake):
first_digit = random.choice([5, 6, 7, 8])
remaining_digits = [random.randint(0, 9) for _ in range(8)]
mobile_number = f"+48 {first_digit}{''.join(map(str, remaining_digits))}"
return mobile_number
fake = Faker(['pl_PL'])
# Import the random module
import random
# Generate 5 Polish mobile numbers
for _ in range(5):
print(generate_polish_mobile_number(fake))
Wynik powyższego skryptu to:
Mamy więc gotową listę typowo polskich numerów komórkowych z prefixem +48.
Do wygenerowania adresu wykorzystujemy następujące metody:
fake.city()
fake.street_address()
fake.postalcode()
Zdefiniujmy zatem metodę, która wygeneruje nam pełny rekord adresowy tzn. Ulica, kod pocztowy i miasto.
# definiujemy indywidualną metodę, która wygeneruje pojedynczy, pełny adres w postaci ulica, kod pocztowy, miasto
def generate_address_line():
street_name = fake.street_address()
postal_code = fake.postcode()
city = fake.city()
return f"{street_name}, {postal_code}, {city}"
# generujemy dane adresowe
for _ in range(5):
print(generate_address_line())
Wyniki tak otrzymane wyglądają następująco:
Otrzymujemy zatem całkiem dobrze wyglądające dane adresowe.
W niektórych zadaniach jako login użytkownika, jest wykorzystywany nie adres email, ale podana nazwa, składająca się z przykładowych liter oraz cyfr.
Aby wygenerować takie nazwy, można wykorzystać następujący skrypt:
# generujemy login
for _ in range(5):
print(fake.user_name())
Przykładowe wyniki:
Aby wygenerować numery zamówień w sklepie, należy wykorzystać poniższą metodę:
import random
def generate_random_string():
return ''.join([str(random.randint(0, 9)) for _ in range(9)])
for _ in range(5):
print(generate_random_string())
Nie korzystamy tu z Faker, ale z generatora liczb losowych.
Otrzymane wyniki to:
Do wygenerowania numeru NIP wykorzystujemy metodę fake.nip()
.
Przykład:
# generujemy numer nip
for _ in range(5):
print(fake.nip())
Otrzymane rezultaty:
Do generowania losowych dat można wykorzystać metodę date().
date = fake.date()
print(date)
Wygenerujmy zatem pełen rekord zamówienia, który będzie miał postać typu:
ID,order_id,customer_name,customer_email,order_value,purchased_items,delivery_cost,payment_method,delivery_method
W tym celu wykorzystajmy poniższy skrypt:
=> Skrypt generuje 10k linijek z danymi testowymi
=> skrypt przyjmuje jako parametr ilość produktów, które może zakupić użytkownik, w ramach jednego zamówienia. Domyślnie jest to jeden produkt per zamówienie
# dane wyjściowe zostaną zapisane w pliku tekstowym ecommerce_data.csv
def generateOrderList(numberOfProducts=1, dateStart=datetime(2021, 1, 1), dateEnd= datetime(2022, 1, 1)):
with open('ecommerce_data.csv', 'w', newline='') as file:
writer = csv.writer(file)
# nagłówek naszego pliku z danymi
writer.writerow(["ID", "order_id", "order_date", "customer_name", "customer_email", "order_value", "purchased_items", "delivery_cost", "payment_method", "delivery_method"])
# liczba rekordów jakie generujemy w pętli
for i in range(1, 10001):
# generuje losową datę w podanym przedziale czasu
random_date = fake.date_between_dates(dateStart, dateEnd)
# wartość zamówienia
order_value = random.randint(100, 3000)
# koszt dostawy zamówienia
delivery_cost = random.randint(10, 50)
#liczba zakupionych elementów
purchased_items = random.sample(items, numberOfProducts) if numberOfProducts > 1 else random.choice(items)
# zapis danych do pliku
writer.writerow([i, i+10000, random_date, get_name_without_prefix(), fake.email(), order_value, str(purchased_items), delivery_cost, random.choice(payment_methods), random.choice(delivery_methods)])
Wywołanie skryptu:
generateOrderList()
Wygeneruje nam - jako rezultat - plik z następującymi danymi:
ID,order_id,order_date,customer_name,customer_email,order_value,purchased_items,delivery_cost,payment_method,delivery_method
1,10001,2021-03-29,Kazimierz Deszcz,marcelpodpora@example.net,2149,Mikser ręczny,49,PayPal,Standardowa dostawa
2,10002,2021-01-24,Julian Krzysiek,alan86@example.com,1436,Odkurzacz,15,PayU,Przesyłka priorytetowa
3,10003,2021-10-01,Nela Ciak,qjaszcz@example.com,2347,Robot sprzątający,10,Przelewy24,Przesyłka ekspresowa
4,10004,2021-07-09,Jeremi Sowała,vdanieluk@example.com,120,Czajnik,11,Apple Pay,Przesyłka ekspresowa
5,10005,2021-04-17,Roksana Szklarek,nkwasek@example.org,2857,Blender,36,Apple Pay,Przesyłka priorytetowa
6,10006,2021-11-05,Jakub Kruzel,bpolom@example.net,130,Zamrażarka,32,TPay,Przesyłka priorytetowa
Biblioteka faker umożliwia również tworzenie danych pod konkretne dziedziny np. Można tworzyć listę zawodów.
Przykład kodu:
for _ in range(5):
print(fake.job())
Przykładowe rezultaty:
Jak zatem widać, otrzymujemy całkiem ładną listę zawodów.
Biblioteka Faker umożliwia generowanie danych testowych w różnych formatach, takich jak CSV, JSON, SQL, XML itp. Dzięki temu możemy łatwo dostosować generowane dane do wymagań naszych narzędzi analitycznych.
Skrypt generujący proste dane testowe z zapisem tych danych w pliku csv:
from faker import Faker
import csv
fake = Faker()
with open('test_data.csv', 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(['Name', 'Email', 'Phone Number'])
for _ in range(10):
name = fake.name()
email = fake.email()
phone_number = fake.phone_number()
writer.writerow([name, email, phone_number])
Skrypt, generujący proste dane testowe z zapisem tych danych w formacie json:
import json
data = []
for _ in range(10):
name = fake.name()
email = fake.email()
phone_number = fake.phone_number()
data.append({
'name': name,
'email': email,
'phone_number': phone_number
})
with open('test_data.json', 'w') as file:
json.dump(data, file)
Skrypt, generujący proste dane testowe z zapisem tych danych w formacie SQLlite:
import sqlite3
from faker import Faker
fake = Faker()
# Utwórz połączenie z bazą danych SQLite i kursor
conn = sqlite3.connect('test_data.db')
cursor = conn.cursor()
# Utwórz tabelę, jeżeli nie istnieje
cursor.execute('''
CREATE TABLE IF NOT EXISTS test_data (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
email TEXT,
phone_number TEXT
);
''')
conn.commit()
# Generuj dane i dodaj je do bazy danych
for _ in range(10):
name = fake.name()
email = fake.email()
phone_number = fake.phone_number()
cursor.execute("INSERT INTO test_data (name, email, phone_number) VALUES (?, ?, ?)", (name, email, phone_number))
conn.commit()
# Zamknij połączenie z bazą danych
conn.close()
Poniżej znajduje się lista linków do Github Gist, gdzie można zobaczyć pełny kod omawianych przykładów.
W niniejszym artykule pokazaliśmy wykorzystanie biblioteki Faker do generowania danych testowych, w szczególności mogliśmy zobaczyć jak wygenerować pełny zestaw danych testowych dla serwisu typu e-commerce, czyli zestaw transakcji.
W niniejszym artykule pojawiły się przykłady danych testowych, wygenerowanych przez bibliotekę Faker. Nie wykluczam, że dane te są podobne do rzeczywistych osób czy podmiotów. Jeżeli tak, to jest to czysty przypadek I nie należy wyciągać tutaj daleko idących wniosków.
Napisz do mnie poprzez formularz kontaktowy.