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.