Neden bir dili test etmek, sözdizimi seviyesinde desteklenen bir özellik değil?


37

Kaynak kodunuzu test etmenin ünitenin faydalarını tanıtan sonsuz bir blog, makale ve web sitesi listesi bulabilirsiniz . Java, C ++, C # ve diğer yazılı diller için derleyicileri programlayan geliştiricilerin, çalışmalarını doğrulamak için birim sınaması kullanmaları neredeyse garanti edilir.

Öyleyse neden, popülaritesine rağmen, bu dillerin sözdiziminde test yok mu?

Microsoft LINQ to C # ürününü tanıttı , peki neden test ekleyemediler?

Bu dil değişikliklerinin ne olacağını tahmin etmek istemiyorum, ama neden başlamadıklarını açıklığa kavuşturmak için.

Örnek olarak: forİfadenin sözdizimi olmadan bir döngü yazabileceğinizi biliyoruz for. Sen kullanabilirsiniz whileveya if/ gotoifadeleri. Birisi bir forifadenin daha verimli olduğuna karar verdi ve onu bir dile getirdi.

Neden test programlama dillerindeki aynı gelişmeyi takip etmedi?


24
Bir dili kolayca, jenerik bir şekilde kolayca genişletilebilecek basit kurallarla tasarlamanın aksine, sözdizimi ekleyerek daha karmaşık hale getirmek gerçekten daha mı iyi?
KChaloux

6
Ne demek "sözdizimi düzeyinde"? Nasıl uygulanacağı hakkında herhangi bir detayınız / fikriniz var mı?
SJuan76,

21
Sözdizimi destekli bir özellik olarak test etmek için sözde kod örneği verebilir misiniz? Nasıl görüneceğini düşündüğünüzü merak ediyorum.
FrustratedWithFormsDesigner

12
@FrustratedWithFormsDesigner Örnek için D diline bakın .
Doval

4
Dahili ünite test özelliklerine sahip diğer bir dil ise Rust.
Sebastian Redl,

Yanıtlar:


36

Birçok şeyde olduğu gibi, birim testi en iyi dil düzeyinde değil kütüphane düzeyinde desteklenir. Özellikle, C #, mevcut .NET Framework'e özgü şeylerin yanı sıra çok sayıda Birim Test kütüphanesine sahiptir Microsoft.VisualStudio.TestTools.UnitTesting.

Her Birim Test kütüphanesinin biraz farklı test felsefesi ve sözdizimi vardır. Her şey eşit olmakla birlikte, daha çok seçenek daha az iyidir. Birim testi dile göre yapılsaydı, ya dil tasarımcının tercihlerine kilitlenirdiniz ya da bir kütüphane kullanır ve dil testi özelliklerinden tamamen kaçınırdınız.

Örnekler

  • Nunit - Genel amaç, C # 'ın dil özelliklerinden tam anlamıyla yararlanan, aptalca tasarlanmış ünite testi çerçevesi.

  • Adedi - Bir kayıt / oynatma metaforu olmadan lambda ifadeleri ve ifade ağaçlarından tam olarak yararlanan alaycı çerçeve.

Başka birçok seçenek var. Microsoft Fakes gibi kütüphaneler, sınıflarınızı arabirimler veya sanal yöntemler kullanarak yazmanızı gerektirmeyen "şimler ..." alayları oluşturabilir.

Linq bir dil özelliği değil (ismine rağmen)

Linq bir kütüphane özelliğidir. C # dilinde ücretsiz olarak lambda ifadeleri ve uzatma yöntemleri gibi birçok yeni özelliğimiz var, ancak Linq'in gerçek uygulaması .NET Framework'te.

Linq ifadelerini daha temiz hale getirmek için C # 'ya eklenmiş bazı sözdizimsel şeker vardır, ancak bu şeklin linq kullanması gerekli değildir.


1
LINQ'un bir dil özelliği olmadığı, ancak LINQ'in gerçekleşmesini sağlamak için bazı temel dil özelliklerinin olması gerektiğine katılıyorum - özellikle jenerik ve dinamik türler.
Wyatt Barnett

