Kopyala-Yapıştır Test Kodu: Bu Ne Kadar Kötü?


12

Şu anki işim çoğunlukla üzerinde çalıştığımız çeşitli uygulamalar için GUI test kodu yazıyor. Ancak, ben testler içine bir sürü kod kopyalama ve yapıştırma eğiliminde olduğunu bulmak. Bunun nedeni, test ettiğim alanların tekrarlamaya ihtiyaç duyacak kadar benzer olmaları, ancak kodu yöntemlere veya nesnelere kapsüllemek için yeterince benzer olmalarıdır. Sınıfları veya yöntemleri daha kapsamlı kullanmaya çalıştığımda, testlerin sürdürülmesi daha zahmetli ve bazen de yazmanın açıkça zor olduğunu görüyorum.

Bunun yerine, genellikle bir bölümden büyük miktarda test kodu kopyalayıp başka bir bölüme yapıştırıyorum ve ihtiyacım olan küçük değişiklikleri yapıyorum. Daha fazla OO ilkesi veya işlevi kullanmak gibi daha yapısal kodlama yolları kullanmıyorum.

Test kodları yazarken diğer kodlayıcılar bu şekilde hissediyor mu? Açıkçası DRY ve YAGNI ilkelerini takip etmek istiyorum, ancak test kodunun (yine de GUI testi için otomatik test kodu) bu ilkeleri takip etmeyi zorlaştırabileceğini düşünüyorum. Yoksa sadece daha fazla kodlama pratiğine ve daha iyi bir genel iş yapma sistemine mi ihtiyacım var?

EDIT: Kullandığım araç, 4Test adlı özel bir dilde olan SilkTest. Ayrıca, bu testler çoğunlukla Windows masaüstü uygulamaları içindir, ancak bu kurulumu kullanarak web uygulamalarını da test ettim.


Hangi test aracını kullanıyorsunuz? Test çerçeveniz, yazdığınız test türlerini desteklemiyor olabilir. 3 satırdan fazla kes-yapıştır, genellikle gerçekten kötüdür, ancak GUI testini otomatikleştirerek her seferinde manuel olarak yapmaktan daha uzun vadeli bir değer ekleyebiliyorsanız, yaptığınız şey muhtemelen oldukça kararlıdır. iyi.
GlenPeterson

Ayrıca, bu hangi dil? Sen edebilir yeniden (birinci sınıf fonksiyonları gibi) izin verecek Sadece akla haşhaş değil mevcut bir şey var. Öte yandan, test durumları vardır basit tutulması gerekiyordu, bunu sağlama olasılığı daha düşüktür kendilerinin ... böcek
Izkata

3
Yazdığım herhangi bir şeyde, test kodu yeniden düzenleme dışında bırakılmaz ..
Simon Whitehead

Yanıtlar:


23

Kopyala yapıştırılan ve sonra düzenlenen test senaryoları genellikle iyidir.

Testler mümkün olduğunca az dış bağımlılığa sahip olmalı ve mümkün olduğunca basit olmalıdır. Test vakaları zamanla değişme eğilimindedir ve daha önce neredeyse aynı test vakaları aniden farklı olabilir. Bir test senaryosunu diğer vakaları kırmaktan endişe etmeden güncellemek İyi Bir Şeydir.

Tabii ki, birçok test durumunda aynı olan ve konserde değiştirmek zorunda olan kaynatma plakası kodu çarpanlarına ayrılmalıdır.


1
Esas olarak böyle hissediyorum. Neredeyse aynı test kodu birçok durumda tamamdır, ancak tekrarlanan aynı test kodu kötü haberdir.
joshin4colours

12

Tekrarlama tüm kötülüklerin köküdür

Bu doğru! Tekrarlama tüm kötülüklerin köküdür . Muhtemelen Knuth, “Erken optimizasyon tüm kötülüklerin köküdür” kitabında diyordu, ama bence bu tekrar.

Bir programa baktığınızda veya bir program yazdığınızda ve bir çeşit tekrar bulduğunuzda: Kaldır! Hemen öldürün ... her neyse ama ondan kurtulun !

Her defasında bir çeşit tekrar tanıttım ve orada bir hatayı düzeltmek zorunda kaldım, kopyayı düzeltmeyi unuttum ... (Donald Knuth) Yani, bir tekrar olduğunda, olabildiğince iyi kaldır, hackleme !

Temiz bir yalın tasarım düşünün (tekrarlayan kod bloklarınızı yardımcı sınıflarda kapsüllemek gibi) ve bir şeyi değiştirmeden önce bazı testler yazın (sadece bir şey kırmadığınızdan emin olmak için). Bu, yazılan herhangi bir kod parçası için geçerlidir ve test kodları istisna değildir.

İşte bana ilham veren Code Horror'dan iyi bir okuma - Kod Yeniden Kopyalama ve Yapıştırma Okulu Yeniden Kullanımı için mütevazı bir teklif .


