Python'da birim testi yazmak için ek kurulum gerektirmeyen araç standart kütüphanedeki unittest modülüdür: unittest.TestCase sınıfından türeyen bir sınıf yazarsınız, adı test ile başlayan her metot bir test olur, kontrolleri assertEqual(), assertRaises() gibi metotlarla yaparsınız ve testleri python -m unittest komutuyla çalıştırırsınız. Modül JUnit'ten esinlenmiştir; hazırlık ve temizlik kodunu paylaşmayı, testleri gruplamayı ve sonuçları raporlamayı nesne yönelimli biçimde sunar.

Bu yazıda gerçek bir küçük modül için test dosyası kuruyoruz, testleri komut satırından keşif (discovery) ile çalıştırıyoruz, başarısız bir testin çıktısını satır satır okuyoruz, setUp, addCleanup, subTest, atlama ve beklenen hata konularına giriyoruz. Sonda unittest.mock ve doctest modüllerine kısa birer giriş var. Gösterilen tüm test çıktıları Python 3.15.2 ile alındı; süre değerleri (0.001s gibi) her çalıştırmada değişebilir.

Temel kavramlar

Temel kavramlar: Test fixture, Test case, Test suite, Test runner

unittest belgeleri dört kavram üzerine kuruludur. Bunları bilmek hem belgeleri okumayı hem de hata çıktılarını yorumlamayı kolaylaştırır:

KavramAnlamıunittest karşılığı
Test fixtureTestten önce yapılan hazırlık ve sonrasındaki temizliksetUp, tearDown, addCleanup
Test caseBelirli bir girdiye verilen yanıtı kontrol eden tek test birimiTestCase alt sınıfındaki test metodu
Test suiteBirlikte çalıştırılacak testlerin topluluğuTestSuite
Test runnerTestleri çalıştırıp sonucu raporlayan bileşenTextTestRunner, python -m unittest

Her test metodu için yeni bir TestCase örneği oluşturulur; setUp() ve tearDown() her testte bir kez çalışır. Bu tasarım testlerin birbirinden bağımsız olmasını amaçlar: bir test diğerinin bıraktığı duruma güvenmemelidir. Testlerin çalışma sırası, metot adlarının metin olarak sıralanmasıyla belirlenir; bu sıraya dayanan bir test yazmak kırılgan olur.

İlk test dosyası

Test edeceğimiz hesap.py modülünde iki fonksiyon var: KDV ekleyen kdv_ekle() ve Türkçe karakterleri ASCII karşılıklarına çevirerek adres dostu metin üreten slug().

python
def kdv_ekle(tutar, oran=20):
    """Tutara KDV ekler ve 2 basamağa yuvarlar."""
    if tutar < 0:
        raise ValueError('tutar negatif olamaz')
    return round(tutar * (1 + oran / 100), 2)

def slug(metin):
    tablo = str.maketrans('çğıöşüÇĞİÖŞÜ', 'cgiosuCGIOSU')
    return '-'.join(metin.translate(tablo).lower().split())

Testleri ayrı bir test_hesap.py dosyasına yazıyoruz. Belgeler test kodunu ayrı modülde tutmanın avantajlarını sayar: test modülü tek başına çalıştırılabilir, dağıtılan koddan kolayca ayrılır ve test edilen kodu yeniden düzenlemek kolaylaşır.

python
import unittest
from hesap import kdv_ekle, slug

class KdvTest(unittest.TestCase):

    def test_varsayilan_oran(self):
        self.assertEqual(kdv_ekle(100), 120.0)

    def test_ozel_oran(self):
        self.assertEqual(kdv_ekle(50, oran=10), 55.0)

    def test_negatif_tutar(self):
        with self.assertRaises(ValueError) as cm:
            kdv_ekle(-5)
        self.assertIn('negatif', str(cm.exception))

class SlugTest(unittest.TestCase):

    def test_turkce_karakter(self):
        self.assertEqual(slug('Çay Şeker Ölçü'), 'cay-seker-olcu')

    def test_buyuk_i(self):
        self.assertEqual(slug('İzmir Iğdır'), 'izmir-igdir')

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

Dosya adının test ile başlaması önemlidir; keşif mekanizması varsayılan olarak test*.py desenine uyan dosyaları arar. Her iki dosya aynı klasördeyken şunları çalıştırabilirsiniz:

bash
$ python -m unittest
.....
----------------------------------------------------------------------
Ran 5 tests in 0.000s

OK

$ python -m unittest -v
test_negatif_tutar (test_hesap.KdvTest.test_negatif_tutar) ... ok
test_ozel_oran (test_hesap.KdvTest.test_ozel_oran) ... ok
test_varsayilan_oran (test_hesap.KdvTest.test_varsayilan_oran) ... ok
test_buyuk_i (test_hesap.SlugTest.test_buyuk_i) ... ok
test_turkce_karakter (test_hesap.SlugTest.test_turkce_karakter) ... ok

----------------------------------------------------------------------
Ran 5 tests in 0.000s

OK

Ayrıntısız modda her başarılı test bir nokta olarak görünür. -v ile her testin tam adı (modül.Sınıf.metot) ve sonucu listelenir. Dosyanın sonundaki unittest.main() satırı sayesinde python test_hesap.py komutu da aynı testleri çalıştırır. test_negatif_tutar testinde assertRaises() bağlam yöneticisi olarak kullanıldı; as cm ile yakalanan istisna nesnesine cm.exception üzerinden ulaşıp mesajını da kontrol ettik.

Test metotlarında Python'un düz assert ifadesi yerine self.assert... metotları kullanılır. Belgeler bunun nedenini açıklar: test çalıştırıcı bu metotlar sayesinde tüm sonuçları toplayıp ayrıntılı rapor üretebilir. Örneğin assertEqual() iki liste farklıysa ilk farklı elemanı ve bir fark (diff) çıktısı gösterir.

Komut satırı seçenekleri ve test keşfi

python -m unittest komutu argümansız çalıştırıldığında python -m unittest discover ile aynı işi yapar: başlangıç klasöründen itibaren test dosyalarını bulup içe aktarır. Belirli bir modülü, sınıfı ya da tek bir metodu da çalıştırabilirsiniz:

bash
python -m unittest test_hesap
python -m unittest test_hesap.KdvTest
python -m unittest test_hesap.KdvTest.test_ozel_oran
python -m unittest tests/test_hesap.py
python -m unittest discover -s tests -p "*_test.py"
python -m unittest -k slug -v
Seçenekİşlevi
-vHer testin adını ve sonucunu yazar
-f, --failfastİlk hata ya da başarısızlıkta durur
-b, --bufferBaşarılı testlerin print çıktısını gizler, başarısızlarda gösterir
-k DESENYalnızca adı desene uyan testleri çalıştırır (birden çok kez verilebilir)
-c, --catchCtrl-C ile mevcut test bitince o ana kadarki sonuçları raporlar
--localsTraceback içinde yerel değişkenleri gösterir
--durations NEn yavaş N testi listeler (3.12 ile geldi)
discover -s KLASÖRKeşfin başlayacağı klasör (varsayılan .)
discover -p DESENTest dosyası deseni (varsayılan test*.py)
discover -t KLASÖRProjenin üst düzey klasörü

-k deseninde * varsa fnmatch kuralıyla, yoksa büyük küçük harfe duyarlı alt metin olarak eşleşme yapılır; eşleşme testin tam adına göredir. Keşif için test dosyalarının proje kökünden içe aktarılabilir modüller olması, yani adlarının geçerli Python tanımlayıcısı olması gerekir. Python 3.14 ile ad alanı paketleri (namespace package) yeniden başlangıç klasörü olarak destekleniyor; ancak Python dışı klasörleri taramamak için __init__.py içermeyen alt klasörlerde test aranmıyor. Testleri tests/ gibi alt klasörlere koyuyorsanız bu klasörlere __init__.py eklemeyi unutmayın. Paket yapısı için modül ve paket yazısına bakabilirsiniz.

Python 3.14 ile test çıktısı terminalde varsayılan olarak renklidir. Renk, ortam değişkenleriyle (NO_COLOR, PYTHON_COLORS) kapatılabilir.

assert metotları

En çok kullanılan karşılaştırma metotları ve neyi kontrol ettikleri:

MetotKontrolNot
assertEqual(a, b)a == bListe, sözlük, metin için ayrıntılı fark gösterir
assertNotEqual(a, b)a != b
assertTrue(x) / assertFalse(x)bool(x) is True / FalseDaha özel metot varsa onu tercih edin
assertIs(a, b)a is bKimlik karşılaştırması
assertIsNone(x)x is None
assertIn(a, b)a in b
assertIsInstance(a, b)isinstance(a, b)
assertAlmostEqual(a, b)round(a - b, 7) == 0Ondalık basamağa göre yuvarlar, delta da verilebilir
assertCountEqual(a, b)Sıradan bağımsız aynı elemanlarTekrar sayıları da karşılaştırılır
assertRegex(metin, desen)re.search eşleşir
assertRaises(Hata)Blok bu istisnayı fırlatırBağlam yöneticisi olarak kullanılabilir
assertLogs(logger, level)Blok en az bir log kaydı üretir3.15: formatter parametresi
assertStartsWith / assertEndsWithÖnek ve sonek kontrolü3.14 ile geldi
assertHasAttr / assertIsSubclasshasattr ve issubclass kontrolü3.14 ile geldi

assertTrue(a == b) yazmak yerine assertEqual(a, b) yazmak, başarısızlıkta "False is not true" yerine iki değeri de gösteren bir mesaj üretir. Belgeler daha özel bir metot varsa onun kullanılmasını önerir. assertTrue(x) aslında bool(x) is True kontrolü yapar; değerin gerçekten True nesnesi olduğunu doğrulamak isterseniz assertIs(x, True) kullanın. Tüm assert metotları isteğe bağlı bir msg argümanı alır ve başarısızlık mesajına eklenir.

Başarısız testin çıktısını okumak

Başarısız testin çıktısını okumak

unittest iki tür olumsuz sonuç ayırır. FAIL, bir assert metodunun koşulunun sağlanmadığı, yani kodun yanlış sonuç verdiği durumdur. ERROR, test sırasında beklenmeyen başka bir istisnanın oluşmasıdır; çoğunlukla testin ya da test edilen kodun hata verdiğini gösterir. Aşağıdaki dosyada ikisinden de birer örnek var:

python
import unittest

class HataliTest(unittest.TestCase):

    def test_liste(self):
        self.assertEqual([1, 2, 3], [1, 2, 4])

    def test_bolme(self):
        sonuc = 10 / 0
bash
$ python -m unittest -v test_hata
test_bolme (test_hata.HataliTest.test_bolme) ... ERROR
test_liste (test_hata.HataliTest.test_liste) ... FAIL

======================================================================
ERROR: test_bolme (test_hata.HataliTest.test_bolme)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_hata.py", line 10, in test_bolme
    sonuc = 10 / 0
            ~~~^~~
ZeroDivisionError: division by zero

======================================================================
FAIL: test_liste (test_hata.HataliTest.test_liste)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_hata.py", line 7, in test_liste
    self.assertEqual([1, 2, 3], [1, 2, 4])
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
AssertionError: Lists differ: [1, 2, 3] != [1, 2, 4]

First differing element 2:
3
4

- [1, 2, 3]
?        ^

+ [1, 2, 4]
?        ^

----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (failures=1, errors=1)

(Çıktıdaki dosya yolunu kısalttık, başka bir şey değiştirmedik.) Raporun en altındaki satır özeti verir: bir başarısızlık, bir hata. assertEqual() listeler için ilk farklı elemanın indeksini (2) ve -, +, ? işaretli bir fark görünümü üretti. Komutun çıkış kodu, en az bir test başarısız olduğunda 0 değildir; sürekli entegrasyon sistemleri bu sayede hatalı bir değişikliği yakalar. Traceback satırlarını okumayı sık hata mesajları yazısında ayrıntılı anlattık.

Hazırlık ve temizlik: setUp, tearDown, addCleanup

Birden çok testin aynı hazırlığa ihtiyacı varsa bu kodu setUp() metoduna taşıyın; çerçeve her testten hemen önce onu çağırır. tearDown() her testten sonra, test başarısız olsa bile çalışır; ancak yalnızca setUp() başarıyla tamamlandıysa. addCleanup() ile eklenen temizlik fonksiyonları ise setUp() yarıda kalsa bile çağrılır ve eklenme sırasının tersiyle (son eklenen ilk) çalışır. Bu yüzden kaynak açtığınız satırın hemen arkasına temizliğini eklemek güvenli bir alışkanlıktır.