@WyattBarnett: Evet ve aynısı kolay ünite testi için de geçerlidir - yansıma ve özellikler.
Doc Brown,

8
LINQ'a lambda ve ifade ağaçları gerekiyordu. Jenerikler zaten C # 'da (ve .Net, genel olarak, CLR'de bulunurlardı) ve dinamiklerin LINQ ile ilgisi yok; Dinamik olmadan LINQ yapabilirsiniz.
Arthur van Leeuwen

Perl'in DBIx :: Class'ı, uygulaması için gereken tüm özelliklerin dilde olmasından 10 yıl sonra uygulanan LINQ benzeri işlevselliğe bir örnektir.
slebetman

2
@ Carson63000 Bence var:) anahtar kelimesiyle birlikte anonim tür demek istediğinizi düşünüyorum
M.Mimpen

21

Çok fazla sebep var. Eric Lippert, nedenlerin feature XC # 'da olmadığını, sadece bütçelerinde olmadığı için defalarca dile getirdi. Dil tasarımcılarının bir şeyleri uygulamak için sınırsız zaman veya parası yoktur ve her yeni özelliğin de bununla ilgili bakım maliyetleri vardır. Dili mümkün olduğu kadar küçük tutmak, dil tasarımcıları için kolay değildir - alternatif uygulamalar ve araçlar yazan herkes için de daha kolaydır (örneğin IDE'ler) Ek olarak, bir dil yerine bir dil yerine uygulandığı zaman, ücretsiz taşınabilirlik. Birim testi bir kütüphane olarak uygulanıyorsa, yalnızca bir kez yazmanız yeterlidir ve bu, dilin uygun bir uygulamasında çalışacaktır.

D'nin birim testi için sözdizimi düzeyinde bir desteğe sahip olduğunu belirtmekte fayda var . Bunu neden atmaya karar verdiklerini bilmiyorum, ama D'nin "yüksek seviyeli bir sistem programlama dili" olduğu anlamına geliyor. Tasarımcılar, güvenli olmayan, düşük seviyeli C ++ kodunun geleneksel olarak kullanıldığı ve güvenli olmayan koddaki bir hatanın inanılmaz derecede pahalı - tanımsız davranışı için geçerli olmasını istedi. Bu yüzden bazı güvenli olmayan kodların çalıştığını doğrulamanıza yardımcı olacak herhangi bir şey için fazladan çaba harcamanın onlara mantıklı geldiğini düşünüyorum. Örneğin, yalnızca belirli güvenilir modüllerin denetlenmeyen dizi erişimi veya işaretçi aritmetiği gibi güvenli olmayan işlemler gerçekleştirmesini zorlayabilirsiniz.

Hızlı gelişme, onlar için de bir öncelikti, öyle ki D kodunun bir kodlama dili olarak kullanılabilir olması için yeterince hızlı derlediği bir tasarım hedefi haline getirdiler. Pişirme birimi testlerini doğrudan dile getirin, böylece sadece derleyiciye fazladan bir bayrak göndererek testlerinizi gerçekleştirebilirsiniz.

Ancak, harika bir birim test kütüphanesinin sadece bazı metotları bulmak ve çalıştırmaktan çok daha fazlasını yaptığını düşünüyorum . Haskell'in QuickCheck'ini ele alalım , örneğin "x ve y için" gibi şeyleri test etmenizi sağlar f (x, y) == f (y, x). QuickCheck daha iyi bir birim test üreticisi olarak tanımlanır ve "bu giriş için bu çıkışı bekliyorum" den daha yüksek seviyede test etmenize olanak sağlar. QuickCheck ve Linq hepsi o kadar farklı değil - ikisi de etki alanına özgü diller. Öyleyse, bir dilin test desteğini cıvatalamak yerine, neden DSL'leri pratik yapmak için gereken özellikleri eklemiyorsunuz? Sadece ünite testleriyle değil, sonuç olarak daha iyi bir dille biteceksiniz.


