TotT: Better Stubbing in Python / Tuvalet Duvarında Test

debugging_vs_testing.PNG

Ben Python’la çalışmaya başladığım sıralarda Google “Google Testing Blog“u yayımladı. İlk yazıları ile birlikte yayımladıkları belgeyi hemen indirdim ve incelemeye başladım. Ne yazık ki o zaman Python hakkında yeterli tecrübeye sahip olmadığım için belgede anlatılmak istenen meseleyi anlayamamıştım. Zaman zaman belgeyi tekrar okuyup anlamaya çalışıyordum. En sonunda bugün (28 Ocak 2007) meseleyi tam olarak kavrayabildim.

Belgede anlatılanları ayrıntılı olarak açıklamaya çalışayım:

Elimizde aşağıdaki gibi bir fonksiyon bulunduğunu varsayalım.

def Foo(path):
  if os.path.exists(path):
    return DoSomething()
  else:
    return DoSomethingElse()

Bu fonksiyon dosya sistemimizdeki herhangi bir adresi parametre olarak alıyor. Bu adresin geçerli bir dosyaya işaret edip etmediğini kontrol ediyor. Sonuçta dosya mevcut ise “DoSomething()” değilse “DoSomethingElse()” fonksiyonunu çalıştırıyor.

Şimdi unit test sınıfımızın içerisinde bu fonksiyonu test eden bir fonksiyon yazacağız. Yapmak istediğimiz adresteki dosyanın var olması ve olmaması durumlarında yukarıdaki fonksiyonun davranışlarını test etmek.

def testFoo(self): # Somewhere in your unit test class / Unit test sınıfının içinde biryerde
  old_exists = os.path.exists
  try:
    os.path.exists = lambda x: True
    self.assertEqual(Foo('bar'), something)
    os.path.exists = lambda x: False
    self.assertEqual(Foo('bar'), something_else)
  finally:
    os.path.exists = old_exists # Remember to clean-up after yourself! / İşinizi bitirdikten sonra ortamı temizlemeyi unutmayın!

Bu fonksiyon ile bütün olasılıkları test ediyoruz. Fakat bazı durumlarda testlerin sonucu beklediğimiz gibi olmuyor. Örneğin “DoSomethingElse()” fonksiyonu başka bir dosyanın varlığını kontrol ediyor olabilir.

def DoSomethingElse():
  assert os.path.exists(some_other_file)
  return some_other_file

Sonuç olumsuz olacaktır çünkü “os.path.exists(path)”in hangi sonucu döndüreceğine test sırasında biz karar veriyoruz. Bu sorunu gidermek için birinci “os.path.exist” yapısını parametre olarak atayabiliriz.

def Foo(path, path_checker=os.path.exists):
  if path_checker(path):
    return DoSomething()
  else:
    return DoSomethingElse()

Böylece sadece yukarıda anlatılan problemi gidermiş olmuyoruz, aynı zamanda hız kazanıyoruz çünkü Python yerel değişkenlere daha hızlı ulaşabiliyor. Test fonksiyonumuz da aşağıdaki gibi kısaltılabiliyor.

def testFoo(self):
  self.assertEqual(Foo('bar', lambda x: True), something)
  self.assertEqual(Foo('bar', lambda x: False), something_else)

Debugging socks. Testing rocks. / Böcek avını bırak. Test etmeye bak.

Reklam

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s