Birim testleri yazarken neyi test edeceğinizi nasıl biliyorsunuz? [kapalı]


127

C # kullanarak, Userkullanıcı adı, şifresi, aktif bayrağı, adı, soyadı, tam adı vb. Olan bir sınıfa ihtiyacım var.

Bir kullanıcının kimliğini doğrulamak ve kaydetmek için yöntemler olmalıdır . Sadece yöntemler için bir test mi yazmalıyım? Ve .Net'in alıcıları ve ayarlayıcıları oldukları için özellikleri test etme konusunda endişelenmem gerekiyor mu?


Bu mesaj daraltan geniş soruyla yardımcı olacaktır: earnestengineer.blogspot.com/2018/03/... sorunuzu odaklamak için bu yönergeleri alabilir
Lindsay Morsillo

Şifrelerin düz metin olarak saklanmaması gerektiğini unutmayın.
Bay Anderson

Yanıtlar:


131

Buna birçok harika yanıt da sorumda : " Başlangıç ​​TDD - Zorluklar? Çözümler? Öneriler? "

Blog yazıma bir göz atmanızı da tavsiye edebilir miyim (kısmen sorumdan ilham almıştır), bu konuda bazı iyi geri bildirimler aldım. Yani:

Nereden Başlayacağımı Bilmiyorum?

  • Yeniden başlayın. Yalnızca yeni kod yazarken test yazmayı düşünün. Bu, eski kodun yeniden çalışması veya tamamen yeni bir özellik olabilir.
  • Basit başlayın. TDD-esque olmanın yanı sıra kaçıp kafanızı bir test çerçevesine sokmaya çalışmayın. Debug.Assert iyi çalışıyor. Bunu bir başlangıç ​​noktası olarak kullanın. Projenizle uğraşmaz veya bağımlılıklar yaratmaz.
  • Pozitif başlayın. Zanaatınızı geliştirmeye çalışıyorsunuz, bu konuda iyi hissedin. Orada durgunlaşmaktan ve kendilerini daha iyi hale getirmek için yeni şeyler denemekten mutlu olan birçok geliştirici gördüm. Doğru olanı yapıyorsun, bunu hatırla ve bu, pes etmene engel olur.
  • Bir meydan okumaya hazır olun. Test etmeye başlamak oldukça zor. Bir meydan okuma bekleyin, ancak unutmayın - zorlukların üstesinden gelinebilir.

Yalnızca Beklediklerinizi Test Edin

İlk başladığımda gerçek problemler yaşadım çünkü sürekli orada oturup oluşabilecek olası her sorunu anlamaya ve sonra test edip düzeltmeye çalışıyordum. Bu, baş ağrısına giden hızlı bir yoldur. Test, gerçek bir YAGNI süreci olmalıdır. Bir sorun olduğunu biliyorsanız, bunun için bir test yazın. Aksi takdirde, zahmet etmeyin.

Sadece Bir Şey Test Edin

Her test senaryosu yalnızca bir şeyi test etmelidir. Kendinizi test senaryosu adına "ve" yazdığını bulursanız, yanlış bir şey yapıyorsunuz demektir.

Umarım bu, "alıcılar ve ayarlayıcılar" dan devam edebileceğimiz anlamına gelir :)


2
"Bir sorun olduğunu biliyorsanız, o zaman bunun için bir test yazın. Aksi takdirde, zahmet etmeyin." Bunun ifade ediliş şekline katılmıyorum. Birim testlerinin tüm olası yürütme yollarını kapsaması gerektiği izlenimine kapılmıştım.
Corin Blaikie

3
Bazıları bu tür şeyleri savunabilirken, şahsen ben değilim. Baş ağrımın% 90'ı sadece "her şeyi" yapmaya çalışmaktan geldi. Olmasını beklediğiniz şey için test diyorum (böylece doğru değerleri geri aldığınızı biliyorsunuz) ama hepsini çözmeye çalışmayın. YAGNI.
Rob Cooper

4
Ben de "böceklerini test et" yaklaşımını savunuyorum. Hepimizin sonsuz zamanı ve sabrı olsaydı, olası her yürütme yolunu test ederdik. Ama biz yapmıyoruz, bu yüzden çabanızı en büyük etkiyi yaratacağı yere harcamalısınız.
Schwern

63

Dili değil kodunuzu test edin.

Şunun gibi bir birim testi:

Integer i = new Integer(7);
assert (i.instanceOf(integer));

yalnızca bir derleyici yazıyorsanız ve instanceofyönteminizin çalışmama ihtimali sıfır olmayan bir ihtimal varsa kullanışlıdır .