python
import os
import tempfile
import unittest

class DosyaTest(unittest.TestCase):

    def setUp(self):
        self.klasor = tempfile.TemporaryDirectory()
        self.addCleanup(self.klasor.cleanup)
        self.yol = os.path.join(self.klasor.name, 'not.txt')

    def test_yaz_oku(self):
        with open(self.yol, 'w', encoding='utf-8') as f:
            f.write('günlük')
        with open(self.yol, encoding='utf-8') as f:
            self.assertEqual(f.read(), 'günlük')

    def test_dosya_yok(self):
        self.assertFalse(os.path.exists(self.yol))

Her iki test de kendi geçici klasörünü alır; test_dosya_yok testi, diğer testin yazdığı dosyayı görmez. Tüm sınıf için bir kez yapılacak pahalı hazırlıklar (örneğin bir veritabanı bağlantısı) için @classmethod olarak tanımlanan setUpClass() ve tearDownClass(), modül düzeyinde setUpModule() ve tearDownModule() vardır. Python 3.11 ile gelen enterContext(), bir bağlam yöneticisine girip çıkışını otomatik temizlik olarak kaydeder; with ve context manager yazısında bu protokolü anlattık.

İstisna, uyarı ve log kontrolü

assertRaises() iki biçimde kullanılır: self.assertRaises(ValueError, kdv_ekle, -5) gibi fonksiyon ve argümanlarıyla, ya da yukarıda yaptığımız gibi with bloğuyla. Bağlam yöneticisi biçimi okunması daha kolay olduğu için genellikle tercih edilir. assertRaisesRegex() ek olarak istisna mesajının bir düzenli ifadeyle eşleşmesini ister. Kendi istisna sınıflarınızı yazmayı raise ve özel istisna yazısında bulabilirsiniz.

Log mesajlarını test etmek için assertLogs() kullanılır. Blok içinde belirtilen logger ya da alt logger'larından, verilen seviyede en az bir kayıt üretilmezse test başarısız olur. Dönen nesnenin output listesi biçimlenmiş mesajları, records listesi ise LogRecord nesnelerini tutar. Python 3.15 ile assertLogs() bir formatter parametresi kabul ediyor; verilmezse biçim %(levelname)s:%(name)s:%(message)s olur.

python
import logging
import unittest

def odeme_al(tutar):
    log = logging.getLogger('odeme')
    if tutar > 10_000:
        log.warning('yüksek tutar: %s', tutar)
    return True

class LogTest(unittest.TestCase):

    def test_uyari(self):
        with self.assertLogs('odeme', level='WARNING') as cm:
            odeme_al(25_000)
        self.assertEqual(cm.output, ['WARNING:odeme:yüksek tutar: 25000'])

Bu test, Python 3.15.2 ile çalıştırıldığında OK sonucunu verdi. Python 3.15 ile assertWarns() ve assertWarnsRegex() davranışı da değişti: artık belirtilen kategoriye ya da desene uymayan uyarıları yutmuyorlar ve iç içe kullanılabiliyorlar. Sürüm notları, bu değişiklik nedeniyle önceden gizlenen bazı uyarıların test çıktısında görünmeye başlayabileceğini ve bunları uyarı filtreleriyle ya da ek assertWarns kontrolleriyle ele almak gerektiğini belirtiyor. Log yapılandırmasının kendisi için logging modülü yazısına bakın.

subTest ile parametreli testler

Aynı kontrolü farklı girdilerle yapmak için bir döngü yazmak doğaldır; ama döngüdeki ilk başarısızlık testi durdurur ve hangi değerde patladığını göstermez. subTest() bağlam yöneticisi her yinelemeyi ayrı bir alt test olarak raporlar ve verdiğiniz parametreleri hata mesajına ekler:

python
import unittest

def cift_mi(n):
    return n % 2 == 0

class AltTest(unittest.TestCase):

    def test_ciftler(self):
        for n in (2, 4, 7, 10):
            with self.subTest(n=n):
                self.assertTrue(cift_mi(n))
bash
$ python -m unittest -v test_alt
test_ciftler (test_alt.AltTest.test_ciftler) ...
  test_ciftler (test_alt.AltTest.test_ciftler) (n=7) ... FAIL