3
.Net dünyasında kalmak için, F # 'ya bir QuickCheck limanı olan FsCheck var, C #' dan kullanım için bazı yardımcılar var.
Arthur van Leeuwen

.NET dünyasında kalmak için? Bu sorunun .NET ile ilgisi yok.
Miles Rout

@MilesRout C #, .NET'in bir parçasıdır. Soru ve cevap, C # hakkında sık sık konuşuyor ve soru bile LINQ hakkında da konuşuyor.
Zachary Dow

Soru etiketli değil .NET veya C #.
Miles Rout

@MilesRout Bu doğru olabilir, ancak etiketin olmadığı için bununla hiçbir ilgisi olmadığını söyleyemezsiniz . :)
Zachary Dow

13

Çünkü test etme ve özellikle teste dayalı gelişim, derinlemesine sezgisel bir fenomendir.

Neredeyse her programcı, kariyerlerini karmaşıklığı yönetmede gerçekte olduğundan daha iyi olduklarına inanmakla başlar. Hatta büyük programcı gerçeği olamaz onlar regresyon testlerinde ciddi hayal kırıklığı ve birçok uygulayıcıları bile utanç verici olduğunu sürü kullanmadığınız sürece şiddetli hatasız büyük ve karmaşık programlar yazmak. Dolayısıyla, zaten daha iyi bilmesi gereken profesyoneller arasında bile düzenli testlere karşı yaygın bir ayrımcılık yaşanması.

Dini testlerin yavaş yavaş daha yaygın hale geldiğini ve beklenen durumun, büyük ölçüde, depolama kapasitesindeki ve hesaplama gücündeki patlama ile, her zamankinden daha büyük sistemlerin inşa edilmesinden kaynaklandığını ve çok büyük sistemlerin özellikle karmaşıklığa yol açtığını düşünüyorum. regresyon testlerinin güvenlik ağı olmadan yönetilemez. Sonuç olarak, özellikle engelleyici ve aldatıcı geliştiriciler bile istemeden test etmeye ihtiyaçları olduğunu ve her zaman teste ihtiyaç duyacaklarını itiraf ediyorlar. bireyler).

Günümüzde popüler olan çoğu dil, bu tutum değişikliğinden önce gelir, bu nedenle testler için yerleşik destekleri assertyoktur: sözleşmeleri vardır ancak sözleşmeleri yoktur. Trend devam ederse, gelecekteki dillerin kütüphane seviyesinden ziyade dile daha fazla destek olacağından oldukça eminim.


3
Davanızı biraz abartırsınız. Ünite testi tartışmasız bir öneme sahip olsa da, programları doğru şekilde inşa etmek , gereksiz karmaşıklığı en aza indiren yol, daha fazla olmasa da aynı derecede önemlidir. Haskell gibi diller, kendilerine yazılan programların güvenilirliğini ve üretilebilirliğini artıran tip sistemlerine sahiptir ve kodlama ve tasarımdaki en iyi uygulamalar, test edilmemiş kodların tuzaklarından kaçınır ve birim testini diğerlerinden daha az kritik hale getirir.
Robert Harvey,

1
@RobertHarve ... ve birim testi, dolaylı olarak geliştiricileri buna itmek için çok iyi bir yoldur. Testler oluştururken API ile çalışmak, başka bir kodla kullanmak yerine, sızan soyutlamaları veya tek yöntemli çağrıları sınırlandırmak veya kaldırmak için doğru zihniyete koymalarına yardımcı olur. KillianFoth'un hiçbir şeyi abarttığını sanmıyorum.
Izkata

@Robert: Üstesinden geldiğimi düşündüğüm tek şey "dini sınavlar yavaş yavaş yaygınlaşıyor". Coğrafi zaman dilimleri açısından yavaşça tanımlanırsa muhtemelen çok uzakta değil ..... :)
mattnz

+1 Şu anki mesleğimde mevcut yeni kütüphaneler ve teknolojilerle birlikte gelişim tutumundaki gelgit değişiminden etkileniyorum. Kariyerimde ilk defa, bu adamlar rüzgarda bağıran bir tepenin tepesinde olduğumu hissetmek yerine, daha gelişmiş bir geliştirme süreci kullanmam için bana ders veriyorlar . Bu tutumların anadili sözdiziminde ifadeyi bulmasının sadece zaman meselesi olduğuna katılıyorum.
Rob,