Dile güvenebileceğiniz şeyleri test etmeyin. Sizin durumunuzda, kimlik doğrulama ve kaydetme yöntemlerinize odaklanırdım ve bu alanların herhangi birinde veya tümünde null değerleri düzgün bir şekilde işleyebilmelerini sağlayan testler yazardım.


1
"Çerçeveyi test etme" üzerine İyi Nokta - Bu konuda yeni olduğumda benim de aldığım bir şey. + 1'ed :)
Rob Cooper

38

Bu beni birim testine soktu ve beni çok mutlu etti

Birim testi yapmaya yeni başladık. Uzun zamandır bunu yapmaya başlamanın iyi olacağını biliyordum ama nasıl başlayacağımı ve daha da önemlisi neyi test edeceğimi bilmiyordum.

Sonra muhasebe programımızda önemli bir kodu yeniden yazmak zorunda kaldık. Bu bölüm, birçok farklı senaryo içerdiği için çok karmaşıktı. Bahsettiğim kısım, muhasebe sistemine zaten girilmiş olan satış ve / veya satın alma faturalarını ödeme yöntemidir.

Pek çok farklı ödeme seçeneği olduğu için kodlamaya nasıl başlayacağımı bilmiyordum. Fatura 100 $ olabilir, ancak müşteri yalnızca 99 $ transfer etti. Belki bir müşteriye satış faturaları göndermişsinizdir, ancak o müşteriden de satın almışsınızdır. Yani onu 300 dolara sattın ama 100 dolara aldın. Müşterinizin bakiyeyi kapatmak için size 200 $ ödemesini bekleyebilirsiniz. Ya 500 dolara sattıysan ama müşteri sana sadece 250 dolar öderse?

Bu yüzden, bir senaryonun mükemmel çalışacağı, ancak diğer türden bir fatura / ödeme kombinasyonunda yanlış olacağı birçok olasılıkla çözmem gereken çok karmaşık bir problem vardı.

Burası birim testinin kurtarmaya geldiği yer.

Hem satışlar hem de satın almalar için fatura listesi oluşturmak için bir yöntem (test kodunun içinde) yazmaya başladım. Sonra asıl ödemeyi oluşturmak için ikinci bir yöntem yazdım. Normalde bir kullanıcı bu bilgiyi bir kullanıcı arayüzü aracılığıyla girer.

Sonra, herhangi bir ödeme indirimi olmaksızın tek bir faturanın çok basit bir ödemesini test eden ilk TestMethod'u oluşturdum. Sistemdeki tüm eylem, bir banka ödemesi veritabanına kaydedildiğinde gerçekleşir. Gördüğünüz gibi bir fatura oluşturdum, bir ödeme (banka işlemi) oluşturdum ve işlemi diske kaydettim. İddialarımda, Banka işleminde ve bağlantılı Faturada biten doğru numaraların ne olması gerektiğini yazıyorum. İşlem sonrası ödeme adedini, ödeme tutarını, indirim tutarını ve fatura bakiyesini kontrol ediyorum.

Test çalıştırıldıktan sonra veritabanına gidip beklediğim şeyin orada olup olmadığını iki kez kontrol ettim.

SonraTesti yazdıktan , ödeme yöntemini (BankHeader sınıfının bir parçası) kodlamaya başladım. Kodlamada ilk testi geçmek için sadece kodla uğraştım. Henüz diğer, daha karmaşık senaryolar hakkında düşünmedim.

İlk testi yaptım, testim geçene kadar küçük bir hatayı düzelttim.

Sonra ikinci testi yazmaya başladım, bu sefer bir ödeme indirimi ile çalışarak. Testi yazdıktan sonra indirimleri desteklemek için ödeme yöntemini değiştirdim.

Bir ödeme indirimi ile doğruluğu test ederken, basit ödemeyi de test ettim. Elbette her iki test de geçmelidir.

Sonra daha karmaşık senaryolara doğru ilerledim.

1) Yeni bir senaryo düşünün

2) Bu senaryo için bir test yazın

3) Geçip geçmeyeceğini görmek için o tek testi çalıştırın

4) Yapmasaydı, kodu geçene kadar hata ayıklayıp değiştirirdim.

5) Kodu değiştirirken tüm testleri çalıştırmaya devam ettim

Çok karmaşık ödeme yöntemimi bu şekilde oluşturmayı başardım. Birim testi olmadan kodlamaya nasıl başlayacağımı bilmiyordum, sorun çok zor görünüyordu. Test ile basit bir yöntemle başlayabilir ve daha basit senaryoların hala işe yarayacağına dair güvence ile bunu adım adım genişletebilirim.

