Basit (kendi kendine yeten) fonksiyonlar için test yapılmasına gerek var mı?


36

Bunu düşün:

public function polynominal($a, $b, $c, $d)
{
    return  $a * pow($x, 3) + $b * pow($x, 2) + $c * $x + $d;
}

Yukarıdaki işlev için çeşitli testler yazdığınızı ve kendinize ve başkalarına "işe yaradığını" kanıtladığınızı varsayalım.

Neden bu testleri kaldırmıyor ve sonsuza dek mutlu yaşıyorsunuz? Benim düşüncem, bazı fonksiyonların işe yaradıkları kanıtlandıktan sonra sürekli test edilmelerine gerek olmadığıdır. Bunu ifade eden karşı noktaları arıyorum, evet, bu işlevlerin hala test edilmesi gerekiyor, çünkü: ... Ya da evet, bunların test edilmesi gerekmez ...


32
Kodunuzu değiştirmediğiniz sürece, dün çalıştıysa yarın da işe yarayacağı her işlev için doğru değil mi? Nokta yazılım olmasıdır edilir değişti.
5gon12eder

3
Çünkü hiç kimse override_function('pow', '$a,$b', 'return $a * $b;');doğru aklına yazmaz ... veya karmaşık sayıları ele almak için tekrar yazmaya çalışır.

8
Yani ... um ... bu "hatasız kod olduğu kanıtlandı" ... bir sorunu var .

Bunun gibi küçük fonksiyonlar için özellik tabanlı test yapmayı düşünebilirsiniz. Özellik temelli testler otomatik olarak test senaryoları ve önceden belirlenmiş değişmezler için testler oluşturur. Değişmezler aracılığıyla dokümantasyon sağlarlar ve bu da çevrede kalmalarını kolaylaştırır. Bunun gibi basit fonksiyonlar için mükemmeller.
Martijn

6
Ayrıca, bu işlev Horner'ın biçiminde bir değişiklik için (($a*$x + $b)*$x + $c)*$x + $dyanlış anlaşılması kolay, ancak genellikle çok daha hızlı olan büyük bir aday . Sırf değişmeyeceğini düşünüyorsun, olmayacak demek değil.
Michael Anderson

Yanıtlar:


78

Gerileme testi

Her şey regresyon testi ile ilgili .

Bir sonraki geliştiricinin yönteminize baktığını ve sihirli sayılar kullandığınızı fark ettiğinizi hayal edin. Büyülü sayıların kötü olduğu söylendi, bu yüzden iki sabit yarattı, biri iki numara, diğeri üç numara için - bu değişikliği yaparken yanlış bir şey yok; Zaten doğru uygulamanızı değiştirdiği gibi değildi.

Dikkatin dağıldığından iki sabiti tersine çevirir.

Kodu onaylıyor ve her şey yolunda görünüyor, çünkü her işlemden sonra çalışan herhangi bir regresyon testi yok.

Bir gün (haftalar sonra olabilir), başka bir yerde bir şeyler kırılıyor. Ve başka bir yerde, kod tabanının tamamen zıt olduğu yerde, yani polynominalişlevle ilgisi yok gibi görünüyor . Saatlerce acı veren hata ayıklama suçluya yol açıyor. Bu süre zarfında, uygulama üretimde başarısız olmaya devam eder ve müşterilerinize birçok soruna neden olur.

Yazdığınız orijinal testlerin tutulması böyle bir acıyı önleyebilir. Dikkat dağıtıcı geliştirici kodu kabul eder ve neredeyse anında bir şeyleri kırdığını görür; bu kod üretime bile ulaşmaz. Birim testleri ayrıca hatanın yeri hakkında da çok kesin olacaktır . Bunu çözmek zor olmazdı.

Yan etki...

Aslında, çoğu refactoring, büyük ölçüde regresyon testine dayanmaktadır. Küçük bir değişiklik yapın. Ölçek. Geçerse, her şey yolunda.

Yan etki, eğer testler yapmazsanız, pratik olarak herhangi bir yeniden düzenleme işleminin kodu çiğneme riski büyük olması. Bu birçok durum göz önüne alındığında, yeniden yapılanmanın yapılması gerektiğini yönetime anlatmak zaten zor , önceki yeniden yapılanma denemelerinizde birden fazla hata ortaya çıktıktan sonra bunu yapmak daha da zor olacaktır.

