Sahte nesneler kullanırken birim testleriyle ilgili bağımlılık sorunlarını nasıl tespit edersiniz?


98

X sınıfınız var ve X1 davranışını doğrulayan bazı birim testleri yazıyorsunuz. X'i bir bağımlılık olarak alan A sınıfı da var.

A için birim testleri yazdığınızda, X ile alay edersiniz. Başka bir deyişle, A birim testi sırasında, X'in alay davranışını X1 olarak ayarlarsınız (varsayılır). Zaman geçiyor, insanlar sisteminizi kullanıyor, değişmesi gerekiyor, X gelişti: X2 davranışını göstermek için X'i değiştirdiniz. Açıkçası, X için birim testleri başarısız olacak ve bunları uyarlamanız gerekecek.

Peki ya A? A'nın birim testleri, X'in davranışı değiştirildiğinde (X'in alayından dolayı) başarısız olmaz. A'nın sonucunun "real" (modifiye) X ile çalıştırıldığında farklı olacağını nasıl tespit edebilirim?

"Bu, ünite testinin amacı değil" hattı boyunca cevaplar bekliyorum, fakat ünite testinin değeri nedir? Gerçekten, sadece tüm testler geçtiğinde, hiçbir değişiklik getirmediğinizi söylüyor mu? Ve bazı sınıfların davranışları değiştiğinde (isteyerek veya istemeyerek), tüm sonuçları (tercihen otomatik olarak) nasıl tespit edebilirsiniz? Entegrasyon testine daha fazla odaklanmamalı mıyız?



36
Önerilen tüm cevaplar yanı sıra, ben şu sözlerine karşı almak söylemeliyim: 'Gerçekten mi sadece tüm testler geçtiğinde, bir kırılma değişiklik teşkil etmediğinden söyleyen oldu mu?' Yeniden
canlandırma

5
Ünite testi size kod ünitenizin beklediğiniz gibi davranıp davranmadığını bildirir. Az ya da çok değil. Alaylar ve test çiftleri, beklentilerinizi karşılayıp karşılamadığını görmek için kod biriminizi (izolasyonlu olarak) kullanmanız için yapay ve kontrollü bir ortam sağlar. Az ya da çok değil.
Robert Harvey,

2
Ben senin öncülünün yanlış olduğuna inanıyorum. Sizden bahsettiğinizde X1bunun Xarayüzü uyguladıklarını söylüyorsunuz X1. Eğer arayüz değiştirirseniz X1için X2artık derlemek olmamalıdır diğer testlerde kullanılan mock, dolayısıyla siz de bu testler düzeltmek zorunda kalıyor. Sınıf davranışındaki değişiklikler önemli olmamalıdır. Aslında, sınıfınız Auygulama ayrıntılarına (bu durumda neyi değiştireceğinize) bağlı olmamalıdır. Bu nedenle, birim testleri Ahala doğru ve size Aarayüzün ideal bir uygulaması verilen çalışmaların olduğunu söylüyorlar .
Bakuriu

5
Seni bilmiyorum, ama testsiz bir kod temeli üzerinde çalışmak zorunda kaldığımda, ölümden korkuyorum, bir şeyleri kıracağım. Ve neden? Çünkü o kadar sık ​​olur ki bir şey amaçlanmadığında kırılır. Test cihazımızın kalbini korusun, her şeyi test edemezler. Hatta yakın. Ancak bir ünite testi, sıkıcı rutinin ardından sıkıcı rutinlerden kolayca uzaklaşacaktır.
corsiKa

Yanıtlar:


125

A için birim testleri yazdığınızda, X ile alay edersiniz

Yapıyor musun? Zorunda olmadığım sürece yapmam. Yapmam gereken:

  1. X yavaş
  2. X yan etkileri var

Bunlardan hiçbiri geçerli değilse, benim birim testlerim Ade test edecektir X. Başka bir şey yapmak, mantıksız bir uç noktaya tecrit testleri yapmak olacaktır.

Kodunuzun diğer bölümlerinin alaylarını kullanarak kodunuzun bölümlerini kullanıyorsanız, o zaman kabul ediyorum: bu tür birim testlerinin amacı nedir? Yani bunu yapma. Bu testler, bu şekilde çok daha değerli testler oluştururken gerçek bağımlılıkları kullanmasına izin verin.

Ve eğer bazı insanlar size bu testleri, "birim testleri" diyorlarsa, sinirlenirlerse, o zaman onları "otomatik testler" olarak adlandırın ve iyi otomatikleştirilmiş testler yazmaya devam edin.


94
@Laiv, No, birim testlerinin bir birim gibi davranması gerekiyor, yani diğer testlerden izole edilmiş şekilde çalışıyor . Düğümler ve grafikler zam alabilir. İzole, yandan etkisiz, uçtan uca bir testi kısa sürede yapabilirsem, bu bir birim testidir. Bu tanımlamayı sevmiyorsanız, otomatik bir test olarak adlandırın ve saçma anlambilim için uygun saçma testler yazmayı bırakın.
David Arno

9
@DavidArno Ne yazık ki, çok geniş bir izole edilmiş tanımı vardır. Bazıları orta seviye ve veri tabanını dahil etmek için bir "birim" ister. İstedikleri her şeye inanabilirler, ancak ihtimaller her boyutta bir gelişimde, yapım müdürünün fırlatıp atmasıyla jantların oldukça kısa bir sürede patlayacağıdır. Genellikle, düzeneğe izole edilmişlerse (veya eşdeğeri), bu iyi. Eğer arayüzleri kodlarsanız NB daha sonra alaycı ve DI'yi eklemek çok daha kolaydır.
Robbie Dee

13
Soruyu cevaplamak yerine farklı bir test türünü savunuyorsunuz. Bu geçerli bir nokta ama bu yapmanın oldukça temel bir yolu.
Phil Frost

17
@PhilFrost, kendime alıntı yapmak için: " Ve eğer bazı insanlar bu testleri," birim sınamalarını "çağırarak sizi rahatsız ederlerse, o zaman onları sadece" otomatik sınamalar "olarak adlandırın ve iyi sınamalar yazarak devam edin. " Aptalca sınamalar değil Bu sadece bir kelimenin rastgele tanımını karşılar. Ya da alternatif olarak, "birim testi" tanımınızın yanlış olduğunu ve sahte kullandığınızdan dolayı fazla kullandığınızı kabul edin. Her iki durumda da, daha iyi testlerle sonuçlanacaksınız.
David Arno

30
Bu konuda @DavidArno ile yaşıyorum; Test stratejim bu konuşmayı Ian Cooper: vimeo.com/68375232 izledikten sonra değişti . Tek bir cümleyle kaynatmak için: Sınıfları sınama . Deney davranışları . Testleriniz, istenen davranışı uygulamak için kullanılan iç sınıflar / yöntemler hakkında bilgi sahibi olmamalıdır; yalnızca API / kütüphanenizin genel yüzeyini bilmeli ve bunu test etmelidir. Testler çok fazla bilgiye sahipse, uygulama ayrıntılarını test edersiniz ve testleriniz kırılgan hale gelir, uygulamanıza eşlik eder ve aslında sadece boynunuzdaki bir çapa.
Richiban

79

İkisine de ihtiyacın var. Birimlerinizin her birinin davranışını doğrulamak için birim testleri ve doğru şekilde bağlandığından emin olmak için birkaç entegrasyon testi. Yalnızca entegrasyon testine güvenmenin sorunu, tüm birimleriniz arasındaki etkileşimlerden kaynaklanan birleşik patlamadır.

Diyelim ki A sınıfı var, tüm yolları tamamen kapamak için 10 ünite testi gerekiyor. Daha sonra, başka bir B sınıfınız var, bu da kodun üstesinden gelebileceği tüm yolları kapsayan 10 birim testi gerektiriyor. Şimdi uygulamanızda, A'nın çıktısını B'ye beslemeniz gerektiğini söyleyelim. Artık kodunuz A'nın girişinden B'nin çıkışına kadar 100 farklı yol izleyebilir

Ünite testlerinde, tüm durumları tamamen kapsayan 20 ünite testi + 1 entegrasyon testine ihtiyacınız var.

Entegrasyon testleriyle, tüm kod yollarını kapsayacak 100 teste ihtiyacınız olacak.

İşte entegrasyon testlerine güvenmenin olumsuz yönleri hakkında çok güzel bir video sadece JB Rainsberger Entegre Testler Are A Scam HD


1
Entegrasyon testlerinin etkinliği konusundaki soru işaretinin her katmanı kapsayan birim testleriyle el ele gitmesi tesadüf değildir.
Robbie Dee

16
Doğru, ama hiçbir yerde 20 birim testin alay gerektirmez. A'nın tümünü kapsayan 10 A testiniz varsa ve B'nin tümünü kapsayan 10 testiniz varsa ve A'nın% 25'ini bonus olarak tekrar test ederseniz, bu "iyi" ile iyi bir şey arasında görünür. Bs testlerinde A ile alay etmek aktif olarak aptalca görünüyor (A probleminin gerçek olmasının bir nedeni olmadıkça, örneğin veri tabanı veya başka şeylerin uzun bir ağını getiriyor)
Richard Tingle

9
Tam kapsama istiyorsanız, tek bir entegrasyon testinin yeterli olduğu fikrine katılmıyorum. B'nin A çıkışına olan tepkileri, çıktıya bağlı olarak değişecektir; A'daki bir parametrenin değiştirilmesi çıktısını değiştirirse, B doğru şekilde işlemeyebilir.
Matthieu M.

3
@ Ebedi21: Amacım bazen sorunun bireysel davranışta değil, beklenmedik bir etkileşimde olmasıydı. Yani, A ve B arasındaki yapıştırıcı bazı senaryolarda beklenmedik şekilde davrandığında. Böylece hem A hem de B spesifikasyonlara göre hareket eder ve mutlu durum çalışır, ancak bazı girdilerde yapıştırıcı kodunda bir hata vardır ...
Matthieu M.

1
@MatthieuM. Bunun Birim Testinin kapsamı dışında olduğunu iddia ediyorum. Yapıştırıcı kodu, A ve B arasındaki yapıştırıcı kodu ile yapılan etkileşimler bir Entegrasyon Testi iken, ünite test edilebilir. Belirli uç durumlar veya hatalar bulunduğunda, bunlar yapıştırıcı kod birimi testlerine eklenebilir ve sonuçta Entegrasyon testinde doğrulanabilir.
Andrew T Finnell

72

A için birim testleri yazdığınızda, X ile alay edersiniz. Başka bir deyişle, A birim testi sırasında, X'in alay davranışını X1 olarak ayarlarsınız (varsayılır). Zaman geçiyor, insanlar sisteminizi kullanıyor, değişmesi gerekiyor, X gelişti: X2 davranışını göstermek için X'i değiştirdiniz. Açıkçası, X için birim testleri başarısız olacak ve bunları uyarlamanız gerekecek.

Woah, biraz bekle. X'in başarısız olmasının testlerinin sonuçları bunun üzerine parlamak için çok önemlidir.

X'in uygulanmasının X1'den X2'ye değiştirilmesi, X için birim testlerini ihlal ederse, bu, X sözleşmesinde geriye dönük olarak uyumsuz bir değişiklik yaptığınızı gösterir.

X2, Liskov anlamında bir X değildir ; bu nedenle , paydaşlarınızın ihtiyaçlarını karşılamanın başka yollarını düşünmelisiniz (yeni bir Y belirtimi, X2 tarafından uygulanan).

Daha derin görüşler için, bkz. Pieter Hinjens: Yazılımın Sonu Sürümlerinin Sonu veya Rich Hickey Simple Made Easy .

A'nın perspektifinden bakıldığında , işbirlikçinin X sözleşmesine saygı duyması için bir önkoşul vardır. Ve gözleminiz, A için izole edilen testin size, X sözleşmesini ihlal eden ortak çalışanları tanıdığına dair hiçbir güvence vermemesidir.

Entegre Testleri gözden geçirin bir aldatmacadır ; yüksek düzeyde, X2'nin X sözleşmesini doğru bir şekilde uyguladığından emin olmak için ihtiyaç duyduğunuz sayıda izole edilmiş sınava girmeniz ve A'nın X'ten ilginç yanıtlar verilen doğru şeyi yapmasını sağlamak için gereken kadar izole edilmiş sınava girmeniz beklenir. X2 ve A'nın X'in ne anlama geldiğine karar vermesini sağlamak için daha az sayıda entegre test.

Bazen testlere karşı yalnız testler olarak ifade edilen bu ayrımı göreceksiniz sociable; Jay Sahaları Birim Testleriyle Etkili Çalışıyor .

Entegrasyon testine daha fazla odaklanmamalı mıyız?

Yine, entegre testlerin bir aldatmaca olduğunu görün - Rainsberger, ayrıntılı olarak (deneyimlerinde) entegre (not yazım) testlerine dayanan projeler için ortak olan olumlu bir geri besleme döngüsü açıklar. Özetle, tasarıma baskı uygulayan izole / tek başına testler olmadan, kalite düşer, daha fazla hataya ve daha entegre testlere yol açar.

Ayrıca (bazı) entegrasyon testlerine ihtiyacınız olacaktır. Birden fazla modül tarafından ortaya konan karmaşıklığa ek olarak, bu testlerin yapılması izole edilmiş testlerden daha fazla sürükleme eğilimindedir; Çalışmalar sürerken çok hızlı kontrollerde yineleme yapmak daha verimlidir ve "yapıldığını" düşündüğünüzde yapılan ek kontrolleri kaydeder.


8
Bu kabul edilen cevap olmalı. Soru, bir sınıfın davranışının uyumsuz bir şekilde değiştirildiği, ancak yine de dışarıdan aynı göründüğü bir durumu ortaya koyuyor. Buradaki sorun, birim testlerinde değil uygulamanın tasarımında yatmaktadır. Bu koşulun testte yakalanmasının yolu, bu iki sınıf arasında bir entegrasyon testi kullanmaktır.
Nick Coad

1
"tasarıma baskı uygulayan izole / tek başına yapılan testler olmadan kalite düşer". Bunun önemli bir nokta olduğunu düşünüyorum. Davranış kontrollerinin yanı sıra, birim testleri sizi daha modüler bir tasarıma zorlamak için yan etkiye sahiptir.
MickaëlG

Sanırım bunların hepsi doğru, ancak dışsal bir bağımlılık X sözleşmesinde geriye dönük bir uyumsuz değişiklik getirdiğinde bu bana nasıl yardımcı olur? Belki de bir kütüphanede bir G / Ç performansı gösteren sınıf uyumluluğu bozar ve X ile dalga geçiyoruz çünkü CI'de birim testlerinin ağır G / Ç'ye bağlı olmasını istemiyoruz. Bence OP bunun için test yapmak istiyor ve bunun soruyu nasıl cevapladığını anlamıyorum. Bunun için nasıl test edilir?
gerrit

15

Sorunun temel öncülünün hatalı olduğunu söyleyerek başlayayım.

Uygulamaları asla test etmiyorsunuz (veya alay ediyorsunuz), arayüzleri test ediyorsunuz (ve alay ediyorsunuz) .

X1 arabirimini uygulayan gerçek bir X sınıfım varsa, X1 ile de uyumlu bir sahte XM yazabilirim. Öyleyse A sınıfı, X1'i uygulayan, X sınıfı veya sahte XM olabilen bir şey kullanmalıdır.

Şimdi, X2'yi yeni bir arayüz X2 uygulamak için değiştirdiğimizi varsayalım. Belli ki kodum artık derlenmiyor. A, X1'i uygulayan ve artık bulunmayan bir şeyi gerektirir. Sorun tespit edildi ve çözülebilir.

X1'i değiştirmek yerine, sadece değiştirdiğimizi varsayalım. Şimdi A sınıfı tamamen ayarlandı. Bununla birlikte, sahte XM artık X1 arayüzünü uygulamamaktadır. Sorun tespit edildi ve çözülebilir.


Ünite testi ve alaycılığının temelini, arayüzleri kullanan kod yazmanızdır. Bir arabirimin tüketicisi , kodun nasıl uygulandığını önemsemez , yalnızca aynı sözleşmeye (girdi / çıktılar) uyulduğunu önemser .

Yöntemlerinizin yan etkileri olduğunda bu bozuluyor, ancak bence "ünite test edilemez veya alay edilemez" olarak hariç tutulabilir.


11
Bu cevap, tutulması gerekmeyen birçok varsayımda bulunur. İlk olarak, kabaca, C # veya Java'da olduğumuzu (veya daha kesin olarak, derlenmiş bir dilde olduğumuzu, dilin arayüzleri olduğunu ve X'in bir arayüz uyguladığı; bunların hiçbirinin doğru olması gerekmediğini) varsayar. İkincisi, X'in davranışındaki veya "sözleşmesindeki" herhangi bir değişikliğin , X'in uyguladığı arayüzde (derleyici tarafından anlaşıldığı şekilde) bir değişiklik gerektirdiğini varsayar . Bu açıkça bir değil biz dahi geçerlidir olan Java veya C #; İmzasını değiştirmeden bir yöntem uygulamasını değiştirebilirsiniz.
Mark Amery

6
@MarkAmery "Arayüz" terminolojisinin C # veya Java'ya özgü olduğu doğrudur, ancak bence mesele tanımlanmış bir "davranış sözleşmesi" davranışı olarak kabul edilir (ve eğer kodlanmamışsa bunu otomatik olarak tespit etmek imkansızdır). Ayrıca bir uygulamanın sözleşmede değişiklik yapılmadan değiştirilebileceği konusunda tamamen haklısınız. Ancak, arayüzde (veya sözleşmede) bir değişiklik olmadan uygulamada yapılan değişiklik, herhangi bir tüketiciyi etkilememelidir. A'nın davranışı, arayüzün (veya sözleşmenin) nasıl uygulandığına bağlıysa, birim testini (anlamlı şekilde) yapmak imkansızdır.
Vlad274

1
“Bir uygulamanın sözleşmede değişiklik yapılmadan değiştirilebileceği konusunda da tamamen haklısın” - doğru olsa da, yapmaya çalıştığım nokta bu değildi. Aksine, sözleşme (bir programcının bir nesnenin ne yapması gerektiğini, belki de belgelerde belirtilmesi gerektiğini anlaması) ile arayüz (derleyici tarafından anlaşılan bir yöntem imzası listesi) ve sözleşmenin yapabileceğini söylemek arasında bir ayrım yapıyorum. arayüzü değiştirmeden değiştirilebilir. Aynı imzaya sahip tüm fonksiyonlar, tip sisteminin perspektifinden değiştirilebilir, ancak gerçekte değil!
Mark Amery

4
@MarkAmery: Vlad'ın "arayüz" kelimesini kullandığınız gibi kullandığını sanmıyorum; Cevabı okuduğum gibi, dar C # / Java anlamındaki (yani bir dizi yöntem imzası) arayüzden değil, örneğin "uygulama programlama arayüzü" veya hatta "terimlerinde kullanıldığı gibi kelimenin genel anlamından bahsediyor. Kullanıcı arayüzü". [...]
Ilmari Karonen

6
@IlmariKaronen Vlad, dar C # / Java anlamında değil de "sözleşme" demek için "arayüz" kullanıyorsa, "Şimdi" ifadesini kullanarak, X2'yi yeni bir arayüz X2 uygulamak üzere değiştirdiğimizi varsayalım. Açıkçası, kodum artık derlenmiyor. " Herhangi bir yöntem imzasını değiştirmeden bir sözleşmeyi değiştirebileceğinizden, yalnızca düz bir yanlıştır. Ama dürüst olmak gerekirse, ben burada sorun Vlad kullanarak ya sürekli anlam, ancak olmadığını düşünüyorum conflating X1 sözleşme herhangi bir değişiklik mutlaka olmadan derleme hatasına neden olacağını iddia yolunu inen budur - onları fark o yanlış olduğunu .
Mark Amery

9

Sorularınızı sırayla almak:

birim testinin değeri nedir?

Yazmaları ve çalıştırmaları ucuzdur ve erken geribildirim alırsınız. X'i kırarsanız, iyi testleriniz varsa hemen ya da hemen öğreneceksiniz. Tüm katmanlarınızı test etmediğiniz sürece entegrasyon testleri yazmayı düşünmeyin (evet, hatta veritabanında bile).

Gerçekten, size sadece tüm testler geçtiğinde, önemli bir değişiklik getirmediğinizi söylüyor mu?

Bu testlerden geçmek size gerçekten çok az şey söyleyebilir. Yeterince test yazmamış olabilirsiniz. Yeterli senaryo test etmemiş olabilirsiniz. Kod kapsamı burada yardımcı olabilir, ancak gümüş bir kurşun değildir. Her zaman başarılı olan testlere sahip olabilirsin . Bu nedenle, kırmızı, yeşil, refactorun ilk basamağı gözden kaçan kırmızıdır.

Ve bazı sınıfların davranışları değiştiğinde (isteyerek veya istemeyerek), tüm sonuçları nasıl (tercihen otomatik olarak) saptayabilirsin

Daha fazla test - aletler daha iyi ve daha iyi hale gelse de. Ancak bir arayüzde sınıf davranışını tanımlamalısınız (aşağıya bakınız). Not: Test piramidinin üstünde manuel test yapmak için her zaman bir yer bulunacaktır.

Entegrasyon testine daha fazla odaklanmamalı mıyız?

Her zamankinden daha fazla entegrasyon testi ya cevap değildir, yazması, çalıştırılması ve bakımı pahalıdır. Yapı kurulumunuza bağlı olarak, yapı yöneticiniz bir geliştiricinin hatırlamalarına bağlı kalmasına rağmen bunları asla hariç tutabilir (asla iyi bir şey değil!).

Geliştiricilerin, eğer iyi bir birim testi yaptırırlarsa beş dakika içinde buldukları kırık entegrasyon testlerini düzeltmek için saatler harcadıklarını gördüm. Bunu başaramazsanız, sadece yazılımı çalıştırmayı deneyin - tüm son kullanıcılarınızın umursadığı şey bu. Kullanıcı tüm paketi çalıştırdığında tüm kartlar düşerse geçecek milyon birim testine gerek yoktur.

A sınıfı X'in aynı şekilde tüketildiğinden emin olmak istiyorsanız, bir betonlama yerine bir arayüz kullanıyor olmalısınız. Öyleyse, derleme zamanında bir kırılma değişikliğinin yakalanması daha olasıdır.


9

Bu doğru.

Birim testleri, bir birimin yalıtılmış işlevselliğini test etmek için yapılmıştır; ilk bakışta, amaçlandığı şekilde çalıştığını ve aptalca hatalar içermediğini kontrol edin.

Tüm uygulamaların çalıştığını test etmek için birim testleri yoktur.

Bir çok insanın unuttuğu şey, birim testlerinin, kodunuzu doğrulamanın en hızlı ve en kirli yoludur. Küçük rutinlerinizin işe yaradığını öğrendikten sonra, Entegrasyon testlerini de yapmalısınız. Ünite testi tek başına, test yapılmamasından yalnızca marjinal olarak daha iyidir.

Birim testler yapmamızın nedeni, ucuz olmalarıydı. Oluşturma, çalıştırma ve bakımını yapmak hızlı. Onları min entegrasyon testlerine dönüştürmeye başladığınızda, acı dolu bir dünya haline geliyorsunuz. Tam Entegrasyon testine girebilir ve bunu yapacaksanız ünite testini tamamen göz ardı edebilirsiniz.

Şimdi, bazı insanlar bir birimin sadece bir sınıftaki bir işlev değil, tüm sınıfın kendisinin (kendim dahil) olduğunu düşünüyor. Ancak, tüm bunlar ünitenin boyutunu arttırmaktır, böylece daha az entegrasyon testine ihtiyacınız olabilir, ancak yine de ihtiyacınız vardır. Programınızın tam entegrasyon test paketi olmadan yapması gerekeni yaptığını doğrulamak hala imkansızdır.

ve daha sonra, tam entegrasyon testini müşterinin kullandığı koşullarla çalıştığını kontrol etmek için canlı (veya yarı-canlı) bir sistemde uygulamanız gerekir.


2

Ünite testleri hiçbir şeyin doğruluğunu kanıtlamaz. Bu tüm testler için geçerlidir. Genellikle birim testleri, sözleşmeye dayalı tasarımla (sözleşmeye göre tasarım bunu söylemenin başka bir yoludur) ve doğruluğun düzenli olarak doğrulanması gerekiyorsa muhtemelen otomatikleştirilmiş doğruluk kanıtlarıyla birleştirilir.

Sınıf değişmezlerinden, önkoşullardan ve post koşullardan oluşan gerçek sözleşmeleriniz varsa, daha düşük seviyeli bileşenlerin sözleşmelerine yüksek seviye bileşenlerin doğruluğunu temel alarak hiyerarşik olarak doğruluk kanıtlamak mümkündür. Bu sözleşme ile tasarımın arkasındaki temel kavramdır.


Ünite testleri hiçbir şeyin doğruluğunu kanıtlamaz . Bunu anladığımdan emin değilim, birim testleri mutlaka kendi sonuçlarını kontrol eder? Yoksa bir davranışın doğru olamayacağını mı demek istediniz, çünkü bu çoklu katmanları kapsayabilir?
Robbie Dee

7
Sanırım @RobbieDee, senin için test ettiğinizde anlamına geliyordu fac(5) == 120, sen sahip değil kanıtlanmış fac()gerçekten onun argüman faktöriyelini çıkmıyor. İçeri fac()girdiğinde sadece beşin faktörünü veren kanıtladın 5. Ve bu kesin olmasa da, Timbuktu'daki toplam güneş tutmanın ardından ilk pazartesi günleri yerine fac()makul bir şekilde geri dönebildiğinden 42... Buradaki sorun, bireysel test girişlerini kontrol ederek uygunluğu kanıtlayamamanız, olası tüm girişleri kontrol etmeniz gerekir. ve ayrıca herhangi bir şeyi unutmadığınızı kanıtlayın (sistem saatini okumak gibi).
cmaster

1
@RobbieDee Testleri (ünite testleri dahil), makine kontrolü kanıtlanmış gerçek bir amaç için genellikle en iyisi olan kötü bir alternatiftir. Buradaki herhangi bir bileşen veya alayların durum alanı da dahil olmak üzere, test edilen birimlerin tüm durum alanını göz önünde bulundurun. Çok sınırlı bir durum alanınız olmadığı sürece, testler bu durum alanını kapsayamaz. Tam kapsama bir kanıt olabilir, ancak bu yalnızca küçük durumlu alanlar için kullanılabilir; örneğin, tek bir değiştirilebilir bayt veya 16 bit tam sayı içeren tek bir nesneyi test etme. Otomatik provalar çok daha değerlidir.
Frank Hileman

1
@cmaster Bir test ile bir kanıt arasındaki farkı çok iyi özetlediniz. Teşekkürler!
Frank Hileman

2

Çok alay konusu testleri nadiren faydalı buluyorum. Çoğu zaman, orijinal sınıfın zaten sahip olduğu, alay etme amacını tamamen yenen davranışları yeniden uygularım.

Bana göre daha iyi bir strateji, kaygılarınızı iyi bir şekilde ayırmaktır (örneğin, uygulamanızın A bölümünü, B'den Z'ye getirmeden test edebilirsiniz). Böyle iyi bir mimari gerçekten iyi bir test yazmak için yardımcı olur.

Ayrıca, onları geri alabildiğim sürece yan etkileri kabul etmeye daha fazla istekliyim, örneğin, eğer yöntemim db'deki verileri değiştirirse, izin verin! Db'yi önceki durumuna getirebildiğim sürece, zararı nedir? Ayrıca, testimin verilerin beklendiği gibi görünüp görünmediğini kontrol edebilmesi avantajı vardır. Bellek içi DB'ler veya belirli dbs test sürümleri burada gerçekten yardımcı olur (örn. RavenDB bellek içi test sürümü).

Son olarak, hizmet sınırlarıyla alay etmeyi severim, örneğin, http servis b'yi yapmayın, ancak bunu durduralım ve onaylayalım.


1

Her iki kamptaki kişilerin de sınıf testi ve davranış testinin dikey olmadığını anlamalarını diliyorum.

Sınıf testi ve birim testi birbirinin yerine kullanılır ve belki de yapılmaması gerekir. Bazı ünite testleri sadece sınıflarda uygulanmaktadır. Hepsi bu. Ünite testi, yıllarca derssiz dillerde yapıldı.

Davranışları test etme gelince, bunu GWT yapısını kullanarak sınıf testi içinde yapmak mükemmel bir şekilde mümkün.

Ayrıca, otomatikleştirilmiş testlerinizin sınıf boyunca mı yoksa davranış çizgileri boyunca mı ilerleyeceği önceliklerinize bağlıdır. Bazılarının hızlı bir şekilde prototip yapması ve kapıdan bir şey çıkarması gerekirken, bazılarının da ev stillerinden dolayı kapsama alanı kısıtlamaları olacaktır. Birçok sebep var. Her ikisi de mükemmel geçerli yaklaşımlar. Paranı ödüyorsun, seçimini yapıyorsun.

Peki, kod kırıldığında ne yapmalı. Eğer bir arayüze kodlanmışsa, sadece betonun değişmesi gerekir (herhangi bir test ile birlikte).

Bununla birlikte, yeni bir davranış getirilmesi, sistemi tehlikeye atmak zorunda değildir. Linux ve diğerleri kullanım dışı özelliklerle doludur. Ayrıca, yapıcılar (ve yöntemler) gibi şeyler, tüm arama kodlarını değiştirmeye zorlamadan mutlu bir şekilde aşırı yüklenebilir.

Sınıf testlerinin kazandığı yer, henüz henüz suya daldırılmayan bir sınıfta değişiklik yapmanız gereken yerdir (zaman kısıtlamaları, karmaşıklık veya her neyse). Kapsamlı testler varsa bir sınıfa başlamak çok daha kolaydır.


Sahip Nerede concretion yazdım olurdu uygulanmasını . Bu, başka bir dilden (Fransızca sanırım) bir mihrap mı yoksa somutlaştırma ve uygulama arasında önemli bir ayrım var mı?
Peter Taylor

0

X'in arayüzü değişmediği sürece, A ile ilgili hiçbir şey değişmediğinden, A için birim testini değiştirmeniz gerekmez. Gerçekten birlikte X ve A ünite testi yazmış gibi görünüyorsun, ama buna A ünite testi olarak adlandırdın:

A için birim testleri yazdığınızda, X ile alay edersiniz. Başka bir deyişle, A birim testi sırasında, X'in alay davranışını X1 olarak ayarlarsınız (varsayılır).

İdeal olarak, X'in alayı, yalnızca X'den beklediğiniz davranışla değil, X'in olası tüm davranışlarını simüle etmelidir . Bu nedenle, X'te gerçekte ne uyguladığınızın önemi yok, A zaten bunu başarabilecek durumda olmalıdır. Bu nedenle, X’de yapılan bir değişiklik, arayüzün kendisini değiştirmek dışında, A için birim testini etkilemeyecektir.

Örneğin: A'nın bir sıralama algoritması olduğunu ve A'nın sıralanacak verileri sağladığını varsayalım. X'in alayına boş bir geri dönüş değeri, boş bir veri listesi, tek bir öğe, çoktan sıralanmış çok sayıda öğe, çoktan sıralanmamış çok sayıda öğe, geriye doğru çok sayıda öğe, aynı öğeyi tekrar eden listeler; Çok sayıda element ve ayrıca bir istisna atmalıdır.

Bu yüzden belki X başlangıçta Pazartesi günleri sıralama verileri ve Salı günleri boş listeler döndürdü. Fakat şimdi X pazartesi günleri sıralanmamış veriler döndürdüğünde ve salı günleri istisnalar atarken, A umrunda değil - bu senaryolar zaten A'nın birim testinde ele alınmıştı.


X, döndürülen dizideki dizini foobar'dan foobarRandomNumber'a değiştirirse, bununla nasıl sayabilirim? Eğer benim fikrimi alırsanız, bu benim meselem, benim meselem, ikinci ismin soyadı olan klasik bir görev olarak döndürülen bir sütunu yeniden adlandırdım, ancak sınavım alay edildiğinden beri asla bilemeyecek. Sadece, bu sorudaki birçok insanın aslında böyle bir şeyi hiç denememiş gibi,
garip bir hisim

Derleyici bu değişikliği tespit etmiş ve size bir derleyici hatası vermiş olmalıdır. Javascript gibi bir şey kullanıyorsanız, daha sonra Typescript'e geçmenizi veya bu şeyleri tespit edebilen Babel gibi bir derleyici kullanmanızı öneririm.
Moby Disk

Dizilerde PHP veya Java ya da Javascript dizileri kullanıyorsam, dizinin bir dizinini değiştirirseniz veya kaldırırsam, bu dillerden hiçbiri derleyenlerin size söyleyemeyeceği, dizinin 36. sayıya yerleştirilebileceği dizinin iç içe düzeyi, bu nedenle derleyicinin bunun için bir çözüm olmadığını düşünüyorum.
FantomX1

-2

Farklı testlere bakmak zorundasın.

Birim testler kendileri yalnızca X testini yapacaklar. X'in davranışını değiştirmeni önlemek için varlar ancak tüm sistemi güvenceye almıyorlar. Davranış değişikliği yapmadan sınıfınızı yeniden düzenleyebilmenizi sağlarlar. Eğer X'i kırarsan, kırdın ...

Bir ünite testleri için gerçekten bir alay X olmalı ve Mock ile yapılan test siz değiştirdikten sonra bile geçmeli.

Ancak birden fazla test seviyesi var! Entegrasyon testleri de var. Bu testler, sınıflar arasındaki etkileşimi doğrulamak için vardır. Bu testler genellikle her şey için alay kullanmadıkları için daha yüksek bir fiyata sahiptir. Örneğin, bir entegrasyon testi aslında bir veritabanına kayıt yazabilir ve bir birim testinin dış bağımlılıkları olmamalıdır.

Ayrıca X'in yeni bir davranışa sahip olması gerekiyorsa, istenen sonucu sağlayacak yeni bir yöntem sunmak daha iyi olur.

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.