Birim testini kullanmanın birkaç gün (veya hafta) kodlamadan tasarruf ettiğinden ve yöntemimin doğruluğunu az çok garanti ettiğinden eminim.

Daha sonra yeni bir senaryo düşünürsem, çalışıp çalışmadığını görmek için onu testlere ekleyebilirim. Değilse, kodu değiştirebilirim, ancak yine de diğer senaryoların doğru şekilde çalıştığından emin olabilirim. Bu, bakım ve hata düzeltme aşamasında günlerden ve günlerden tasarruf sağlayacaktır.

Evet, bir kullanıcı sizin düşünmediğiniz veya yapmasını engellemediğiniz şeyler yaparsa, test edilen kodda bile hatalar olabilir.

Aşağıda, ödeme yöntemimi test etmek için oluşturduğum testlerden bazıları verilmiştir.

public class TestPayments
{
    InvoiceDiaryHeader invoiceHeader = null;
    InvoiceDiaryDetail invoiceDetail = null;
    BankCashDiaryHeader bankHeader = null;
    BankCashDiaryDetail bankDetail = null;



    public InvoiceDiaryHeader CreateSales(string amountIncVat, bool sales, int invoiceNumber, string date)
    {
        ......
        ......
    }

    public BankCashDiaryHeader CreateMultiplePayments(IList<InvoiceDiaryHeader> invoices, int headerNumber, decimal amount, decimal discount)
    {
       ......
       ......
       ......
    }


    [TestMethod]
    public void TestSingleSalesPaymentNoDiscount()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("119", true, 1, "01-09-2008"));
        bankHeader = CreateMultiplePayments(list, 1, 119.00M, 0);
        bankHeader.Save();

        Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
        Assert.AreEqual(1, bankHeader.BankCashDetails[0].Payments.Count);
        Assert.AreEqual(119M, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
        Assert.AreEqual(0M, bankHeader.BankCashDetails[0].Payments[0].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
    }

    [TestMethod]
    public void TestSingleSalesPaymentDiscount()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("119", true, 2, "01-09-2008"));
        bankHeader = CreateMultiplePayments(list, 2, 118.00M, 1M);
        bankHeader.Save();

        Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
        Assert.AreEqual(1, bankHeader.BankCashDetails[0].Payments.Count);
        Assert.AreEqual(118M, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
        Assert.AreEqual(1M, bankHeader.BankCashDetails[0].Payments[0].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
    }

    [TestMethod]
    [ExpectedException(typeof(ApplicationException))]
    public void TestDuplicateInvoiceNumber()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("100", true, 2, "01-09-2008"));
        list.Add(CreateSales("200", true, 2, "01-09-2008"));

        bankHeader = CreateMultiplePayments(list, 3, 300, 0);
        bankHeader.Save();
        Assert.Fail("expected an ApplicationException");
    }

    [TestMethod]
    public void TestMultipleSalesPaymentWithPaymentDiscount()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("119", true, 11, "01-09-2008"));
        list.Add(CreateSales("400", true, 12, "02-09-2008"));
        list.Add(CreateSales("600", true, 13, "03-09-2008"));
        list.Add(CreateSales("25,40", true, 14, "04-09-2008"));

        bankHeader = CreateMultiplePayments(list, 5, 1144.00M, 0.40M);
        bankHeader.Save();

        Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
        Assert.AreEqual(4, bankHeader.BankCashDetails[0].Payments.Count);
        Assert.AreEqual(118.60M, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
        Assert.AreEqual(400, bankHeader.BankCashDetails[0].Payments[1].PaymentAmount);
        Assert.AreEqual(600, bankHeader.BankCashDetails[0].Payments[2].PaymentAmount);
        Assert.AreEqual(25.40M, bankHeader.BankCashDetails[0].Payments[3].PaymentAmount);

        Assert.AreEqual(0.40M, bankHeader.BankCashDetails[0].Payments[0].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[1].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[2].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[3].PaymentDiscount);

        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[1].InvoiceHeader.Balance);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[2].InvoiceHeader.Balance);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[3].InvoiceHeader.Balance);
    }

    [TestMethod]
    public void TestSettlement()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("300", true, 43, "01-09-2008")); //Sales
        list.Add(CreateSales("100", false, 6453, "02-09-2008")); //Purchase

        bankHeader = CreateMultiplePayments(list, 22, 200, 0);
        bankHeader.Save();

        Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
        Assert.AreEqual(2, bankHeader.BankCashDetails[0].Payments.Count);
        Assert.AreEqual(300, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
        Assert.AreEqual(-100, bankHeader.BankCashDetails[0].Payments[1].PaymentAmount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[1].InvoiceHeader.Balance);
    }

