Birim Testler ile Doğruluğa Yaklaşma

Yazılımcıların sıklıkla yaptığı bir hata vardır. Geliştirdikleri kodu önlerindeki basit veri senaryosuna (happy path) göre geliştirip onun tüm senaryolarda çalışacağını varsayarlar. Geliştirdikleri yazılımın yeterince sınamadan çözümü genelleştirdiğine inanırlar. Bu problemin temel kaynağı kısıtlı zaman, teknik bilgisizlik ya da etik dışı davranış değilse, konunun bilimsel sürecine dair bilgisizlik olabileceği kanısındayım. Bilim felsefesi bize bu konuda yol gösterebilir diye düşünüyorum. Bu yazıda yazılımcının yazdığı ilk satır kod ile beraber ortaya cesur ve kapsayıcı bir kuram koyduğunu ve o kodun bilimsel olması için onu sınaması gerektiğini iddia edeceğim. Eğer kod üretme şeklimiz bilimsel değilse fal bakanlardan ne farkımız kalır öyle değil mi.

Doğruluğa Yaklaşma

Bilim felsefesine bakarak başlayalım. Karl Popper’ın bilim kuramının en önemli fikirlerinden biri olduğunu söylediği “doğruluğa yaklaşma” fikrini ele alalım. Örneğin:

Tüm kargalar siyahtır.

Bu cesur kuram aşırı basit olmasına ve bize nedensel bir açıklama yapmamasına rağmen bilimseldir. Bilimsel olmasının sebebi yanlışlanabilir olmasıdır. Bir tek beyaz karga gözlemleyebilirseniz bu kuramı çürütebilirsiniz. Kuram kendi içinde bu bilgiyi sağlamaktadır. Sorun şu ki kuram sahibi bugün bütün kargaları görebilse bile gelecekte siyah olmayan bir karga görülüp görülemeyeceğine asla emin olamaz. Her gün yeni kargalar doğduğunu unutmayalım. Kuram şu anda doğru olsa bile bu doğanın kendisi değişebilir. Araştırmacı, bilim alemine rezil olmak istemiyorsa bu kuramı öne atmadan önce elinden geldiğince gezmeli ve çok gözlem yapmalıdır. Bu yüzden de bilimsel bilgi kesin değildir diyoruz. Eğer Asya’da bir beyaz karga görürse kuramını “Avrupa’daki tüm kargalar siyahtır” diye özelleştirerek yenileyebilir. Her yenilemede doğruya biraz daha yaklaşmış olacaktır. Şimdi bir analoji yaparak bu yöntemi yazılım geliştirmeye uygulamaya çalışacağım:

Geliştirdiğim X yazılımı Y problemini çözer.

Bu kuramımıza göre geliştirdiğimiz X programı cesur bir genelleme yapıyor ve Y problemini çözdüğünü iddia ediyor. Burada Y, problemi çözmemiz için bize aktarılmış olan analizi temsil etsin. Peki X yazılımı bilimsel mi? Bilimsel olması için yanlışlanabilir olması gerekir. O zaman kuram sahibinin (yazılımcı) herkes tarafından nesnel olarak gözlemlenebilecek bir yöntem önermesi, yani siyah olmayan en az bir karga göstermenin yolunu da göstermesi gerekir. Burada yazılımcının geliştireceği her birim test senaryosunu (test case) gözlemlediği bir kargaya, tüm test senaryo grubunda (test suite) en az bir testin kırmızı olmasını ise siyah olmayan en az bir kargaya benzetebiliriz. Yazılımcı ürün sponsoruna rezil olmak istemiyorsa X yazılımını sürmeden (release) önce elinden geldiğince (code coverage) test senaryosu üretmelidir. Sonsuz sayıda olan senaryoları (kargalar) üretmek mümkün olmadığı için X’in kesin doğru çözüm olduğuna asla emin olamaz. Mevcut Y analizine göre X’in tüm senaryolarını (T) test etse bile yeni kargalar doğacak, doğa değişecek yani Y analizi değişecektir. Y analizi sürekli değişebiliyor ise yazılımcı hiçbir zaman rahat uyuyamayacak ve X yazılım projesi hiçbir zaman bitmeyecektir. Değişen ve gelişen Y analizine göre X yazılımı her geçen gün daha karmaşıklaşacak (kuramın kapsamı daralıyor) ve artık sadece kargaların rengine bakmak yeterli olmayacak, her birine kan testi de yapması gerekecektir. Y her değiştiğinde T içindeki bazı senaryoların güncellenmesi, X her değiştiğinde de T’nin kurama uyduğuna tekrar emin olunması gerekeceğinden bunu otomatik olarak daha hızlı yapmanın yolları aranacaktır…

Buraya kadar testlerin X yazılımını bilimsel kıldığına ikna etmeye çalıştım. Yazılım geliştirme bilimsel bir süreç ise birim testler (ya da testler) yazılımcının laboratuvarıdır. Laboratuvarlar objektif deney/gözlem yapmamız için olmazsa olmaz araçlardır. Objektif ölçme yöntemleri olan çabaları bilimsel, subjektif yöntemleri olanları ise sanatsal kabul edersek çevik dünyada sıklıkla kullanılan “The Art of Programming”, “Sanat”, “Zanaat” gibi ifadeleri çok da uygun olmadığını düşünebiliriz. Yazılım geliştirme kendi başına bir bilim ya da mühendislik olmasa da bilimsel bir süreç gerektirdiği görülüyor.

Çeviklik

Son olarak buradan çeviklik (agility) ile ilgili de bir bağlantı çıkartmak istiyorum. X yazılımı hiçbir zaman mükemmel (kesin doğru) olmayacaksa ama doğruluğa yaklaşacaksa bir anda nihai kuramı bulmak yerine, kuramı sürekli olarak basitten karmaşığa doğru gidecek şekilde aşama aşama güncellemek akla yatkın olurdu. Her aşamada eklediğimiz bir özellik (feature), kapsamı daraltarak her seferinde daha fazla ve karmaşık kodla problemi daha sorunsuz çözen bir kuram üretecektir. Genelden özele gittikçe doğadaki bilinmezlikler azalacak, gözlem yapmak zorlaşsa da gittikçe daha fazla işe yarayan bir çözümün oluştuğu görülecektir. Bu durumda en basit kuram ile en fazla iş değeri taşıyan özellikleri ilk kuramlara dahil etmek (önceliklendirme) akla yatkın olurdu. Süreç hiç bitmeyeceğine göre elimizdeki X’lerden hangisinin ne zaman yayına alınacağına karar vermek bu kuramın ne kadar işe yaradığını ölçebilen X’in sponsoruna bırakılabilir.

Geri bildirimler için yazıyı Medium'da aç.