======================================================================
FAIL: test_ciftler (test_alt.AltTest.test_ciftler) (n=7)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_alt.py", line 13, in test_ciftler
    self.assertTrue(cift_mi(n))
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^
AssertionError: False is not true

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)

Rapor tek testi sayar ama başarısız yinelemeyi (n=7) etiketiyle gösterir; 2, 4 ve 10 değerleri de denenmiştir. Bu çıktı aynı zamanda assertTrue() mesajının ne kadar az bilgi verdiğini gösteriyor: burada assertEqual(n % 2, 0) yazmak "1 != 0" gibi daha açıklayıcı bir mesaj üretirdi.

Testleri atlamak ve beklenen hatalar

Bir testi koşulsuz atlamak için @unittest.skip(neden), koşula bağlı atlamak için skipIf ve skipUnless dekoratörleri kullanılır. Test içinde self.skipTest() çağırarak çalışma anında da atlayabilirsiniz. @unittest.expectedFailure bilinen bir hatayı işaretler: test başarısız olursa başarı sayılır, beklenmedik şekilde geçerse başarısızlık sayılır. Atlanan testlerde setUp() ve tearDown() çalışmaz.

python
import sys
import unittest

class AtlamaTest(unittest.TestCase):

    @unittest.skip('henüz yazılmadı')
    def test_rapor(self):
        pass

    @unittest.skipUnless(sys.platform.startswith('linux'), 'yalnızca Linux')
    def test_linux(self):
        pass

    @unittest.expectedFailure
    def test_bilinen_hata(self):
        self.assertEqual(0.1 + 0.2, 0.3)

    def test_yaklasik(self):
        self.assertAlmostEqual(0.1 + 0.2, 0.3)
bash
$ python -m unittest -v test_atla
test_bilinen_hata (test_atla.AtlamaTest.test_bilinen_hata) ... expected failure
test_linux (test_atla.AtlamaTest.test_linux) ... skipped 'yalnızca Linux'
test_rapor (test_atla.AtlamaTest.test_rapor) ... skipped 'henüz yazılmadı'
test_yaklasik (test_atla.AtlamaTest.test_yaklasik) ... ok

----------------------------------------------------------------------
Ran 4 tests in 0.001s

OK (skipped=2, expected failures=1)

Çıktı Windows üzerinde alındığı için Linux testi atlandı. Bu örnek ondalıklı sayılarla ilgili klasik bir tuzağı da gösteriyor: 0.1 + 0.2 == 0.3 karşılaştırması kayan nokta gösterimi yüzünden False verir, bu yüzden assertEqual başarısız olur. assertAlmostEqual() farkı varsayılan olarak 7 ondalık basamağa yuvarlayıp sıfırla karşılaştırdığı için geçer. Nedenini Python sayılar yazısında anlattık.

unittest.mock ile bağımlılıkları taklit etmek

Ağ isteği, veritabanı ya da saat gibi dış bağımlılıkları testte gerçekten çalıştırmak istemezsiniz. unittest.mock modülü, erişildikçe öznitelik ve metot üreten Mock nesneleri ve modül düzeyindeki nesneleri test süresince değiştiren patch() dekoratörünü sunar. Mock nesnesinin nasıl çağrıldığını sonradan kontrol edebilirsiniz:

python
import unittest
from unittest import mock

def kur_getir(istemci):
    yanit = istemci.get('/kur/usd')
    return yanit['satis']

class MockTest(unittest.TestCase):

    def test_kur(self):
        sahte = mock.Mock()
        sahte.get.return_value = {'satis': 41.25}
        self.assertEqual(kur_getir(sahte), 41.25)
        sahte.get.assert_called_once_with('/kur/usd')

Bu test de 3.15.2 ile OK verdi. return_value sahte metodun döndüreceği değeri belirler, assert_called_once_with() tam olarak bir kez ve bu argümanla çağrıldığını doğrular. Mock konusu kendi başına geniş olduğu için ayrıntılar için resmî Python belgeleri: unittest.mock sayfasına bakmanızı öneririz.

doctest: belgedeki örnekleri test etmek

doctest modülü docstring içindeki >>> ile başlayan etkileşimli oturum parçalarını bulur, çalıştırır ve çıktının yazılanla aynı olup olmadığını kontrol eder. Belgelerdeki örneklerin güncel kalmasını sağlamanın kolay bir yoludur:

python
def faktoriyel(n):
    """n! değerini döndürür.

    >>> faktoriyel(5)
    120
    >>> [faktoriyel(i) for i in range(5)]
    [1, 1, 2, 6, 24]
    >>> faktoriyel(-1)
    Traceback (most recent call last):
        ...
    ValueError: n negatif olamaz
    """
    if n < 0:
        raise ValueError('n negatif olamaz')
    sonuc = 1
    for i in range(2, n + 1):
        sonuc *= i
    return sonuc

if __name__ == '__main__':
    import doctest
    doctest.testmod()
bash
$ python faktoriyel.py
$ python faktoriyel.py -v
Trying:
    faktoriyel(5)
Expecting:
    120
ok
Trying:
    [faktoriyel(i) for i in range(5)]
Expecting:
    [1, 1, 2, 6, 24]
ok
Trying:
    faktoriyel(-1)
Expecting:
    Traceback (most recent call last):
        ...
    ValueError: n negatif olamaz
ok
1 item had no tests:
    __main__
1 item passed all tests:
   3 tests in __main__.faktoriyel
3 tests in 2 items.
3 passed.
Test passed.

Tüm örnekler geçtiğinde doctest hiçbir şey yazmaz; -v ayrıntılı günlüğü açar. Çıktı karşılaştırması metin düzeyinde yapıldığı için sözlük gösterimi, bellek adresi içeren repr değerleri gibi değişebilen çıktılar doctest için uygun değildir. Mevcut doctest'leri unittest paketine bağlamak için doctest.DocTestSuite kullanılabilir.

Sık yapılan hatalar

Sık yapılan hatalar: Metot adını test ile başlatmamak, Testlerin sırasına güvenmek, Test dosyasına standart modülle aynı adı vermek, Alt klasörde __init__.py unutmak
  • Metot adını test ile başlatmamak: kontrol_kdv() adlı metot test olarak çalıştırılmaz, hata da vermez.
  • Testlerin sırasına güvenmek: sıra metot adlarının alfabetik sıralamasıyla belirlenir; her test kendi hazırlığını yapmalıdır.
  • Test dosyasına standart modülle aynı adı vermek: unittest.py ya da random.py adlı dosya gerçek modülü gölgeler.
  • Alt klasörde __init__.py unutmak: keşif bu klasörlere inmez ve çıktıda "Ran 0 tests" ile "NO TESTS RAN" satırlarını görürsünüz (3.15.2 bu durumda 5 çıkış koduyla döner).
  • Test metodundan değer döndürmek: Python 3.11 ile None dışında bir değer döndürmek kullanımdan kaldırılmak üzere işaretlendi.
  • Ondalıklı sayıları assertEqual ile karşılaştırmak: assertAlmostEqual kullanın.

Sık Sorulan Sorular

unittest mi, pytest mi?

unittest standart kütüphanededir ve ek kurulum gerektirmez. Python belgeleri, daha hafif söz dizimiyle (assert func(10) == 42 gibi) test yazmayı sağlayan üçüncü taraf bir çerçeve olarak pytest'e işaret eder. pytest ayrı bir paket olduğu için kurulumunu bir sanal ortam içinde yapmanız önerilir; API ayrıntıları bu yazının kapsamı dışında.

Testi çalıştırınca "NO TESTS RAN" görüyorum, neden?

En yaygın nedenler: dosya adı test*.py desenine uymuyor, metot adları test ile başlamıyor, sınıf unittest.TestCase sınıfından türemiyor ya da testler __init__.py içermeyen bir alt klasörde duruyor. -p ile deseni, -s ile başlangıç klasörünü belirtebilirsiniz.

Tek bir testi nasıl çalıştırırım?

Tam adını verin: python -m unittest test_hesap.KdvTest.test_ozel_oran. Ada göre filtrelemek için -k ozel da kullanılabilir.

Komut satırı aracımı nasıl test ederim?

Ayrıştırma mantığını bir fonksiyona koyup parse_args() metoduna liste verin; böylece sys.argv ile uğraşmadan test edebilirsiniz. Örnekler için argparse rehberine bakın.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: Python öğrenme rehberi · argparse ile komut satırı · try/except hata yönetimi · raise ve özel istisna · logging modülü · venv ve pip