Eksiksiz bir test grubuyla, yeniden düzenlemeyi ve çok daha iyi, daha temiz kodları teşvik ediyorsunuz. Risksiz, düzenli olarak daha fazla refaktör için çok cazip hale gelir.

Gereksinimlerdeki değişiklikler

Diğer bir önemli özellik ise gereksinimlerin değişmesidir. Sizden karmaşık sayıları kullanmanız istenebilir ve aniden, önceki testleri bulmak, geri yüklemek ve yeni testler eklemeye başlamak için sürüm kontrol günlüğünüzü aramanız gerekir.

Neden bütün bu güçlük? Neden daha sonra eklemek için testleri kaldırmak? Onları ilk etapta tutabilirdin.


Pedantik not: hiçbir şey risksiz değildir. ;)
jpmc26

2
Regresyon benim için testlerin bir numaralı nedenidir - kodunuz sorumluluklar konusunda net olsa ve yalnızca kendisine iletilenleri kullanıyorsa (örneğin, küresel olmayanlar), bir şeyi kazara kırmak çok kolaydır. Testler mükemmel değildir, ancak yine de mükemmeller (ve hemen hemen her zaman aynı hatanın tekrar ortaya çıkmasını önler, çoğu müşterinin mutsuz olduğu bir şey). Testleriniz işe yararsa, bakım maliyeti yoktur. Çalışmayı bırakırlarsa, muhtemelen bir hata bulmuşsundur. Binlerce küresel ile eski bir uygulama üzerinde çalışıyorum - testler olmadan, gerekli değişikliklerin çoğunu yapmaya cesaret edemem.
Luaan

Başka bir bilgeli not: Bazı "sihirli" sayılar aslında sorun değil ve bunları sabitlerle değiştirmek kötü bir fikirdir.
Deduplicator

3
@Teduplicator bunu biliyoruz, ancak özellikle üniversitede yeni yetişmiş genç programcıların çoğu, mantraları takip etmekten son derece kıskanıyorlar. Ve "sihirli sayılar kötüdür" bunlardan biridir. Bir diğeri ise, aşırı durumlarda, tek bir ifadeyi içeren ancak bir tek ifadeyi içeren bir yöntem bolluğuna yol açan "bir kereden fazla kullanılan her şey bir yönteme yeniden yansıtılmalıdır" (ve daha sonra performansın neden aniden düştüğünü merak ediyorlar, çağrılar hakkında hiç bir şey öğrenmediler).
Ağustos'ta

@jwenting: MainMa "bu değişikliği yaparken yanlış bir şey yok" yazdığı için bu notu yeni ekledim.
Deduplicator

45

Çünkü hiçbir şey böcek olamayacak kadar basittir.

Kodunuz, bunun yüzünde iken hatasız görünüyor. Aslında, bir polinom fonksiyonunun basit bir programatik temsilidir.

Bir hata olması dışında ...

public function polynominal($a, $b, $c, $d)
{
    return  $a * pow($x, 3) + $b * pow($x, 2) + $c * $x + $d;
}

$xkodunuza giriş olarak tanımlanmaz ve dile veya çalışma zamanına veya kapsam belirlemeye bağlı olarak, işleviniz çalışmayabilir, geçersiz sonuçlara neden olabilir veya bir uzay gemisiyle çakışabilir .


Zeyilname:

Kod hatalarınızı şimdilik ücretsiz olarak düşünebilirsiniz, ancak bu durumun ne kadar sürdüğünü söylemek zor. Bu kadar önemsiz bir kod parçası için bir test yazmanın buna değmeyeceği söylenebilir olsa da, testi zaten yazmış olması işin yapılmasının ve silinmesinin somut bir güvenlik görevlisini silmesinin yolunu açıyor.

Ek not, bir test paketinin sağladığı kapsamın iyi bir göstergesi olan kod kapsamı hizmetleridir (coveralls.io gibi). Her kod satırını kaplayarak, yaptığınız testin miktarını (kalitesi değilse) iyi bir ölçüt verirsiniz. Nerede küçük testlerin bir sürü birlikte, en azından bu hizmetler size değil o olur bir hata aramaya.

Sonuçta, zaten yazılı bir sınavınız varsa, devam edin . Çünkü onu silmekten alan veya zamandan tasarruf, eğer bir hata meydana gelirse, muhtemelen teknik borçtan çok daha az olacaktır.