1
Birim testinizde bir hata bulundu! Bunlardan birine 2 Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[3].InvoiceHeader.Balance);
eklemek

2
Diyorsunuz: "Test çalıştıktan sonra veritabanına gidip beklediğim şeyin orada olup olmadığını iki kez kontrol ederdim." Bu, sisteminizin bileşenleri arasındaki entegrasyon testinin iyi bir örneğidir - tek bir kod parçasının izole edilmiş birim testi değil.
JTech

2
Ayrıca test başına birden fazla Onaylama kuralını da çiğnediniz.
Steve

13

Gerçekten önemsizlerse, test etme zahmetine girmeyin. Örneğin, bu şekilde uygulanırlarsa;

public class User
{
    public string Username { get; set; }
    public string Password { get; set; }
}

Öte yandan, akıllıca bir şey yapıyorsanız (alıcı / ayarlayıcıda şifreyi şifrelemek ve şifresini çözmek gibi), o zaman bir test yapın.


10

Kural, yazdığınız her mantık parçasını test etmeniz gerektiğidir. Alıcılarda ve ayarlayıcılarda bazı özel işlevler uyguladıysanız, bunların test edilmeye değer olduğunu düşünüyorum. Yalnızca bazı özel alanlara değer atarlarsa, zahmet etmeyin.


6

Bu soru, hangi yöntemlerin test edilip hangilerinin test edilmediğine dair çizginin nereye çekileceği sorusudur.

Değer tahsisi için belirleyiciler ve alıcılar, tutarlılık ve gelecekteki büyüme göz önünde bulundurularak yaratılmıştır ve yolun aşağısında bir süre ayarlayıcı / alıcının daha karmaşık işlemlere dönüşebileceğini öngörmektedir. Tutarlılık ve gelecekteki büyüme adına, bu yöntemlerin birim testlerini yerine koymak mantıklı olacaktır.

Özellikle ek işlevler eklemek için değişiklik yapılırken kod güvenilirliği birincil hedeftir. Test metodolojisine ayarlayıcıları / alıcıları dahil ettiği için hiç kimsenin kovulduğunu bilmiyorum, ancak en son farkında oldukları veya hatırlayabilecekleri basit set / paketler olan yöntemleri test etmelerini isteyen insanlar olduğundan eminim ama bu hayır değildi daha uzun durum.

Belki ekibin başka bir üyesi, şimdi test edilmesi gereken ancak daha sonra testleri oluşturmayan mantığı içerecek şekilde ayar / alma yöntemlerini genişletti. Ancak şimdi kodunuz bu yöntemleri çağırıyor ve bunların değiştiğinin ve derinlemesine testlere ihtiyaç duyduğunun farkında değilsiniz ve geliştirme ve QA'da yaptığınız testler kusuru tetiklemiyor, ancak piyasaya sürüldüğü ilk gündeki gerçek iş verileri tetikleyin.

İki takım arkadaşı şimdi topu kimin düşürdüğünü tartışacak ve başarısız olabilecek ancak bir birim testi kapsamına girmeyen mantığı içerecek şekilde set / morphed edildiğinde birim testleri yapamayacaklar. Başlangıçta seti / kayıtları yazan takım arkadaşı, testler basit set / get'lerde ilk günden itibaren uygulandıysa, bu temizden daha kolay çıkacaktır.

Benim fikrim, TÜM yöntemleri, önemsiz olanlar da dahil olmak üzere, birim testleri ile kapsayan birkaç dakikalık "boşa harcanan" zamanın, günler boyunca baş ağrısından ve işin para / itibar kaybından ve birinin işinin kaybından kurtarabileceği yönünde.

Ve önemsiz yöntemleri birim testlerle sardığınız gerçeği, o genç takım arkadaşı tarafından önemsiz yöntemleri önemsiz yöntemlerle değiştirip testi güncellemelerini istediği zaman görülebilir ve şimdi kimsenin başı belada değildir çünkü kusur içerilmiştir. üretime ulaşmaktan.

Kodlama şeklimiz ve kodumuzdan görülebilen disiplin başkalarına yardımcı olabilir.


4

Başka bir kanonik cevap. Sanırım Ron Jeffries'den:

Yalnızca çalışmak istediğiniz kodu test edin.


3

Standart kodu test etmek zaman kaybıdır, ancak Slavo'nun dediği gibi, alıcılarınıza / ayarlayıcılarınıza bir yan etki eklerseniz, bu işlevselliğe eşlik edecek bir test yazmalısınız.

