İçeriğe geç

Python Testing Tools – Faker

Selamlar, test yazarken bir çok kere sahte verinin senaryolarınız koşulurken oluşturulup-kullanılması ihtiyacı doğmuş, bu ihtiyacı canlı ortamın kopyası olan anonim bir veritabanı dumpını yada JSON/XML formatında uygun veriyi geri yükleyerek karşılamış olabilirsiniz.

Bu 2 çözümde gayet geçerli olmakla birlikte bugün Python’daki Faker kütüphanesi ile kolayca sahte veri üretmeye göz atacağız.

Faker nedir?

Faker, bir çok alanda kolaylıkla sahte veri üretmenizi sağlayan bir Python paketi.

Bir çok alan tanımını biraz açacak olursak; klasik kişisel kullanıcı bilgilerinden(isim, soyisim, doğum tarihi), şirket bilgileri, banka hesapları para birimleri hatta araç plakaları üzerine sahte veri üretebiliyor.

Spoiler. Üretilebilecek tüm sahte veri tipleri aslında birer provider olarak tanımlanıyor ve kullanıcı tarafından genişletilebiliyor.

Yükleme işlemi standart bir Python paketinden farksız;

$ pip install faker

Python REPL üzerinde kullanımı.

Öncelikle fakeri import edip bir faker nesnesi örnekleyelim.

from faker import Faker

f = Faker()

sonrasında varsayılan providerler üzerinde bulunan metodlar üzerinden sahte veri üretelim;

f.name()
'Amanda Carroll'

f.text()
'Trial senior tell deal throughout building machine. Camera admit my them seven example.\nDetermine major indicate resource well deep. Within stock become sign different knowledge.'

f.address()
'8653 Harris Center\nWest Johnhaven, KS 34635'

f.profile()
{'job': 'Maintenance engineer',
 'company': 'Perry, Campbell and Davis',
 'ssn': '239-09-6296',
 'residence': '7697 Paul Locks\nBallland, WI 66663',
 'current_location': (Decimal('-10.907420'), Decimal('109.688267')),
 'blood_group': 'AB+',
 'website': ['https://www.hernandez.info/'],
 'username': 'ehoffman',
 'name': 'Wendy Palmer',
 'sex': 'F',
 'address': '349 Roy Motorway Suite 719\nEast David, TN 74639',
 'mail': 'alvinfigueroa@hotmail.com',
 'birthdate': datetime.date(1912, 5, 16)}

f.random_number()
57567318

Buradaki çağrımlar pekala sizde farklı sonuçlar üretecektir 😅

Kullanılabilecek tüm yerleşik provider metodlarına göz atmak için;

dir(f)

Localization.

Faker, lokal veri üretmek için hepsi için geçerli olmasada, providerler üzerinde bu desteğe sahip ve bu doğrultuda lokalize edilmiş veri sunabiliyor.

Localizationı sağlamak için Faker nesnesini örneklediğiniz sırada ilgili lokal(lleri) belirtmek yeterli.

f_tr = Faker(locale="tr_TR")

f_tr.license_plate()
'14 YEH 18'

f_tr.email()
'elnurguclu@example.net'

f_tr.job()
'Balerin'

Kullanılabilecek lokal providerların listesi için bu linke göz atmak isteyebilirsiniz

Seeding.

Testler için faker kullanıldığında aynı metodun her seferinde farklı bir sonuç döndürmesi istenmeyen bir durum olacaktır. Bu durumun önüne geçmek için, çağrıma hazır veri setine rastgelelik için bir başlangıç noktası tanımlayabiliriz.

from faker import Faker

f = Faker()

f.seed_instance(123)

f.name()
'Brandon Russell'

f_2 = Faker()

f_2.seed_instance(123)

f_2.name()
'Brandon Russell'

2 farklı faker nesnesi, dolayısıyla tekrar tekrar yürütülen testler içinde seeding sonucu metod çağrımları aynı sonuçları döndürecektir.

Custom provider yazmak.