Alternatif bir çözüm var: dinamik olmayan zayıf dillere geçiş. Birim testleri genellikle yetersiz güçlü derleme zamanı doğrulaması için bir geçici çözüm vardır ve bazı diller şuna tür iyi vardır ) en.wikipedia.org/wiki/Agda_(programming_language
Den

21

Evet. Kesin olarak% 100 güvenle söyleyebilseydik: bu işlev asla düzenlenmez ve asla başarısız olmasına neden olabilecek bir bağlamda çalışmayacak - eğer söylersek, testleri düşürebilir ve her milisaniyeden bir kaç milisaniye kurtarabiliriz. CI yapı.

Ama yapamayız. Veya birçok fonksiyonla yapamayız. Tam olarak hangi güven eşiğinden memnun olduğumuzu ve verilen herhangi bir işlevin değişmezliğine ve yanılmazlığına ne kadar güven duyduğumuzu belirlemeye çalışmaktan ziyade, tüm testleri her zaman çalıştırma kuralına sahip olmak daha kolaydır.

Ve işlem süresi ucuzdur. Birçok kez çoğaltılmış olsa bile, kaydedilen bu milisaniye, sormak için her fonksiyonla zaman ayırmayı haklı kılmak için neredeyse hiç bir şey katmıyor: bir daha asla test etmemize gerek duyduğumuza güveniyor muyuz?


Bence buraya getirdiğin çok iyi bir nokta. İki erkeğin birkaç küçük işlevsellik için testler yapmayı savunarak saatlerini harcadığını görebiliyorum .
Kapol

@Kapol: bir tartışma değil, hangisinin gidebileceğini ve hangilerinin kalacağını ve hangi kriterlere karar verilmesi gerektiğine, kriterleri nerede belgeleyeceğine ve son kararı kimin imzaladığına karar vermek için kullanılacak bir toplantı değil ...
jmoreno

12

Diğer cevaplarda söylenen her şey doğru, ama bir tane daha ekleyeceğim.

belgeleme

Birim testler, iyi yazılmışsa, geliştiriciye bir işlevin tam olarak ne yaptığını, girdi / çıktı beklentilerinin ne olduğunu ve daha da önemlisi hangi davranıştan beklenebileceğini açıklayabilir.

Bir hatanın tespit edilmesini kolaylaştırabilir ve karışıklığı azaltabilir.

Herkes polinomları, geometriyi ve hatta cebiri hatırlamıyor :) Ama sürüm kontrolünde yapılan iyi bir birim testi benim için hatırlayacaktır.

Dokümantasyon olarak ne kadar yararlı olabileceğinin bir örneği için Yasemin girişine bakın: http://jasmine.github.io/edge/introduction.html Yüklemek için birkaç saniye bekleyin , sonra altına kaydırın. Tüm Yasemin API'sini birim test çıktısı olarak belgelendiğini göreceksiniz.