Test odaklı geliştirme yapıyorsanız, önce sözleşmeyi (örneğin arayüz) yazmalı, ardından beklenen sonuçları / davranışı belgeleyen bu arayüzü kullanmak için testleri yazmalısınız. Ardından birim testlerinizdeki koda dokunmadan yöntemlerinizi kendiniz yazın. Son olarak, bir kod kapsama aracı alın ve testlerinizin kodunuzdaki tüm mantık yollarını uyguladığından emin olun.


3

Özel bir alan belirlemekten daha fazla davranışı olmayan alıcılar ve ayarlayıcılar gibi gerçekten önemsiz kodlar test etmek için gereğinden fazla olur. 3.0'da C # bile, derleyicinin özel alanı ilgilendirdiği bir miktar sözdizimsel şekere sahiptir, böylece bunu programlamanız gerekmez.

Genelde derslerimden beklediğim davranışları doğrulayan çok basit testler yazarım. İki sayı eklemek gibi basit şeyler olsa bile. Basit bir test yazmakla birkaç satır kod yazmak arasında çok geçiş yapıyorum. Bunun nedeni, daha sonra düşünmediğim şeyleri kırmaktan korkmadan kodu değiştirebilmemdir.


KISS prensibini iyi anladığınıza sevindim .. Genellikle 2-3 satır kod gibi, gerçekten küçük, basit testler yaptırırım. Sallaması kolay ve kırılması zor :) + 1'ed
Rob Cooper

3

Her şeyi test etmelisiniz. Şu anda alıcılarınız ve ayarlayıcılarınız var, ancak bir gün onları biraz değiştirebilir, belki doğrulama veya başka bir şey yapabilirsiniz. Bugün yazdığınız testler, her şeyin her zamanki gibi çalıştığından emin olmak için yarın kullanılacaktır. Test yazarken, "şu anda önemsiz" gibi düşünceleri unutmalısınız. Çevik veya test odaklı bir bağlamda, gelecekte yeniden düzenleme yapmayı test etmelisiniz. Ayrıca, çok uzun dizeler veya diğer "kötü" içerikler gibi gerçekten tuhaf değerler koymayı denediniz mi? Pekala ... kodunuzun gelecekte ne kadar kötüye kullanılabileceğini asla tahmin etmemelisiniz.

Genel olarak, kapsamlı kullanıcı testleri yazmanın bir tarafta yorucu olduğunu düşünüyorum. Öte yandan, uygulamanızın nasıl çalışması gerektiği konusunda size her zaman paha biçilmez bir fikir verir ve kolay (ve yanlış) varsayımları atmanıza yardımcı olur (örneğin: kullanıcı adı her zaman 1000 karakterden daha az olacaktır).


3

Bir araç setinde veya açık kaynaklı bir proje türünde yer alabilecek basit modüller için, önemsiz alıcılar ve ayarlayıcılar dahil olmak üzere mümkün olduğunca çok test etmelisiniz. Aklınızda bulundurmanız gereken şey, belirli bir modülü yazarken bir birim testi oluşturmanın oldukça basit ve anlaşılır olmasıdır. Alıcılar ve ayarlayıcılar eklemek minimum koddur ve fazla düşünmeden kullanılabilir. Bununla birlikte, kodunuz daha büyük bir sisteme yerleştirildiğinde, bu ekstra çaba sizi temel sistemdeki, bir temel sınıftaki tür değişiklikleri gibi değişikliklere karşı koruyabilir. Her şeyi test etmek, tam bir gerilemeye sahip olmanın en iyi yoludur.


2

Alıcılarınız ve ayarlayıcılarınız için birim testleri yazmaktan zarar gelmez. Şu anda, sadece başlık altında alan alma / setleri yapıyor olabilirler, ancak gelecekte test edilmesi gereken doğrulama mantığına veya mülkler arası bağımlılıklara sahip olabilirsiniz. Şimdi onu düşünürken yazmak daha kolay, ardından zamanı gelirse güçlendirmeyi hatırlayın.


Peki, alıcılarınızın / ayarlayıcılarınızın birim testlerine ihtiyacı varsa, bunlarla ilişkili bir mantık olması gerekir, bu nedenle mantık içlerine yazılmalıdır, eğer herhangi bir mantıkları yoksa birim testlerinin yazılmasına gerek yoktur.
Pop Catalin

2
Demek istediğim, mantığın onlara daha sonra eklenebileceğidir.
LegendLength

2