"Her ne zaman bir çeşit tekrar tanıttığımda ve oradaki bir hatayı düzeltmem gerektiğinde, kopyayı düzeltmeyi unuttum ..." tam olarak. Ayrıca, c & p kullanıyorsanız ve kopyalanan metni mevcut bağlamınıza göre ayarlamayı unutursanız, bu çok acı verir. Hatalı test kodu en uygun duruma benzemiyor, şimdi öyle mi?
marktani

Evet, istasyonları
Knuth'dan aldım

9
Kendinizi tekrarladınız: Başlıkta ve giriş cümlenizde "Tekrar tüm kötülüğün köküdür" diyerek kendinizi tekrarladınız.
Thomas Eding

Yeap, önemini vurgulamak için bunu kasten yaptım ve bu kısmı düzenlemeye hoş geldiniz :)
Yusubov

1
Thomas Eding, sen de kendini tekrarladın. Kendinizi de tekrarladınız =)
marktani

7

Kesmek ve yapıştırmak hala çok kötü. Birkaç sorun var.

Tüm kopyala yapıştırılan kodda değişiklik gerektiren bir şeye karşı savunmasız olduğunuz için testleriniz kırılgan olabilir. Tüm testleri yeniden yazmak zorunda kalacak mısınız?

Eğer mantığı testlerinizin dışındaki yardımcı yöntemlerle kapsülleyemezseniz, bu yardımcı yöntemlerin kendilerinin testlerini yazamazsınız. Testi test etmek için kodunuzu kırmanız gerektiğinden, test yöntemlerinin testlerini yazmak genellikle zordur. Ancak test yardımcı yöntemlerini birim olarak ayarlayabilirsiniz .

Testleri daha az okunabilir hale getirebilir. Büyük bir kopyalanan kod bloğunun okunması, açıklayıcı bir ada sahip bir yardım çağrısı yönteminden daha zor olabilir.

Listelediğim her şey sorun olabilecek bir şey . Eğer onlardan hiçbiri bulursanız aslında vardır elbette 's para cezasının ardından bir sorun.


> açıklayıcı bir adla bir yardım çağrısı yöntemi. Ünite testlerinizin artık kendi başlarına programlar haline gelmesi ile ilgili bir sorun değil - ki bu kaçınılması gerekiyor. Bazı testler başarısız olursa - kırık kod mu yoksa test yardımcıları mı?
dwjohnston

4

Sana katılırdım. Ama sonra, zamanla, yaptığım her değişikliğin (özellikle birim testlerdeki DI değişikliklerinin) değişmesi için çok sayıda test gerektirdiğini ve bunun hantal olduğunu gördüm. Şimdi testler yazarken bile DRY okuluna abone oluyorum.

GUI testi için, tekrarlanan kodu azaltmak üzere PageObject modeline bakmak isteyebilirsiniz .


2

XUnit modellerini almanızı tavsiye ederim. O kitabı kullanmaya başlayana kadar aynı problemi yaşardım. Nesne Anne böyle desen seslerin senaryo için en yararlı olacaktır.

Başka biri gibi, bu kurulum kodunu düzgün bir şekilde kapsüllemek zahmetli olabilir, ancak kopyalayıp yapıştırdığınız tüm yerlerde değiştirmek zorunda kalırsınız.


Object Mother patternOrtak başlatma kodu için +1 .
k3b

2

İnsanlar yapabildikleri zaman tekrarlamayı sınırlandırmalılarsa - evet Ancak getirisi duruma bağlıdır. Bu, 'en iyi uygulama' tartışmasına geri dönebilir. Ancak soru bu durumda sizin için en iyi olan şeydir. Her kuralın istisnaları vardır.

Sormak istediğim birkaç şey: 1) UAT'de test edilen bu işlevin değişme olasılığı nedir? Muhtemelen değişmeyecekse, her kod kümenizi güncellemeniz için daha az şansınız vardır. 2) UAT'de bir değişiklik varsa, kopyalanan kodun her setini her zaman etkiler mi yoksa yalnızca bir veya iki seti etkiler mi? İzole edilmişse ve sadece bir sette değişiklik gerektiriyorsa, şeylerin ayrılması yardımcı olabilir. 3) İlk senaryoyu tüm senaryoları halletmeye çalışırsanız ne kadar karmaşık olur? / Else / loop'ları iç içe yerleştiriyor musunuz? Tüm branşları aşırı yapmaya başlarsanız, anlaşılması zor bir kodla karşılaşabilirsiniz. Kopyalanan metnin her birinde güncellemeyi yapmak, tüm dallanma mantığını yeniden ziyaret etmekten daha kolay olur mu?

Eğer kopyala / yapıştır / alter sıkışmış iseniz 'Bu yöntem xyz kopyalanır' gibi yorum eklemek istiyorum düşünürdüm. Bu şekilde, kodun yapıştırılan tüm sürümlerini güncellemeniz hatırlatılır. Veya (başka bir SilkTest kullanıcısından geliyor), yalnızca bu tekrarlanan koda odaklanacak ayrı bir inc dosyası ekleyebilir misiniz? Bu şekilde tüm varyasyonlar tek bir yerde olur ve güncellenmesi gereken farklı yöntemleri kolayca görebilirsiniz.