[@Warbo'nun geri bildirimlerine dayanarak güncelleme] Testlerin güncel olmaları garanti edilir, çünkü yapılmazlarsa, başarısız olurlar, bu genellikle CI kullanılırsa bir derleme hatasına neden olur. Harici dokümantasyon koddan bağımsız olarak değişir ve bu nedenle mutlaka güncel değildir.


1
Testleri (bir bölümünün) gizli bırakmış olduğunuz belgeler olarak kullanmanın büyük bir avantajı vardır: otomatik olarak kontrol edilirler. Diğer dokümantasyon türleri, örneğin. Bir Web sayfasındaki açıklayıcı yorumlar veya kod parçacıkları, kod geliştikçe eski hale gelebilir. Ünite testleri, artık doğru olmazlarsa bir arızayı tetikler. Bu yasemin sayfası buna aşırı bir örnek.
Warbo

D ve Rust gibi bazı dillerin dokümantasyon nesillerini birim testleriyle birleştirdiğini, böylece aynı kod parçasını hem birim testinde derleyip hem de HTML belgelerine eklenebildiğini eklemek
isterim

2

Gerçeklik kontrolü

Bütçeleme ve programlama sırasında testin "zaman kaybı" ve ardından müşteri hatalarla uğraşırken "kalite güvencesinin temel bir parçası" olduğu zorlu ortamlarda bulundum, bu yüzden fikrim diğerlerinden daha akıcı.

Bütçen var. İşiniz, bu bütçeyle elde edebileceğiniz en iyi ürünü elde etmek, hangi “en iyi” tanımı ne olursa olsun birlikte kazıyın (tanımlaması kolay bir kelime değil). Hikayenin sonu.

Test, envanterinizde bir araçtır. Kullanmalısınız, çünkü uzun bir milyonlarca tasarruf geçmişinde, hatta belki de milyarlarca dolara sahip iyi bir araçtır . Eğer bir şans verilirse, bu basit fonksiyonlara testler eklemelisiniz. Bir gün cildinizi kurtarabilir.

Ancak gerçek dünyada, bütçe ve zamanlama kısıtlamaları ile, bu gerçekleşmeyebilir. Kendinizi işlem için bir köle yapmayın. Test fonksiyonları gayet güzel, ancak bir noktada, çalışma saatleriniz kod geliştiriciden daha ziyade kod yazarak dökümantasyon dökümanları yazmakla daha iyi harcanabilir. Ya da kod tabanını yeniden gözden geçirerek daha iyi harcanması daha iyi olabilir, bu yüzden bir canavarı zorlamak zorunda kalmazsınız. Veya belki de o zaman patronunuzla bütçe ve program hakkında konuşmak için daha iyi harcanır, böylece bir sonraki finansman turu boruya indiğinde ne için teklif verdiklerini daha iyi anlar.

Yazılım geliştirme bir dengedir. Vaktinizi harcamanın daha iyi bir yolu olmadığından emin olmak için, yaptığınız her şeyin fırsat maliyetini daima hesaba katın.


4
Bu durumda, zaten bir sınama vardı, bu yüzden soru onları yazıp yazmamak değil, tüm kurguları veya sürümleri uygulamak veya bunları yapmak ya da çalıştırmak ya da tüm testleri yapmak için ne gibi bir program varsa bunları yapmak.
Paŭlo Ebermann

0

Evet, testleri sürdür, çalıştırmaya devam et ve devam et.

Birim testleri sizi (ve diğerlerini) kendinizden (ve kendilerinden) korumak için vardır.

Testler neden iyi bir fikirdir?

  • Yeni gereksinimler ve ek işlevler karşısında önceki gereksinimlerin işlevselliğini doğrulayın
  • Yeniden düzenleme alıştırmalarının doğru olduğunu onaylayın
  • Dahili dokümantasyon - kodun kullanılması bekleniyor mu?
  • Regresyon testi, işler değişiyor
    • Değişiklikler eski kodu bozuyor mu?
    • Değişiklikler mevcut işlevler veya kod için daha fazla değişiklik isteği veya güncellemesi gerektiriyor mu?
  • Testlerin zaten yazılmış olduğu göz önünde bulundurulursa; bakım maliyetlerini daha da azaltacak, hali hazırda harcanan zaman ve paradır

2
Bu, verilen diğer cevaplar üzerinde önemli bir şey sunmuyor gibi görünüyor.

1
Daha önce gönderirken bir sorun oluştu, ancak geçmişe bakıldığında, bu güzel bir özetidir. Onu kaldıracağım.
Niall

-1

Geliştirici Belgeleri

  • (Başka bir geliştirici olarak) bunun test edildiğini nasıl bilebilirim?
  • Ben bir hata düzeltmek istiyorsanız müstakil fonksiyonu, nasıl ben zaten kabul ettiğini bir hata tanıtan değilim biliyoruz?
  • Karmaşıklık göstergesi: Test sayısı, bir şeyin ne kadar karmaşık olduğu konusunda iyi bir ölçü olabilir. Bu, dokunmamanız gerektiğini, olgun ve stabil olması veya şişirilmesi ve bağlanması gerektiğini gösterebilir.

Kullanıcı Belgeleri

  • Zayıf dokümanda, {sıfır, negatif değerler, boş kümeler, vb. Kabul edilip edilmediğini ve beklenen geri dönüş değerinin ne olduğunu görebilir ve görebilirim.
  • Ayrıca, nesneyi / işlevi nasıl kullanmam gerektiğine dair iyi bir örnek verir.

1
Bu, önceki cevaplarda verilen ve açıklanan önemli noktalar üzerinde önemli bir şey sunmuyor gibi görünüyor. "Güzel Özeti" bile zaten gönderildi (benim zevkime göre o kadar güzel değil ama oh iyi)
gnat
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.