“Test yazmaya zamanımız yok!”

Alpcan Aydın
Atolye15
Published in
6 min readDec 23, 2020

11. yılını doldurmuş bir şirket Atölye15. Sürekli gelişmeye inanan bir ekip olarak birçok konuda zaman içinde kötü yaptığımız şeyleri iyi yapmayı, iyi yaptığımız şeyleri daha iyi yapmayı öğrendik ve hala öğrenmeye devam ediyoruz. Kabul etmek gerekir ki hala kötü yaptığımız şeyler de olduğunu biliyoruz.

Aslında bu süreç hemen hemen bütün şirketlerin, geliştiricilerin ortak problemi. Hepimiz önceki yazılımcı esprilerini görünce gülüp eğleniyoruz. Ancak bir nokta var ki bazı firmalar süreçlerini iyileştirmenin başında, bazıları ortasında ama bazıları da böyle bir sürece bile girmiyor ve girme gibi bir niyetleri yok. Bu da geliştiriciler için bıkkınlığa yol açıyor.

Bu yazıda kendi tecrübelerimizden, yaptığımız yüzlerce iş görüşmesinden çıkarımını yaptığımız ortak dertlerden ve biz bunlara nasıl yaklaşıyoruzdan bahsedeceğim. Problemlere girmeden önce bunların bizim bakış açımız olduğunu, tamamen subjektif sonuçlar elde edildiğini, bir başka sürece veya topluluğa uymayabileceğini belirtmekte fayda var.

Hazırsanız başlıyoruz.

Test yazmaya zamanımız yok

Bu iş görüşmelerinde açık ara en çok duyduğumuz cümle. Ne zaman ki testler hakkında bir sohbet açılsa çoğunlukla ilk duyduğumuz söylem “Aslında ben test yazmak istiyorum, ancak şirketim çok zaman alacağı için izin vermiyor. Ben de kendi hobi projelerimde test yazıyorum.” şeklinde oluyor.

Bize göre bu düşünce şekli iki yönden çok doğru değil. Testlerin yararlarına gelmeden önce şunu düşünmek gerekiyor; nasıl ki bir geliştirici serüvenine başladığında çoğunlukla spagetti kod yazıp, yaptığı hatalar sonucu oluşan dil yanmalarından daha sürdürülebilir production kodu yazmayı öğreniyorsa, aynısı testler için de birebir geçerli. Production kodunda yapılan bir değişiklikle otuz tane test patladığında, testlerin yanlış kurgulandığını, davranış yerine yazılan production koduna odaklanıldığını kişinin bizzat zaman içinde deneyimleyip öğrenmesi gerektiğini düşünüyoruz.

Birçok test çeşidi ile birlikte, birçok test yöntemi de mevcut. Sürdürülebilir test yazmak için de bunu sıkça tekrar etmek gerekiyor.

İkinci konu ise başlığı oluşturan “Zamanımız yok.” düşüncesi. İtiraf etmek gerekir ki yeterli bir test coverage’ı ile geliştirilen increment, testsiz geliştirilecek süreye göre daha fazla zaman alıyor. Buradaki zaman faktörü ekibin test tecrübesine ve feature’ın iyi tanımlanmasına göre değişir elbette. Bu noktada aslında bir trade-off’a düşüyoruz.

  1. Hızlıca increment deliver edip bunu manuel test ederek çalıştığından tahmini bir şekilde emin olmak ve sonsuz zamanda çıkabilecek regresyonları sürekli olarak manuel kontrol etmeye devam etmek.
  2. Daha uzun sürede unit, integration ve E2E testlerini de yazarak feature’ın çalıştığından senaryolar kadar kesinlikle emin olmak ve sonsuz zamanda çıkabilecek regresyonları her zaman bilmek ve hatta regresyon ihtimalini minimuma indirmek. Buraya tabii ki dezavantaj olarak test kodlarının da bakımını eklememiz gerekiyor.

Bu iki değişkenli denkleme baktığımızda biz her zaman ikinci yoldan gitmeyi tercih ediyoruz. Çünkü kısa vadede zamanımız yok diye yazmadığımız testler uzun vadede daha fazla “Zamanımız yok.” bahanesine dönüşüyor. Çünkü biz zamanımızı, çıkan hataları çözüp bunlara yeni hatalar eklemek ile harcıyoruz.

Deadline’a yetişmemiz lazım

