TDD - İç Dış vs İç Dış


53

TDD kullanarak bir uygulama Outside In vs Inside Out bir uygulama oluşturma arasındaki fark nedir ?

Bunlar TDD ve birim testleri hakkında okuduğum kitaplardır:
Teste Dayalı Geliştirme: Örnek
Teste Dayalı Geliştirme: Pratik Bir Rehber: Microsoft'ta
Yüksek Kalite PHP Altyapıları ve Uygulamalarına
Dayalı Geliştirme Geliştirmeye Yönelik Gerçek-Dünya Çözümleri . NET
xUnit Test Modelleri: Test Kodunun
Yeniden Uygulanması Ünite Testleri Sanatı: .Net Örnekleriyle
Büyüyen Nesne Yönelimli Yazılımlarla, Testler Kılavuzuyla ---> JAVA benim ana dilim olmadığı için bunu anlamak gerçekten zor oldu :)

Neredeyse hepsi genel olarak TDD'nin temellerini ve birim testlerini açıkladı, ancak uygulamanın yapılabileceği farklı yollardan çok az söz etti.

Dikkatimi çeken bir diğer şey ise, bu kitapların çoğunun (eğer hepsi değilse), başvuru yazarken tasarım aşamasını göz ardı etmesidir. Test vakalarını hızlı bir şekilde yazmaya ve tasarımın kendiliğinden ortaya çıkmasına izin vermeye daha fazla odaklanırlar.

Ancak, insanların TDD'ye yaklaşım yollarını tartışan xUnit Test Patterns'da bir paragrafa rastladım. Outside In vs Inside Out dışında 2 okul var .

Ne yazık ki kitap bu noktada daha fazla ayrıntı vermiyor. Bu iki vaka arasındaki temel farkın ne olduğunu bilmek istiyorum.
Her birini ne zaman kullanmalıyım?
Bir TDD acemi için hangisini kavramak daha kolaydır?
Her yöntemin dezavantajı nedir?
Bu konuyu özel olarak tartışan herhangi bir materyal var mı?


İki yaklaşım, XUnit Test Patterns sitesinde açıklanmaktadır: xunitpatterns.com/Philosophy%20Of%20Test%20Automation.html . Kitapta olmaması garip.
guillaume31 11

Yanıtlar:


45