1
Üzgünüz, bir düşünce daha: Robert Harvey'in yorumu. Şu anda tip sistemleri güzel bir kontrol, ancak gerçekten türler üzerindeki kısıtlamaları tanımlamada oldukça yetersiz kalıyorlar - ara yüzü ele alıyorlar, ancak doğru davranışı kısıtlamıyorlar. (yani 1 + 1 == 3, + uygulamasına bağlı olarak derlenecek ancak doğru olabilir veya olmayabilir). Bir sonraki eğilimin, şu anda birim testi olarak düşündüğümüzü birleştiren daha etkileyici tip sistemler görüp görmeyeceğini merak ediyorum.
Rob,

6

Test için birçok dil desteği var. C'nin iddiası, programın başarısız olabileceği testlerdir. Çoğu dilin durduğu yer burasıdır, ancak Eyfel ve daha yakın bir zamanda Ada 2012'de ön değişkenler var (bir fonksiyonun argümanlarının geçmesi gereken şeyler) ve postinvariantlar (bir fonksiyonun çıktısının geçmesi gereken şeyler), Ada'da ilk argümanlara referans verme yeteneği sunar. postinvariant. Ada 2012, aynı zamanda tür değişmezleri de sunar; bu nedenle, bir Ada sınıfında bir yöntem çağrıldığında, değişmeyen tür döndürmeden önce denetlenir.

Bu, iyi bir test çerçevesinin size sağlayabileceği tam kapsamlı test türü değildir, ancak dillerin en iyi şekilde destekleyebileceği önemli bir test türüdür.


2
Eyfel’de biraz çalışma yapmış ve iddiaların kapsamlı bir kullanıcısı olarak, deneyimlerim, yapabileceğiniz her şeyin doğada yapabileceği herhangi bir şeyin bir sürü hataya yol açmasına yardımcı olduğuydu.
Blrfl

2

Güçlü yazılmış dillerin bazı savunucuları, bu dil özelliklerinin birim testlerine duyulan ihtiyacı azalttığını veya ortadan kaldırdığını iddia eder.

İkincisi, bunun için iyi bir örnek, burada ve burada Eğlence ve Kar için F # dan

Şahsen, hala birim testlerinin değerine inanıyorum, ancak bazı geçerli noktalar var. Örneğin, yasadışı bir durum kodda bildirilemezse, o zaman bu durumda bir birim sınamaları yapmak gereksiz değildir, bu mümkün değildir.


2

Bazı gerekli özelliklerin eklenmesini kaçırdığınızı, çünkü ünite testlerinde olduğu gibi vurgulanmadıklarını iddia ediyorum .

Örneğin, C # 'daki birim testi temel olarak nitelikler kullanılarak yapılır. Özel Ayrıntılar özelliği gibi şeyler, yineleme ve rekabet ettiğini için NUnit gibi çerçeveler sağlayan bir zengin uzatma mekanizma sağlar Teorisi tabanlı ve Parametreli testleri.

Bu beni ikinci ana noktama getiriyor - onu bir dilde pişirmek için iyi bir test edilebilirliği neyin iyi olduğu hakkında yeterince bilgimiz yok. Testte inovasyonun hızı diğer dil kurgularından çok daha hızlı olduğundan, inovasyon için özgürlük bırakmak için dillerimizde esnek mekanizmalara ihtiyacımız var.

Ben bir kullanıcıyım ama TDD konusunda fanatik değilim - bazı durumlarda özellikle tasarım düşüncenizi geliştirmek için çok yararlıdır. Daha büyük eski sistemler için mutlaka faydalı değildir - iyi veri ve otomasyonla daha yüksek seviyeli test yapılması, güçlü bir kod inceleme kültürüyle birlikte daha fazla fayda sağlayacaktır .

Diğer ilgili okumalar:

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.