İş görüşmelerinde en çok duyduğumuz ikinci yakınma diye adlandırabileceğimiz söylem ise farklı farklı kalıplarda bize geliyor. Bunlar; “Deadline’a yetişmemiz lazım.”, “Sürekli feature ekliyoruz, refactoring yapamıyoruz.”, “Bir şekilde bitirmemiz lazım.” gibi söylemler şeklinde sıralanabilir. Bizim düşüncemiz aslında hiç bir zaman deadline’ları kötülemek değil. Çünkü koyulan deadline tarihi çoğunlukla arkasında mantıklı bir sebep barındırıyor. Belki bir fuara katılınacak, belki bütün marketing planlamaları o tarihe göre yapıldı, belki bütçe o tarihe göre alındı gibi gibi sonsuz haklı sebepler söyleyebiliriz.

Bizce, deadline ile ilgili bir problem hissedildiğinde alınması gereken aksiyon; “O zaman hızımızı arttıralım.” gibi konuyu işçi problemine çevirmek yerine önceliklerimizi tekrar gözden geçirmek. Bu tarihe yetiştirebileceğimiz ve kesinlikle olması gereken şeyler neler, daha sonraya neleri atabiliriz, bu feature gerçekten şu üç senaryo olmadan da olur mu gibi soruları, sürece katılan herkesle birlikte cevaplayarak tekrar bir release planı yapmamız en sağlıklısı olacaktır.

Tüm bunlara ek olarak bizce tek bir tane deadline yerine, o deadline’a ulaşmak için aşılması gereken birkaç tane ufak milestone belirlemek her zaman daha iyi olacaktır. Bu küçük hedefler, ana hedeften ne kadar uzakta olduğunuzu size daha iyi gösterecek ve zaman planınızı sürekli gözden geçirmenizi sağlayacaktır. Ayrıca, ekip motivasyonu için uzakta bir hedef yerine, daha yakındaki ufak hedeflerin her zaman daha olumlu sonuçlar doğurduğunu gördük.

Deadline’a yetişmek için kod kalitesinden ödün vermek ise belki de bu başlığın en çok alınan aksiyonu. Bu durum maalesef birkaç tane olumsuz sonuç doğuruyor.

  1. Yazmadığımız her test bize regresyon olarak geri dönüyor ve her yeni feature’da sistemimize yeni bug’lar katıyoruz. Bu söylem, her şeyiyle doğru ilerleyen projelerde hiç bug çıkmaz anlamına gelmiyor. Burada sadece çok rahat bir şekilde engellenebilecek bug’lardan bahsediyoruz.
  2. Gelecek düşünülmeden yazılmış her kod aslında daha fazla deadline baskısı yaratıyor. Çünkü düzgünce planlanmamış her bir kod parçasına yeni bir kod parçası eklemek, zaman geçtikçe daha da zorlu bir eylem haline geliyor. Yani başlangıçtaki zaman baskısından kurtulmak için, sürekli katlanarak artan bir deadline baskısı yaratıyoruz.
  3. Refactoring için ayırmadığımız her bir zaman, refactoring yapmaya korkan ekipler yaratıyor. Zaman içinde biriken o kadar fazla güncellenmesi gereken yer oluyor ki artık hiçbir kimse bu sorumluluğa girmek istemediği için günün sonunda aşağıdaki maddeye geliyoruz: Baştan yazmamız lazım. Bu da, başlı başına yeni bir deadline demek.

Bunu baştan yazmamız lazım

İtiraf etmek gerekir ki bunu biz de birkaç defa dedik. Zaten aslında Atölye15 olarak her zaman çok iyiyiz gibi bir iddiamız da yok. Birçok hata yaptık ve bu hataların sonuçlarını yaşadık. Açıkçası bana kalırsa bir şeyleri iyi yapma isteği genellikle içinde bulunulan veya başkasından duyulan kötü süreçlerden öğrenilen dersler sonucu ortaya çıkıyor.

“Bunu baştan yazmamız lazım.” cümlesi bir sonuç. Tabii ki her zaman haklı bir söylem olmayabilir ama biz haklı olduğunu varsayalım. O zaman belki de sebeplere yoğunlaşmamız gerekiyor. Bu sebepleri de birkaç alt başlık altında inceleyebiliriz.

Yazılmamış testler

Kabul etmeliyiz ki her bir kod bloğu zamanla legacy kod haline gelecektir. Önemli olan ise codebase’imizi sürekli refactor edebilmek. Bunun için de iki şey lazım; birincisi refactoring için cesaretli ve istekli bir ekip, ikincisi ise bu cesareti verebilecek güvenilir testler. Refactor’ün riskli bir iş olduğu ekiplerde insanlar zaman içinde gönüllü olarak bu işi yapmaktan çekinirler. Çünkü refactor ettiği kapsamda bir problem çıkarsa bu artık onların sorumluluğu olur ve kendini “Keşke hiç ellemeseydim.” derken bulurlar. Bir yerden sonra insanlar sadece kendi görevlerini yapar ve kötü davrandığını düşündükleri kodları kullanmaya devam ederken bunların hala codebase içinde yaşamasına izin verirler.

