Yüksek kaliteli yazılım geliştirmeyi öğrenememenin gerçeği
(florianbellmann.com)- Birçok proje QA önlemlerini sonraya bırakıp sürümden hemen önce büyük bir QA sprintine bel bağlıyor ve aynı kaosu bir sonraki döngüde de tekrarlıyor
- Bilgisayar mühendisliği eğitimi algoritmalar ve dillere, proje yönetimine zaman ayırsa da yazılım kalite güvencesini çoğu zaman pratik iş düzeyinde ele almıyor
- Şirketlerde bütçe yetersizliği, geliştirme gecikmesi ve kapsam artışı olduğunda ilk kısılan alan genellikle QA oluyor; yalnızca asgari düzeyde ve yapısız testlerden geçmiş kırılgan yazılımlar dağıtıma çıkıyor
- QA için ikna etmek gerektiğinde “daha kararlı” gibi soyut ifadeler yerine, yapılmadığındaki maliyeti geliştirme maliyetindeki artış veya sürüm stabilizasyon süresinin uzaması üzerinden anlatmak gerekiyor
- Tüm kalite sistemini bir anda kurmak yerine, müşteri değeriyle doğrudan bağlantılı çekirdek işlevleri önce korumak ve yeni özellikler için testleri uygulama anında yazmak daha gerçekçi
Sürümden hemen önceye itilen QA
- Birçok projede önemli kalite güvence önlemleri eksikken geliştirme devam ediyor
- Gerekliliği bilinse bile gerçek uygulama çoğu zaman sürümden hemen önce yapılan büyük QA sprintine sıkışıyor
- Bu yaklaşım stresi artırıyor ve yazılımı ancak zar zor çalışır hale getirmekle sonuçlanıyor
- Aynı kaos bir sonraki sürüm döngüsünde de tekrarlanıyor ve yapısal iyileştirmeye dönüşmesi zor oluyor
Eğitim ile pratik arasındaki kalite boşluğu
- Bilgisayar mühendisliği programları çoğunlukla algoritmalar, bilgisayarların çalışma mantığı ve dillerin tarihi ile kavramlarına odaklanıyor
- Proje yönetimi yöntemleri veya Scrum öğretilen dönemler olabilir, ancak QA tamamen dışarıda kalabiliyor
- Mezunların %90'dan fazlası şirket bağlamında çalışacağından, belirli bir süre içinde hatasız yazılım teslim etme becerisine ihtiyaç duyuyor
- QA'nın eğitimde ihmal edilmesi, gerçek iş gereksinimleriyle örtüşmüyor
Şirketlerde QA’nın ilk kısılan alan olması
- Projelerde bütçe sorunu çıktığında ilk çıkarılanlar çoğu zaman QA standartları ve önlemleri oluyor
- QA sık sık projenin sonuna bırakıldığı için geliştirme uzadığında veya kapsam büyüdüğünde kaliteyi güvence altına alacak zaman kalmıyor
- Sonuç olarak yalnızca asgari düzeyde, yapısız testler yapılıyor ve kırılgan yapıda bir yazılım dağıtıma çıkarılıyor
- Bazı ekiplerde QA standartları var, ancak bu genelde kıdemli bir ekip üyesinin diğerlerine bunları dayatması şeklinde işliyor
- Standartlar olsa bile ekip testleri yalnızca proje yönetimi metriklerini tutturmak için yazıyorsa, bu yeterli kalite güvencesine dönüşmeyebiliyor
Tekrarlayan kalite sorunlarını kırmanın ilk adımı
- QA önlemlerinin eksik olduğunu dile getirmek için deneyim ve özgüven gerekiyor
- Sürüm öncesi crunch dönemi, arıza veren production sistemleri ve eksik izleme sonunda tüm ekibin yükü haline geliyor
- Refactoring gibi yöneticiler için doğrudan görünür olmayan iyileştirmeleri savunmak zor; QA ise daha önce düzgün yapılmadıysa daha da göz korkutucu gelebiliyor
- Sorunları tekrar tekrar dile getirmek ve tartışmayı yeniden açmak, ilk adımı oluşturabiliyor
QA’yı paranın diliyle anlatmak
- “Yazılım daha kararlı olur” ya da “bakımı kolaylaşır” gibi ifadeler, codebase üzerinde çalışmayan kişiler için yeterince somut olmayabiliyor
- Geliştiricilerin anlatması gereken şey, QA yapmamanın maliyeti
- Örnek ifadeler şöyle olabilir
- Bunu şimdi yapmazsak 4 ay sonra geliştirme eforu ve maliyeti %15 artacak
- Tüm işlevlere unit test eklemezsek sürüm stabilizasyon aşaması her seferinde uzayacak
- Yeni özellikler arttıkça yan etkileri her defasında manuel test etmek gerekecek ve her sürümde ilerleme yavaşlayacak
- Bu yaklaşım, iş tarafı ve yöneticilere aktarılması kolay bir dil sunuyor
- Sonuçta QA önlemleri hem geliştiricilerin hem de yöneticilerin hayatını iyileştirebilir
Minimum etkili dozla başlamak
- QA’yı büyük bir ön yatırım olarak aşırı tasarlamak, projenin ilerlemesini engelleyebilir ve paydaş onayı almayı zorlaştırabilir
- Gerçekçi başlangıç noktası, uygulamadaki en önemli bölümleri bulmaktır
- Genelde tüm uygulamanın dayandığı belirli kullanım senaryoları, işlevler veya çekirdek davranışlar vardır
- Müşteri için değer üretebilmesi adına mutlaka doğru çalışması gereken çekirdek işlevler önce test edilmelidir
- Minimum etkili doz (MED), istenen sonucu üreten en küçük doz anlamına gelir
- QA bağlamında MED şu seçeneklerden biri olabilir
- Manuel test planı
- Pipeline içindeki otomatik testler
- Çekirdek davranışı garanti eden başka önlemler
- Çekirdek işlevler güvence altına alındıktan sonra kararlılık kademeli olarak genişletilebilir
- Her yeni özelliğe unit test eklenmeli; dış API'ler veya kullanıcı girdileri gibi kontrol edilemeyen bilgiler de doğrulanmalıdır
- QA da tekrar eden ve kademeli biçimde iyileştirilmelidir
Yeni projede sorulacak QA soruları
- Yeni bir projeye başlarken veya katılırken, küçük ölçekte bile olsa bir QA anlayışı olup olmadığı doğrulanmalıdır
- Ekip şu sorular üzerine düşünmelidir
- Ne dağıtıyoruz
- Neyin mutlaka çalışması gerekiyor
- Bunu nasıl garanti ediyoruz
- Hangi önlemleri bilinçli olarak almıyoruz ve neden
- Bunları yazılı hale getirip bir test planı eklemek, yazılımın ilerlemesi için iyi bir temel oluşturur
- Seçilen yaklaşımın düzenli olarak, örneğin her çeyrekte, gözden geçirilmesi faydalıdır
Testleri uygulamayla birlikte yazmak
- TDD kullanılmasa bile, yazılım geliştirilirken testlerin de birlikte yazılması önerilir
- Bir özelliğin uygulandığı an, test yazmak için en iyi andır
- Uygulamayla aynı anda test yazmak, kodun gerçekten test edilebilir bir yapıda olmasını zorunlu kılar
- Testler sonradan mevcut yazılıma eklenmeye çalışıldığında, kodun aşırı derecede birbirine bağımlı olduğu veya tek sorumluluk ilkesini ihlal ettiği sıkça ortaya çıkar
- Testler, istenen davranışın anlaşıldığını ve beklendiği gibi çalıştığının doğrulandığını anlatan bir açıklama olur; aynı zamanda bir tür kod dokümantasyonu işlevi görür
Projeye ve kişiye geri dönen etkiler
- Kalite tartışmasını açmak ve mümkün olan çözümler önermek, çevreye projeyi önemsediğinizi gösterir
- Kalite tartışmaları geliştirici olarak etki alanınızı genişletebilir
- Geliştiricilerin ve yöneticilerin yaşam kalitesi de yükselebilir
- Proje, QA önlemleri olduğunda sağlıklı bir hızla büyüyebilir
- Herkesin bir QA elçisi olması gerekmez, ancak küçük bir MED ile başlayıp ekip içinde daha iyi bir yöntemi göstermek mümkündür
1 yorum
Hacker News yorumları
Bu tür içerikler öğretiliyor. Sadece temel bilgisayar bilimi derslerinde değil, yazılım mühendisliği gibi seçmeli derslerde yer alıyor
CMU'da yazılım mühendisliği yüksek lisans ve doktora programları da var; blog yazısının anlattıklarını ve daha fazlasını kapsıyorlar. CS ile SE arasında büyük bir kopukluk var, ama durum “kimse kaliteli yazılım yapmayı öğretmiyor” seviyesinde değil
İronik biçimde, öğrenciyken en sevmediğim ders yazılım mühendisliğiydi. UML'ye sıkı sıkıya bağlı tasarım desenleri dersi eski görünüyordu; Java ekosistemindeki TDD ve araçları öğreten QA dersi de sıkıcıydı. Birkaç yıl sonra, yüksek güvenlik gereksinimli yazılımlar için test iş akışları ve araçları kuran bir ekibe katıldığımda, yapılması gerekenleri zaten bildiğim için iş arkadaşlarım şaşırmıştı
Öğretilse bile genelde eski kalıyor ya da web uygulaması yazmak gibi çok kelimesi kelimesine konulara kayıyor. Uygulamaya, ekip çalışmasına ve karmaşık sistemler kurmaya odaklanan bir ders olsaydı gerçekten almak isterdim
Bu tür konuları seçmeli derslere ya da yüksek lisans programlarına bırakmak yerine lisans düzeyinde yazılım mühendisliği programlarına ihtiyaç var; CS öğrencilerinin %90'ı da oraya geçmeli
Kod tabanı virüs/kötü amaçlı yazılım taraması sunan basit bir servisti; tarayıcılar ve imzalar dâhil her zaman eklenecek iş çıkacak şekilde tasarlanmıştı. 15 yıldan da eski bir fikirdi ama sürekli devam eden harika bir ders olabilirdi; bölümü ikna edememiş olması üzücü
Lisans yıllarımı tanımlayan ders denecek kadar olmasa da ona epey yakındı; sistem tasarlayan çoğu kişinin bunları bilmemesi aynı anda hem öfke hem de varoluşsal bir korku veriyor
CS derecesi olan insanlarla çalışmanın kolay olmasının nedeni, iyi algoritmalara duyulan ihtiyacı ya da parser ve kriptoyu baştan yazmamak gerektiğini anlatmaya daha az ihtiyaç duyulması
Buna karşılık yazılım mühendisliği tarafında kalite, ekip çalışması ve diğer ekiplerle iş birliği konusundaki saflığın benzer biçimde törpülendiğine inanmayı sağlayacak bir yeterlilik yok. Hızla korkunç, doğrulanmamış kod yazıp sorun patlamadan önce ayrılma deneyimiyle bilenmiş insanlar ortaya çıkıyor; yönetim de bu insanları seviyor ve geride kalıp enkazı temizleyenleri küçümsüyor
Belirgin ayraçları olan metin tabanlı protokoller genellikle çok kolay parse edilebilir; kullanım senaryosuna göre yalnızca bir kısmını ele almak da yeterli olabilir. Elbette testler ve işlev gereksinimleri düşünülmeli. Bir dil geliştiriyorsanız tavsiye değişebilir
Yeni başlayanlar kendileri yazar, orta seviye geliştiriciler ve orta ölçekli projeler parser üreticileri kullanır; en gelişmiş parser'ları sürdürenler de elle yazmayı tercih eder. GCC eskiden bison parser kullanıyordu ama daha iyi hata mesajları için elle yazılmış recursive descent parser'a geçti; Clang de recursive descent kullanıyor
Kişisel olarak bildiğim tek istisna jq; bu yüzden jq uygulamasında faydalı söz dizimi hata mesajları üretmek zor
Parser yazmak tek bir ödeve sığacak kadar basit olabilir; elle yazılmış parser kodu da sonunda LL gramerine benzer. Parsing, derleyici ya da dil araçları yazmanın en kolay kısmıdır; bu yüzden elle yazılmış bir parser ekip için fazla yüksek bir çıtaysa projenin tamamı şüpheli olabilir. Parser üreticilerini asla kullanmayalım demiyorum; ama ek araçlarla build'i karmaşıklaştıran ya da Bison/ANTLR gibi eski araçlar kullanan projelere kıyasla, iyi test edilmiş elle yazılmış parser'ı olan bir projede çalışmayı tercih ederim
Yine de genel standartlar 20 yıl öncesine göre yükselmiş gibi. Örneğin kaynak kontrolü, birim testleri ve CI/CD artık tartışmalı değil
“Hatasız yazılımı zamanında teslim etmeliyiz” varsayımı, kaliteli yazılım üzerine bir yazıya başlamak için oldukça kötü bir çıkış noktasıdır.
Hatasız kod dağıtabileceğinize inanıyorsanız meslek değiştirmenin zamanı gelmiş demektir.
Birim testleri, entegrasyon testleri, kullanıcı kabul testleri; hepsini yapsanız bile tek bir kod değişikliği yeni bir hata olasılığı demektir. Bir geliştirici “Ben asla hatalı kod dağıtmam” dediğinde, bunun ne anlama geldiğini daha fazla sorgulamak isterim.
“Fonksiyonu yazdım”, “fonksiyonu test ettim”, “ağın ötesinden çağrılan fonksiyona kadar test ettim” aşamalarını geçince, sınır koşullarını ne kadar iyi yakalasanız ve QA’yı ne kadar titiz yapsanız da belirli bir ayarda, belirli bir donanımda, belirli bir çekirdekte her zaman 0-day tanımsız davranış kaldığını fark edersiniz. Testlerden, insan gözünden ve incelemeden geçtiği için neredeyse hatasız olduğunu garanti ettiğinizi söylemekle yetinirsiniz; sonunda yapabileceğiniz tek şey parmaklarınızı çaprazlamak olur.
Düzeltmesi bir hafta süren ama yalnızca az sayıda kullanıcının çok nadir bir durumda karşılaştığı bir hataysa, düzeltmemek mümkün olabilir.
Bilgisayar bilimi programları da var; staj ve uygulamayı vurgulayan üniversiteler de var. Ama birçok üniversitedeki CS bölümü matematikten doğmuştur ve teori odaklıdır.
Kimyanın kimya mühendisliği olmaması gibi, bunun da sorun olmadığını düşünüyorum. Üniversite basitçe bir meslek okulu değildir; neredeyse tüm diplomaların amacı düşünme becerisini eğitmek ve karmaşık içerikleri öğrenme kapasitesini göstermektir.
Gerçek dünyada işe yarayıp yaramadığını dikkate almayan saf üniversite eğitimi eğitim açısından zararlıdır; ama anlamadan yalnızca yöntemi öğreten saf mesleki eğitim de yararlı değildir. Yine de gerçek meslek okulları tamamen böyle değildir; zor kısımların üzerinden geçseler bile önemli konularda derin bir anlayış kazandırma eğilimindedirler.
Yine de profesyonel yazılım dünyasına göz atmak için iyidir.
Bunlar iyi geliştirme organizasyonlarında öğrenilir. 10-15 yıl önce kabaca FAANG böyleydi; bugün TailScale gibi yerler buna örnek.
Gereksiz mikroservisler ve katman katman Docker, JSON serileştirme/ters serileştirme katmanları, yalnızca coverage için yazılmış birim testleri yığını bırakıp QuickCheck, Hypothesis ve fuzzing’i görmezden gelmeyebilirsiniz. Yığın hâlinde değişiklik setleri, kodu yazan ekibin on-call rotasyonu, dinamik bağlama ve zorunlu kılınmamış bağımlılık hatalarını en aza indirme, yönetilen dil runtime’ına uygun tasarım, dilin okunabilir sözel sözdizimini “okunabilirlik” diye şart koşma; bunların hepsi mümkündür. Defalarca görmezden gelinse de kaliteli yazılım dağıtmanın yolu kamusal bilgidir.
Kaliteli yazılım hakkında fikirleri olabilir ama bu yorumu anlamak zor.
Neye bakmak gerekir, önerebileceğiniz kitap ya da ders var mı bilmek isterim.
“Bunu şimdi yapmazsak 4 ay sonra geliştirme eforu ve maliyet %15 artar” türü bir iddiayı destekleyecek kadar geçerli ölçümlere ulaşmak zordur.
Bir startup’ta iki kurucunun “birim testi yazmayın” dediği olmuştu. Tartışmadım; bu sözün gerçek anlamının çok yavaş olduğumuz, bu yüzden olabildiğince hızlı dağıtmamız gerektiği olduğunu anladım. Hızlı dağıttım, kaliteyi de korudum, birim testleri de yazdım. Onların bunu bilmesine gerek yoktu; yalnızca sonuca ihtiyaçları vardı. Bu tartışmanın gizli özü, çoğu yazılım organizasyonunun hem hızlı hem de kaliteli dağıtmayı bilmemesidir. Sihirli bir formül yok; bireysel zanaatkârlık gerekir ve bu aynı zamanda bir takım sporudur. Koşullar her yerde farklıdır; hafif süreçler kısmen işe yarayabilir ama etkileri sınırlıdır. Sonunda deneyime, doğru değerlere ve değer sunmaya odaklanan bilgeliğe sahip iyi bir ekibe ihtiyaç vardır.
Üniversitenin sektörde yazılım yapmayı öğrettiği varsayımı oldukça cesur bir iddia.
Ayrıca bu yazı, yazılımın CD ya da disketle dağıtıldığı 90’lardan kalma bir yazı gibi görünüyor. Günümüzde sürekli dağıtım pipeline’ları yüzünden “release” kavramı çoğu zaman bulanıklaşıyor ve bu iyi bir uygulama olarak görülüyor. Bu durumda QA departmanının bir release’in hatasız olduğunu elle garanti etmesi epey eski moda görünüyor.
Yükseltmesi kolay olmayan cihazlara yüklenip gönderilen kodu yazanlar da var.
Birinin onayına ihtiyacınız varsa, ona bunun neden iyi bir fikir olduğunu açıklamanız gerekir.
“Daha kararlı” ya da “bakımı kolaylaşır” demek, kod tabanıyla doğrudan çalışmayan birine hitap etmez. Geliştiriciler QA yapılmadığında ortaya çıkan maliyeti, yani paranın diliyle konuşmalıdır. “Ama doğru yöntem bu!” sözü çürütülemez bir argüman gibi hissettirse de onay veren kişi bunun doğruluğuyla ilgilenmeyebilir. Bu ilke yalnızca yazılımı doğru şekilde düzeltmek için değil, iş yerindeki neredeyse her şey için geçerlidir.
Kalitenin neden önemli olduğunu açıklamak zorundaysanız, en az sizin kadar, belki de daha fazla bilgisiz durumdadırlar. Böyle organizasyonlar kaderini kabullenmelidir. Buna karşılık olgun şirketlerde daha hızlı ve daha fazla ödüllendirilir, işin nasıl yürümesi gerektiğine dair sezginizi de daha hızlı geliştirirsiniz. Elbette harcadığınız zamanın gerçek iyileştirmeye dönüştüğünü kendiniz kanıtlamalısınız; bu amatörce, Don Kişotvari bir dürtü olmamalıdır.
Kalite, kısa süre, düşük iletişim karmaşıklığı ve az para arasından kabaca yalnızca üçünü elde edebilirsiniz; burada zaman daha çok bağımlı değişkene yakındır.
İnsanlar, bir takım sporu ve mühendislik alanı olan yazılıma fabrika tipi süreçler ve yapılar uygulamaya çalışıyor. Bir basketbol takımını hücum aşamalarına göre prosedürlere ve kontrol listelerine bölerek öğretmediğiniz ya da kurmadığınız gibi, iletişimi en aza indirip takımın tek bir bütün gibi hareket etmesini sağlamalısınız. Bu, süreç kurmak değil; takım ve bireyler inşa etmektir. Plan yapılır, ama Moltke'nin dediği gibi düşmanla ilk temastan sonra kesinliğini koruyan hiçbir harekât planı yoktur. Buna rağmen iş dünyası bakış açısı, plan beklendiği gibi gitmediği için daha fazla süreç eklenmesi gerektiğine inanır ve bir sonraki başarısızlıkta yöneticinin suçu bireylere atabilmesini sağlar. Süreçlerin, işlerin hukuki ve ahlaki çerçevede gerçekleşmesini sağlamak ve test sırasında bir hedge fonun tüm parasını yanlışlıkla bahse yatırmak gibi kötü koşulları azaltmak konusunda yeri vardır. Ancak çoğu startup ve şirkette, takımı merkeze almayan bir şekilde kullanılır.
Geleneksel bir mimara “ne zaman bitecek?” diye bağırılmaz. Genellikle müşteri memnun olduğunda ya da bir karar verdiğinde biter. Pek çok geliştirme işi de buna benzer.
Kalite denen niteliği başarıyla öğreten bir insan faaliyeti olup olmadığı şüpheli.
Deneyime göre kaliteli bir şey üretme becerisi ancak pratik, pratik ve daha fazla pratikle kazanılır.
Buna karşılık başlık, programlamanın endüstriyel bir pratik olmadığı anlamına gelir. Dikkatle bakan biri için bunun aşikâr olması gerekir, ama bazıları sonuna kadar bakmayı reddeder.
Sadece yazmaya bakıldığında bile birçok insan kalitenin nasıl yükseltileceğini öğrenir. Ne yazmayı deneyeceğine rehberlik etmek ve daha önemlisi, az önce yazdığı metnin kalitesini nasıl gözden geçirip iyileştireceğine rehberlik etmek gibi.
Pratik her zaman yardımcı olur, ama kalite de pek çok kişinin öğrendiği ve ustalaştığı bir şeydir.
Uçmayı öğrenirken standartları öğrenirsiniz, ama zamanla tolerans aralıklarını daraltmanız öğretilir. Örneğin dik bir dönüşte irtifa standardı ±100 feet ise bu asgari değerdir; hedef 50 feet, 20 feet, hatta ibrenin hiç oynamayacağı bir seviyedir. Amaç “daha iyi, her zaman daha iyi; neyi daha iyi yapabilirim?”dir ve uçuşta geçmek için genel ortalama değil, tüm kalemlerde tatmin edici olmak gerekir. Kültürel olarak “tatmin edici” son değil, başlangıç noktasıdır.
Bu tutumun çok daha işbirlikçi bir model oluşturduğunu düşünüyorum. Uçuşta herkes gerçekten herkesin başarılı olmasını ister; biri başarısız olursa kendisinin de kısmen sorumluluğu vardır. Hata yapıldığında gelecekteki hata olasılığını azaltmanın yollarını bulmak gerektiği yönünde bir kültür vardı; havayollarında uçuş operasyonları kalite güvencesi (FOQA) de büyük rol oynar. Küçük, uzak bölgelerde çalışan operasyonlarda bu daha gayriresmîydi, ama çoğu “kusur aramayan” kültüre yakındı ve özünde “bunu nasıl daha iyi hâle getiririz?” sorusu vardı.
Kalite, karar verme ve “doğru olanı yapmak” havacılık kültürünün merkezindeydi. İtibarlı bir işletmecide hava güvenli şekilde uçulamayacak kadar kötüyse bu karar doğrudan operasyonun durdurulmasına yol açar; işi bitirmek için kendini zorlayıp kalkış yapılmaz. Yeni girdiğim teknoloji sektörü bunun tam tersi gibi hissettiriyor. Minimum uygulanabilir ürün kavramının kendisi sorunu gösteriyor. “Minimum uygulanabilir” değil, “başlangıç noktası olarak kabul edilebilir asgari kaliteli ürün” olmalı. Minimum hedeflenmemeli; minimum yalnızca başlangıç noktasıdır.
Sadece çöp üretme pratiği yaparsanız, çöp üretmekte ustalaşırsınız. Kaliteyi gerçekten umursamayan insanlar da var; böyle durumlarda tüm varsayımlar çöker.