Farklı geliştiriciler, bir çok custom provider ile farklı alanlarda veri üretmemize yardımcı olsada sadece sizin codebaseinizde tanımlı olan belirli durum yada ihtiyaçlar için yeni bir provider tanımlamak isteyebilirsiniz.

Örneğin elimizde bir sipariş sınıfı var ve doğrudan faker üstünden sipariş numarası, sipariş durumunu alarak veri üretmek istiyoruz.

import random
from enum import Enum

from faker import Faker
from faker.providers import BaseProvider


class OrderStatus(str, Enum):
    APPROVED = "approved"
    SHIPPED = "shipped"
    DELIVERED = "delivered"


class OrderProvider(BaseProvider):
    def order_number(self) -> str:
        return str(random.randint(100000000, 999999999))

    def order_status(self, status: OrderStatus = None) -> OrderStatus:
        return random.choice(list(OrderStatus)) if status is None else status

Tanımlanan yeni provideri faker nesnesine tanıttıktan sonra rastgele veri üretmeye başlayabiliriz.

f = Faker()

f.add_provider(OrderProvider)

f.order_number()
'751277174'

f.order_status()
<OrderStatus.APPROVED: 'approved'>

assert f.order_status(status=OrderStatus.APPROVED).value == "approved"

Testcaseler ile birleştirecek olursak.

Yukarıda göz attığımız kavramları basit bir senaryo üstünden test senaryosu haline getirelim.

import random
import unittest
from dataclasses import dataclass, field
from enum import Enum
from typing import List

from faker import Faker
from faker.providers import BaseProvider


class OrderStatus(str, Enum):
    APPROVED = "approved"
    SHIPPED = "shipped"
    DELIVERED = "delivered"


class OrderProvider(BaseProvider):
    def order_number(self) -> str:
        return str(random.randint(100000000, 999999999))

    def order_status(self, status: OrderStatus = None) -> OrderStatus:
        return random.choice(list(OrderStatus)) if status is None else status


@dataclass
class Order:
    number: str
    status: str


@dataclass
class User:
    first_name: str
    last_name: str
    orders: List[Order] = field(default_factory=lambda: [])

    def get_orders_with_given_status(self, status: OrderStatus):
        return [o for o in self.orders if o.status == status]




class UserTestCase(unittest.TestCase):
    def setUp(self):
        self.faker = Faker()
        self.faker.add_provider(OrderProvider)

    def test_users_order_filter(self):
        u = User(
            first_name=self.faker.first_name(),
            last_name=self.faker.last_name(),
            orders=[
                Order(
                    self.faker.order_number(),
                    self.faker.order_status(status=OrderStatus.SHIPPED),
                )
            ],
        )
        self.assertEqual(len(u.get_orders_with_given_status(OrderStatus.SHIPPED)), 1)

        user_2 = User(
            first_name=self.faker.first_name(),
            last_name=self.faker.last_name(),
            orders=[
                Order(
                    number=self.faker.order_number(),
                    status=self.faker.unique.order_status(),
                )
                for _ in range(3)
            ],
        )

        self.assertEqual(
            len(user_2.get_orders_with_given_status(OrderStatus.APPROVED)), 1
        )
        self.assertEqual(
            len(user_2.get_orders_with_given_status(OrderStatus.SHIPPED)), 1
        )
        self.assertEqual(
            len(user_2.get_orders_with_given_status(OrderStatus.DELIVERED)), 1
        )


if __name__ == "__main__":
    unittest.main()

Tamam görünüyor👍🏻


Sonuç.

Bu yazıda, testleriniz için sahte veri üretmesi için Fakeri başlangıç seviyede kurgulamayı ve kullanmayı, locale ayarlarını, custom provider eklenmesi gibi kısımlara göz attık.  Faker benim kişisel projelerimde severek kullandığım bir kütüphane.

Daha fazla provider ve trick için dökümantasyon linki burada.

Bunun yanında sahte veri üretmek doğrudan model nesneleri üretmek için Django projelerinde kullanabileceğiniz model-bakery kütüphanesinin yazısını bu linke bırakıyorum.

İyi günler!

Tarih:Blog

İlk Yorumu Siz Yapın

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.

Göster
Gizle