İçeride ve Dışarıda oldukça nadir terimlerdir, daha çok Klasik okul ve Londra okulu hakkında duydum / okudum .

  • Inside-Out (Klasik okul, aşağıdan yukarıya ): bileşen / sınıf düzeyinde (içeride) başlar ve gereksinimlere test eklersiniz. Kod geliştikçe (yeniden yapılanmalar nedeniyle), yeni ortak çalışanlar, etkileşimler ve diğer bileşenler ortaya çıkar. TDD, tasarımı tamamen yönlendirir.

  • Dışarıda ( Martin Fowler'ın söylediği gibi Londra okulu, yukarıdan aşağıya veya "alaycı TDD" ): Öncelikle etkileşimleri ve ortak çalışanları (özellikle en üst düzeylerde olanlar) ve oradan başlayarak gerekli bağımlılıkları alay ederek biliyorsunuz . Her bitmiş bileşenle, daha önce alay konusu olan ortak çalışanlara geçiyor ve orada tekrar TDD ile başlıyorsunuz, gerçek uygulamalar ( soyutlamalar sayesinde daha önce gerekli olmasa da gerekli olan) yaratıyorsunuz . Not dıştan içe yaklaşım ile iyi gider YAGNI prensibi.

Yaklaşımların hiçbiri tek değil ; ikisi de ne yaptığınıza bağlı olarak kendi yerlerine sahip. Tasarımın parçalarının mimarlardan geldiği (veya ön planda olduğu) büyük kurumsal çözümlerde, biri "Londra tarzı" yaklaşımıyla başlayabilir. Öte yandan, kodunuzun nasıl görünmesi gerektiğinden (veya sisteminizin diğer bölümlerine nasıl sığması gerektiğinden) emin olmadığınız bir durumla karşılaştığınızda, bazı düşük kaliteli bileşenlerle başlamak ve izin vermek daha kolay olabilir daha fazla test, refactorings ve gereksinimler ortaya çıktıkça gelişir.

Hangisini kullanırsanız kullanın, durumundan çok daha sık.

Daha fazla okumak için, bu ayrımın nasıl ortaya çıkmış olabileceği ve neden Londra'nın en uygun isim olamayacağı konusunda oldukça ilginç bir tartışma içeren Google grubu gönderisi var.


2
İlginç. TDD’de dışardan “alaycı” TDD olduğu sonucuna nasıl vardınız? Dışarıda düşünmeyi ve tasarlamayı ve böylece test etmeyi çok tercih ediyorum (bkz. Softwareonastring.com/2015/01/10/… ), ancak Fowler makalesi beni kesinlikle klasikçi kamptaki Fowler'a bırakıyor. Alaycı her zaman bir dışardan yaklaşım kullanabilse de, onu geri çeviremez ve dışardan tasarım ve testlerin alaycı TDD olduğunu söyleyemezsiniz. Dışardakiler klasik TDD-ers tarafından da uygulanabilir ve fazlasıyla uygulanabilir.
Marjan Venema

@jimmy_keen - Dışardayken, herhangi bir noktada, daha sonra oluşturulan gerçek uygulamalarla daha üst düzey testlerdeki alayların yerini alıyor musunuz? Yoksa onları alaycı bağımlılıklar olarak bırakıp ardından tüm üretim kodunu bir entegrasyon testi olarak mı kullanıyorsunuz?
thehowler

1
Klasik / Mockist ve Inside-Out / Outside-In'in birbiriyle ilgili olduğunu kabul etmiyorum. Ortogonallar. Inside-Out / Outside-In ile ikisini de kullanabilirsiniz.
Daniel Kaplan

Daniel ile aynı fikirde. Farklı olan iki taksonomiyi deniyorsunuz. Dışarıdaki gelişim genellikle Londra (mockist) okuluyla ilişkilendirilse de, her zaman böyle değildir.
guillaume31

Bunun dışarıdaki sürecin doğru bir açıklaması olduğunu sanmıyorum. Ortak arabirimlerden mümkün olduğunca dahili bağlantılara bağlanmadan test yapmakla ilgili.
mcintyre321

15

Kısa Cevap: Her zaman olduğu gibi , kodlama tercihinize ve takım yaklaşımınıza bağlı olacaktır .

İçeride kodlama yapmak harika çünkü her zaman çalışan bir şeyin var. Dezavantajı, mutlaka radikal olarak farklı bir yere gitmenize yardımcı olmamasıdır. Bu şekilde bir kursu haritalamak daha zordur. Benzer şekilde, dışarıda kod yazmak , hızlı bir yinelemeli gelişme avantajına sahip olmamanın ve kodun yapısının derinliklerinden doğabilecek tüm fırsatları ve kalıpları mutlaka görmemenin dezavantajıdır.

Her iki gelişim tarzının da önemli olduğuna ve bir takım stilleri bir karışımına sahip olmanın gerçekten yararlı olduğuna inanmaya başladım . Buradaki fikir, iç yapı dış yapı taşları oluşturmak için harikadır ve dış düşünme biçiminde yapı ve yön sağlar.

Akıl yürütmemin bir kısmı, çoğunlukla içten gelişme ile eşanlamlı olan, yinelemeli gelişimi destekleyen çok popüler bir düşünce okulundan geliyor. Çok fazla ilerlemen olmadığında yinelemeli gelişimin harika olduğuna inanıyorum . Ancak, büyük yinelemeli bir sürecin aksine, büyük resim düşüncesinin, bazı inovasyon türlerine ve daha az belirgin bir yere gitmeye değmez olduğunu düşünüyorum. Düzgün bir şekilde yönetilen, içte ve dışta birlikte çok etkili bir kombinasyon olabilir.


8

C #'daki Çevik Prinicples, Patterns and Practices'i bu listeye eklemelisiniz . Sonunda neden "in C #" ye girdiğini bilmiyorum. Kitaplar hiç dil değil ve amazonda 5 yıldız alamamasının tek nedeni, örneklerinin C # sıfatıyla hayal kırıklığına uğramış insanlardan.

Yazar, mümkün olduğunca dışarıdan kod yazmaya çalışmanız ve ağır evrimsel tasarıma güvenmeniz gerektiğini savunuyor ve bu ifadeye katılıyorum. Onun mantığı, işlevsellik ekledikçe, tasarımımızın her zaman değişeceğidir. Özellikler eklendikçe düşük seviyeli bileşenlerle başlarsak, bu bileşenlerin yapmak istediklerimizi yapmadıklarını ya da hareket ettirilmeleri gerektiğini fark edeceğiz. Bu, özellikle işlevselliği bir sınıftan diğerine taşıdığınızda, aynı işlemi tüm birim test projelerinde yapmanız gerektiğinde oldukça pahalı olabilir.

Diğer taraftan, uygulamanızın ilk başta ne yapması gerektiğini belirlerseniz, harici arayüzü kodlarsınız. Özellikler eklendikçe ve test altındaki kodlar büyüdükçe, uygulamanızı daha fazla sınıfa yeniden yansıtırsınız, ancak bu yeniden düzenleme çabası devam ederken, yazdığınız orijinal birim testleri geçerli kalır. Böylece, tamamen dışarıdan başlayıp, daha düşük seviyeli sınıflara yeniden girmeye devam ederken, bu iç sınıflara ek ünite testleri eklersiniz, ancak nadiren ünite testlerinizi hareket ettirmek ve yeniden yazmak zorunda kalırsınız.

Bununla birlikte, uygulamanızın ihtiyaç duyacağı belirli bir düşük seviye alt sistemi tespit ederseniz (ve belki de şirketinizin diğer uygulamalarda bu tür alt sistemlere zaten ihtiyacı olabilir), ilk önce düşük seviyeli bir yapı bloğu ile başlamanın zamanı gelmiştir. Bunun üzerine uygulamayı inşa.


7

Gördüğüm kadarıyla Dış Gelişim kavramı gerçekten 2 seviyeye yayılıyor. Gerard Meszaros , bunları kısaca “dışarıdan tasarım ” ve “dışarıdan içeriye / dışarıya kodlama ” olarak tanımlamaktadır .

  • İlk seviye bir organizasyon ve süreç seviyesidir. Dış tasarım, yukarıdan aşağıya (şelale / taylorist) ve aşağıdan yukarıya anlamına gelir. Dışarıdan gelen bir yaklaşımla, son kullanıcının bakış açısına odaklanırız. Öykü testleri, ATDD veya BDD testleri ile başlıyoruz ve teknik testler ve kodlar çıkartarak "içe" gidiyoruz. Bu nedenle dışarıdan gelen tasarım, genellikle çevik bir bağlamda yapacağınız şeydir. Dan North BDD, yukarıdan aşağıya, aşağıdan yukarıya ve dışarıdan içeri yaklaşımlar hakkında harika bir konuşma yaptı .

  • İkinci seviye teknik ve uygulamalı katmanlarla ilgili. Dışarıdan kodlama temel olarak UI'dan başlayarak içeriye doğru merkezi katmana (genellikle işletme / etki alanı katmanı) geçmek anlamına gelir. Merkez katmandan başlayıp dış katmanları en son kodlayan iç kodlamanın aksine.

Böylece, dışarıdan içeri kodlama veya dışarıdan içeri kodlama ile dışarıdan içeriye sahip olabilirsiniz.

Meszaros ile aynı fikirde olmadığım şey ise, iç-dış kodlamayı entegrasyon testiyle ilişkilendirdiğinde, iç-dış bağlamda "aslında dış yazılımı iç yazılımın izolasyonunda test etmediğimizi" iddia ediyor. Ama hiçbir şeyin senin yapmanı engellemediğine inanıyorum Dış katman nesnelerinizi, üretim kodu zaten varsa bile iç katman nesnelerini alay ederek test etmeyi mükemmel şekilde seçebilirsiniz. Arayüzleri yazmak, alay etmek ve daha sonra dış kodlamada yaptığınız gibi uygulamaları oluşturmak yerine mevcut somut nesnelerin üzerine arayüzler ve alaylar eklemeniz gerekir.

Başka bir deyişle, mockist veya klasik tarz TDD, IMO'nun dışarıdan içeriye / dışarıdan dışarıya kodlamada ortogonal bir endişe kaynağıdır. Bir mockist stili içten dışa yaklaşımla birlikte mükemmel bir şekilde kullanabilirsiniz. Bunun arkasındaki neden, mockist / klasik stilin kod bağımlılıkları ile ilgili olmasıdır ; dışarıdan / dışarıdan-dışarı kodlama uygulama katmanları ile ilgilidir .

Bir diğer önemli şey, bağımlılıkların sadece katmanlar arasında olmadığı, aynı katmandaki nesneler arasında da var olduklarıdır. Örneğin, merkezi iş katmanınızdaki (iç içe yaklaşım) bir nesneyle başlamak ve nesnenizi konuştuğu diğer iş katmanı nesnelerinden izole etmek için alay kullanmak isteyebilirsiniz. Bu IoC ile çok olur - nesnenizin dayandığı soyutlamalar genellikle aynı katmanda bildirilir, ancak somut uygulamalar farklı bir katmandadır.

Robert "Bob Amca" Martin kısaca içeriden kodlamayı ve bunun " Temiz Mimari " adlı yazısında ayrık bir mimariyle nasıl çakışmayacağını anlatıyor .

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.