Zaman geçtikçe, bırakın refactor yapmayı, yeni bir şey eklemek bile işkence haline gelir. Bir gün, bu işkenceye daha fazla dayanmak istemeyen ekip “Bunu baştan yazmalıyız.” cümlesine sarılmaya başlar. Oysa ki başta söylediğim gibi bu bir sonuçtur. Yani eğer bu sonucun sebepleri değiştirilmeden bu ekip gerçekten bu işi baştan yazarsa büyük ihtimalle bir kez daha “Bunu baştan yazmamız gerek.” cümlesini kendilerine söylerken bulabilirler.

Testlerine güvenen her ekip ise kendilerini sürekli refactoring yaparken bulur. Çünkü yaptıkları değişikliklerin nelere sebep olduğu bellidir. Testler yeşil kaldığı sürece istenilen şekilde süreç tekrar tekrar kurgulanabilir.

Yanlış yazılmış testler

Yanlış yazılmış testleri, hiç yazılmamış testlere tercih etsek de davranışı değiştirmeyecek şekilde yapılan kod değişiklikleri çok sayıda testin fail olmasına sebep oluyorsa burada testlerin belki de yanlış yazıldığından bahsedebiliriz. Çok fazla kod odaklı yazılmış testler aslında “Sistem doğru çalışıyor mu?” sorusundan ziyade “Kafamdaki kodu doğru yazmış mıyım?” sorusunu kontrol eder. Dolayısıyla refactor sürecine girildiğinde ve kafamızda başka bir kod yazım şekli oluştuğunda artık testlerimiz fail olmaya başlar. Bu sürecin sürekli yaşandığı codebase’lerde testlerin atıl duruma dönmesi ve doğruluk kaynağı olmaktan çıkması an meselesidir.

Yarın yokmuş gibi yazılan kodlar

Durmaksızın feature eklemekle uğraşan ekipler, bir yerden sonra kendilerini sürekli bir yere yetişmeye çalışıyorlarmış gibi bulabilirler. Bu da bir süreden sonra kişilerde tepkisizlik olarak semptom gösterebilir. Yani kişi artık yaptığı işin kalitesinden ziyade sadece işi bitirmeye odaklanır. Bu da tahmin edersiniz ki verimsiz bir süreç ortaya çıkarır.

Bu başlığa ek olarak yine zaman baskısı eklenebilir ama onun da sonuçları yine çok farklı olmayacaktır. Zaman baskısı ile nasıl mücadele ettiğimizi üst başlıklarda açıklamaya çalıştım ancak sadece yeni feature eklemeye odaklanan ekipler ile ilgili birkaç şey söyleyebiliriz.

Uygulamaların zaman içinde evrilmesi, belki pivot etmesi, revizenin de revizesinin olması aslında yadsınamaz süreçler. Yaptığımız ürün yaşayan bir varlık ve dolayısıyla zaman içinde hedef kitlesi, çözmeye çalıştığı problem veya problemi çözüş şekli de değişiyor. Buna itiraz edemeyiz. Ancak aklımızdan çıkarmamamız gereken şey; zamanımızın bir kısmını da var olan codebase’imizi veya feature’larımızı daha iyi hale getirmeye ayırmamız gerektiği. Çünkü ekip bir şeylerin yanlış gittiğini farkettiğinde istemsizce oraya takılı kalacaktır ve onu düzeltmek yerine üstüne yeni bir şey eklenmesi istendiğinde bu konu hakkında çok da istekli olmayacaklardır. Bu süreç devamlı hale gelirse bahsettiğimiz bıkkınlık evresi devreye girebilir ve ekip robotlaşabilir.

Aslında hepimizin bildiği daha birçok ve tahmin edebileceğiniz başlıklar bulunuyor. Biz bir kısmını birinci elden zaman içinde yaşadık. Bir kısmını ise başkalarından tecrübe edindik ve genel olarak bu problemlerin farkındayız. Elimizden geldiğince çözmeye ve süreçlerimizi iyileştirmeye çalışıyoruz. Eğer sen de bunun için katkıda bulunmak istersen kariyer sayfamızdan bize başvuruda bulunabilirsin.

--

--