genel olarak, bir yöntem yalnızca belirli değerler için tanımlandığında , kabul edilebilir olan sınırın üzerindeki ve üzerindeki değerleri test edin . Başka bir deyişle, yönteminizin yapması gerekeni yaptığından emin olun, ancak daha fazlasını yapmayın . Bu önemlidir, çünkü başarısız olacağınız zaman erken başarısız olmak istersiniz.

Miras hiyerarşilerinde, LSP'yi test ettiğinizden emin olun uyumluluğunu .

Varsayılan alıcıları ve ayarlayıcıları test etmek, daha sonra bazı doğrulama yapmayı planlamıyorsanız, benim için pek kullanışlı görünmüyor.


2

Eğer kırılabileceğini düşünüyorsanız, bunun için bir test yazın. Genellikle ayarlayıcı / alıcıyı test etmiyorum, ancak Kullanıcı için bir tane oluşturduğunuzu söyleyelim, adı ve soyadını birleştiren, bir test yazardım, böylece biri soyadını ve adını değiştirirse, en azından bilirdi test edilen bir şeyi değiştirdi.


2

Kanonik cevap, "kırılabilecek her şeyi test et" dir. Özelliklerin bozulmayacağından eminseniz, onları test etmeyin.

Ve bir şeyin kırıldığı tespit edildiğinde (bir hata bulduğunuzda), açıkça onu test etmeniz gerektiği anlamına gelir. Hatayı yeniden oluşturmak için bir test yazın, başarısız olduğunu izleyin, ardından hatayı düzeltin ve ardından testin geçmesini izleyin.


1

Çevik geliştirme bağlamındaki birim testlerini anladığıma göre, Mike, evet, alıcıları ve ayarlayıcıları test etmeniz gerekiyor (herkesin görebileceği varsayılarak). Birim testi kavramının tamamı, bu durumda bir sınıf olan yazılım birimini kara kutu olarak test etmektir . Alıcılar ve ayarlayıcılar dışarıdan görünür olduklarından, onları Kimlik Doğrulama ve Kaydet ile birlikte test etmeniz gerekir.


1

Kimlik Doğrulama ve Kaydetme yöntemleri özellikleri kullanıyorsa, testleriniz dolaylı olarak özelliklere dokunacaktır. Mülkler yalnızca verilere erişim sağladığı sürece, açık testler gerekli olmamalıdır (% 100 kapsama için gitmediğiniz sürece).


1

Alıcılarınızı ve ayarlayıcılarınızı test ederdim. Kodu kimin yazdığına bağlı olarak, bazı insanlar alıcı / ayarlayıcı yöntemlerinin anlamını değiştirir. Alıcı yöntemlerinin bir parçası olarak değişken başlatma ve diğer doğrulamaları gördüm. Bu tür şeyleri test etmek için, bu kodu açıkça kapsayan birim testleri istersiniz.


1

Şahsen ben "kırılabilecek her şeyi test ederdim" ve basit alıcı (veya daha iyi oto özellikleri) bozulmaz. Hiçbir zaman basit bir dönüş ifadesinin başarısız olmadı ve bu nedenle onlar için asla test etmedim. Alıcıların kendi içlerinde hesaplamaları veya başka tür ifadeler varsa, kesinlikle onlar için testler eklerim.

Kişisel olarak Moq'u sahte bir nesne çerçevesi olarak kullanıyorum ve ardından nesnemin etraftaki nesneleri olması gerektiği gibi çağırdığını doğruluyorum.


1

Sınıfın her yönteminin yürütülmesini UT ile ele almalı ve yöntem dönüş değerini kontrol etmelisiniz. Bu, alıcıları ve ayarlayıcıları içerir, özellikle üyelerin (özelliklerin), başlatılmaları sırasında büyük bellek tahsisi gerektiren karmaşık sınıflar olması durumunda. Ayarlayıcıyı örneğin çok büyük bir dizeyle (veya yunan sembolleri içeren bir şeyle) çağırın ve sonucun doğru olup olmadığını kontrol edin (kesilmemiş, kodlama iyi vb.)

Aynı zamanda geçerli olan basit tamsayılar durumunda - tamsayı yerine uzun geçerseniz ne olur? UT yazmanızın nedeni bu :)


1

Özelliklerin gerçek ayarını test etmem. Bu mülklerin tüketici tarafından nasıl doldurulduğu ve neyle doldurulduğu konusunda daha çok endişeleniyorum. Herhangi bir testte riskleri testin süresi / maliyeti ile tartmanız gerekir.


1

Olabildiğince birim testleri kullanarak "önemsiz olmayan her kod bloğunu" test etmelisiniz.

Mülkleriniz önemsizse ve birisinin içinde bir hata oluşturması olası değilse, onları birim test etmemek güvenli olmalıdır.