0

Bir Büyük Prosedür

Bir düşünce: Kulağa şöyle bir yöntem yaparak cut-n-paste kodundan kaçınmaya çalıştığınız anlaşılıyor:

testScreen(title, fieldList, linkList, param1, param2, param3,...) {
    test that the layout at the top of the screen is correct
    test if PageTitle == title?
    for each field in fieldList:
        check that it appears in order on the screen
    for each field in linkList:
        check that it appears in order on the screen
    test if param1 is whatever...
    test if param2 is whatever...
    etc.
    test that the bottom of the screen is correct
}

Birçok Küçük Prosedür (araç kiti)

Bunun tersi yaklaşımı da düşündünüz mü? Büyük bir testScreen () prosedürüne bir milyon parametre geçirmek yerine, kendi çerçevenizi veya araç setini ihtiyacınız olan şekilde kırbaçladığınız küçük yardımcı prosedürler yapabilirsiniz. Sevmek:

testScreenTop()
verifyLinks(list)
testScreenBottom()

Bu prosedürleri hala her ekrana kesip yapıştırıyorsunuz, ancak daha küçük kod parçalarını kesiyor ve yapıştırıyorsunuz ve kesilmemiş ve yapıştırılmamış ortaklık parçalarını (her küçük prosedürün içeriği) gerçekleştiriyorsunuz.

Kes ve yapıştır

Kesilen ve yapıştırılan kod beni ısırmamış olan tek zaman, kodu değiştirmek zorunda kalmadan önce kodun atıldığı zamandı. UI testleriyle ilgili en büyük endişem, ne kadar çabuk eskimiş olduklarıdır. Eğer değiştirmeden önce tüm kodunuzu atmak bulursanız, o zaman belki kesme ve yapıştırma tamam bir niş bulduk! Ayrıca, kesilen ve yapıştırılan koddan aşağı yönde bir kod olmadığında (örneğin bir uygulamanın kullanıcı arayüzünde) o kadar da kötü değildir. 3 satırdan fazla yapıştırıyorsanız, gerçekten bu konuda bir şeyler yapmak istiyorum. En azından küçültmek için adımlar at!

Otomatik Kullanıcı Arayüzü Testi

Heck, otomatik UI testi ile herhangi bir teknik kullanarak manuel testten daha fazla üretkenlik kanıtlayabilirseniz (otomatik testlerin yazılması / sürdürülmesinin maliyeti her seferinde manuel olarak testten daha düşüktür, ancak kalite aynıdır) Bence bir kağıt yazmalısınız. Ben okurdum! Şimdi başlığı, "UI Testi için Net Win Kodunu Kes ve Yapıştır!"


0

Gerçekten o kadar da kötü değil. Aslında, belirli kod modellerinin çok sık kullanıldığını ve değişikliklerin çok rutin olduğunu fark ederseniz (birkaç dize veya parametre değeri gibi), küçük bir (- ish?) değişen değerlerin girdi listesi. Toplu iş dosyaları, SQLPlus komut dosyaları, hatta Excel makroları (bu çirkin görünüyor, ancak farklı test komut dosyalarının değişkenleri zaten bir e-tabloda) kullanarak bunu (oluşturulan test kodu) birçok kez yaptım ve harika bir zaman tasarrufu olabilir . Mesele şu ki, tekrarlanan test senaryosu kodunun genel yapısında bir şey değişirse, ihtiyacınız olan her şeyi yeniden oluşturabilirsiniz.


0

Bu, diğer cevapların çoğuyla aynıdır, ancak teknik olmayan bir yöneticinin anlayabileceği bir şekilde.

Aşağıdaki hata senaryosunu düşünün:

  • Birisi, testinizin çoğunun bağlı olduğu veritabanında değişiklikler yapar.
  • Sonuç: 2933 otomatik testinizin 117'si aniden başarısız oluyor.

Ne yapacaksın?

  • (1) 117 test düzeltildi mi?
  • (2) 117 testi silin ve yeni kopyala ve yapıştır ile yeniden uygulayın. bu (1) 'den daha kolay olabilir
  • (3) ortak kodu çıkarmak için testleri yeniden düzenleyin, böylece gelecekte testleri düzeltmek için sadece bir yöntemi (veya birkaçını) uyarlamanız gerekir (@pdr veya @Michael Brown'un cevaplarına bakın)
  • (4) 117 testi tekrar uygulamadan silin

Deneyimlerimden:

Otomatikleştirilmiş testler tanıtırken yönetim "kopyala ve yapıştır testleri" ni sever: kısa sürede birçok test alırsınız.

Bazı "hata senaryoları" sonra yönetim (4) tercih ediyor çünkü "kopyala ve yapıştır testleri" düzeltmek çok pahalı.

İlk etapta doğru yapın (3) çok hızlı olmayacak, ancak testlerin hayatta kalma şansını artıracaktır

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.