Authenticate () ve Save () yöntemleriniz test için iyi adaylar gibi görünüyor.


1

İdeal olarak, dersi yazarken birim testlerinizi yapardınız. Test Driven Development'ı kullanırken bunu böyle yapmanız gerekiyor. Testleri, her bir fonksiyon noktasını uygularken eklersiniz ve uç durumları da test ile kapladığınızdan emin olursunuz.

Sonrasında testleri yazmak çok daha acı verici ama yapılabilir.

İşte senin pozisyonunda yapacağım şey:

  1. Temel işlevi test eden temel bir test seti yazın.
  2. NCover'ı edinin ve testlerinizde çalıştırın. Bu noktada test kapsamınız muhtemelen% 50 civarında olacaktır.
  3. Yaklaşık% 80 -% 90 kapsama alanı elde edene kadar uç durumlarınızı kapsayan testler eklemeye devam edin

Bu size gerilemelere karşı iyi bir tampon görevi görecek güzel çalışan bir dizi birim testi sağlamalıdır.

Bu yaklaşımla ilgili tek sorun, kodun tasarlanması gerektiğidir. şekilde test edilebilir gerektiğidir. Erken herhangi bir bağlantı hatası yaptıysanız, çok kolay bir şekilde yüksek kapsama alanı elde edemezsiniz.

Bu yüzden kodu yazmadan önce testleri yazmanız gerçekten önemlidir. Sizi gevşek bağlı kod yazmaya zorlar.


1

Açıkça çalışan (standart) kodu test etmeyin. Bu nedenle, ayarlayıcılarınız ve alıcılarınız yalnızca "özellik değeri = değer" ve "dönüş özellik değeri" ise, test etmenin bir anlamı yoktur.


1

Get / set bile nasıl uygulandıklarına bağlı olarak tuhaf sonuçlar doğurabilir, bu nedenle bunlar yöntem olarak ele alınmalıdır.

Bunların her testinin, aramaların beklenen şekilde geri dönmesini / başarısız olmasını sağlamak için hem kabul edilebilir hem de kabul edilemez özellikleri tanımlayarak özellikler için parametre setlerini belirlemesi gerekecektir.

Ayrıca, örnek bir SQL enjeksiyonu olarak güvenlik sorunlarının farkında olmanız ve bunları test etmeniz gerekir.

Yani evet, özellikleri test etme konusunda endişelenmeniz gerekiyor.


1

Alıcıları ve ayarlayıcıları sadece basit bir işlem yaptıklarında test etmenin aptalca olduğuna inanıyorum. Kişisel olarak, herhangi bir kullanım modelini kapsayacak şekilde karmaşık birim testleri yazmıyorum. Normal yürütme davranışını ve aklıma gelen tüm hata durumlarını ele aldığımdan emin olmak için yeterince test yazmaya çalışıyorum. Hata raporlarına yanıt olarak daha fazla birim testi yazacağım. Kodun gereksinimleri karşıladığından emin olmak ve gelecekteki değişiklikleri kolaylaştırmak için birim testi kullanıyorum. Bir şeyi kırarsam bir testin başarısız olacağını bildiğimde kodu değiştirmeye çok daha istekli hissediyorum.


1

GUI arayüzünün dışında test edilebilecek kod yazdığınız her şey için bir test yazardım.

Tipik olarak, başka bir katman veya iş mantığı katmanına yerleştirdiğim herhangi bir iş mantığına sahip yazdığım herhangi bir mantık.

O zaman bir şey yapan her şey için test yazmak kolaydır.

İlk geçişte, "İş Mantığı Katmanınızdaki" her genel yöntem için bir birim testi yazın.

Böyle bir dersim olsaydı:

   public class AccountService
    {
        public void DebitAccount(int accountNumber, double amount)
        {

        }

        public void CreditAccount(int accountNumber, double amount)
        {

        }

        public void CloseAccount(int accountNumber)
        {

        }
    }

Bu eylemleri gerçekleştirmem gerektiğini bilerek herhangi bir kod yazmadan önce yapacağım ilk şey, birim testleri yazmaya başlamak olurdu.

   [TestFixture]
    public class AccountServiceTests
    {
        [Test]
        public void DebitAccountTest()
        {

        }

        [Test]
        public void CreditAccountTest()
        {

        }

        [Test]
        public void CloseAccountTest()
        {

        }
    }

Bir şeyler yapmak için yazdığınız kodu doğrulamak için testlerinizi yazın. Bir şeyler koleksiyonunu yinelerseniz ve her biri hakkında bir şeyi değiştirirseniz, aynı şeyi yapan bir test yazın ve gerçekte olanı iddia edin.

Behavoir Driven Development (BDD) adında alabileceğiniz birçok başka yaklaşım var, bu daha kapsamlı ve birim test becerilerinizle başlamak için harika bir yer değil.

Öyleyse, hikayenin ahlaki, endişelenebileceğiniz herhangi bir şeyi test edin, birim testleri küçük boyutlu belirli şeyleri test etmeye devam edin, birçok test iyidir.

İş mantığınızı Kullanıcı Arayüzü katmanının dışında tutun, böylece onlar için kolayca testler yazabilirsiniz ve iyi olursunuz.

TestDriven.Net veya ReSharper'ı her ikisi de Visual Studio'ya kolayca entegre edilebileceği için öneriyorum .


1

Kimlik Doğrulama ve Kaydetme yöntemleriniz için birden çok test yazmanızı tavsiye ederim. Başarı durumuna ek olarak (tüm parametrelerin sağlandığı, her şeyin doğru yazıldığı, vb.), Çeşitli hata durumları (yanlış veya eksik parametreler, varsa kullanılamayan veritabanı bağlantıları, vb.) İçin testler yaptırmak iyidir. C # ile NUnit ile Pragmatik Birim Testini öneririmReferans olarak .

Diğerlerinin de belirttiği gibi, alıcılarınız ve ayarlayıcılarınızda koşullu mantık olmadığı sürece alıcılar ve ayarlayıcılar için birim testleri aşırıdır.


1

Kodunuzun nerede test edilmesi gerektiğini doğru bir şekilde tahmin etmek mümkün olsa da, genellikle bu tahmini desteklemek için metriklere ihtiyacınız olduğunu düşünüyorum. Benim görüşüme göre birim testi, kod kapsamı ölçütleriyle el ele gider.

Çok sayıda test içeren kodlayın, ancak küçük bir kapsam iyi test edilmemiştir. Bununla birlikte,% 100 kapsama alanına sahip ancak sınırlamaları ve hata durumlarını test etmeyen kodlar da harika değildir.

Yüksek kapsam (minimum% 90) ve değişken girdi verileri arasında bir denge istiyorsunuz.

"Çöp girişini" test etmeyi unutmayın!

Ayrıca, bir birim testi, bir arıza olup olmadığını kontrol etmediği sürece bir birim testi değildir. İddiaları olmayan veya bilinen istisnalarla işaretlenmiş birim testleri, kodun çalıştırıldığında ölmediğini test edecektir!

Testlerinizi, her zaman hataları veya beklenmeyen / istenmeyen verileri rapor edecek şekilde tasarlamanız gerekir!


1

Kodumuzu daha iyi yapar ... nokta!

Yazılım geliştiricilerin test odaklı geliştirme yaparken unuttuğumuz bir şey, eylemlerimizin arkasındaki amaçtır. Üretim kodu zaten yerleştirildikten sonra bir birim testi yazılıyorsa, testin değeri çok düşer (ancak tamamen kaybolmaz).

Birim testinin gerçek ruhunda, bu testler öncelikle kodumuzun daha fazlasını "test etmek" için orada değildir ; veya% 90 -% 100 daha iyi kod kapsamı elde etmek için. Tüm bunlar, önce testleri yazmanın yan faydalarıdır . En büyük kazanç, üretim kodumuzun doğal TDD süreci nedeniyle çok daha iyi yazılmasıdır.

Bu fikrin daha iyi iletilmesine yardımcı olmak için aşağıdakiler okumaya yardımcı olabilir:

Birim Testlerinin Hatalı Teorisi
Amaçlı Yazılım Geliştirme

Daha fazla birim test yazma eyleminin daha yüksek kaliteli bir ürün elde etmemize yardımcı olduğunu hissedersek , o zaman bir Kargo Test Odaklı Geliştirme Kültünden muzdarip olabiliriz .


Üretim kodu zaten yerleştirildikten sonra birim testlerinin değerinin olmadığı iddiasına katılmıyorum. Bu tür iddialar, üretimde bulunan hata koşullarının kopyalanmasında veya önceki bir geliştiriciden veya takımdan devralınan kodun anlaşılmasındaki faydalarını hesaba katmaz.
Scott Lawrence

Yanlış görmüş olabilirim. Üretim kodu yerleştirildikten sonra birim testlerin bir değeri olmadığını söylemedim. Ancak değerleri düşer. Birim testinin en büyük yararı, üretim geliştirmemizi yönlendirmelerine izin verdiğimizde ortaya çıkan doğal sihirden gelir.
Scott Saad
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.