Ünite testi nasıl çalışır?


23

Kodumu daha sağlam hale getirmeye çalışıyorum ve birim testi hakkında okudum, ancak gerçek bir kullanışlı kullanım bulmak çok zor. Örneğin, Wikipedia örneği :

public class TestAdder {
    public void testSum() {
        Adder adder = new AdderImpl();
        assert(adder.add(1, 1) == 2);
        assert(adder.add(1, 2) == 3);
        assert(adder.add(2, 2) == 4);
        assert(adder.add(0, 0) == 0);
        assert(adder.add(-1, -2) == -3);
        assert(adder.add(-1, 1) == 0);
        assert(adder.add(1234, 988) == 2222);
    }
}

Bu testin tamamen işe yaramaz olduğunu hissediyorum, çünkü istenen sonucu manuel olarak hesaplamanız ve test etmeniz gerekiyor, burada daha iyi bir birim testi gibi hissediyorum.

assert(adder.add(a, b) == (a+b));

ama o zaman bu sadece testte işlevin kendisini kodlar. Birisi bana birim testinin gerçekten yararlı olduğu bir örnek verebilir mi? FYI Halen ~ 10 boolean ve birkaç inç alan ve bana bu konuda bir int sonuç veren çoğunlukla "usule uygun" fonksiyonları kodluyorum, yapabileceğim tek ünite testinde sadece algoritmayı yeniden kodlamak olacağını hissediyorum Ölçek. düzenleme: Ben de bunu yapmalıydım (muhtemelen kötü tasarlanmış) yakut kodunu taşımadım (yapmadığım)


14
How does unit testing work?Kimse gerçekten bilmiyor :)
yannis

30
msgstr "İstenen sonucu elle hesaplamanız gerekiyor". Bu nasıl "tamamen işe yaramaz"? Cevabın doğru olduğundan başka nasıl emin olabilirsin ?
S.Lott

9
@ S.Lott: Eski zamanlarda insanlar sayıları ezmek ve zaman kazanmak için bilgisayar kullanıyorlardı, modern günlerde insanlar sayıları ezmek için zaman harcıyorlar: D
Coder

2
@Coder: Birim testinin amacı "sayıları sıkmak ve zaman kazanmak" değildir);)
Andres F.

7
@lezebulon: Wikipedia'dan örnek çok iyi değil, ancak bu test durumuyla ilgili, genel olarak birim testiyle ilgili bir sorun. Örnekteki test verilerinin yaklaşık yarısı yeni bir şey eklemiyor, gereksiz hale getiriyor (testin yazarının daha karmaşık senaryolarla ne yapabileceğini düşünmekten korkuyorum). Daha anlamlı bir test, test verilerini en azından aşağıdaki senaryolarda bölümlere ayırır: "negatif sayılar ekleyebilir mi?", "Sıfır nötr mü?", "Negatif ve pozitif sayılar ekleyebilir mi?".
Andres F.

Yanıtlar:


26

Ünite testleri, yeterince küçük üniteleri test ediyorsanız, her zaman kör edici olduğunu açıkça ortaya koyar.

add(x, y)Birim bir testten bile söz edilmesinin sebebi , bir süre sonra birisinin girip add, eklemenin her yerde kullanıldığının farkına varmadan özel bir vergi mantığı işleme kodu koyacağıdır.

Birim testleri , birleşme prensibi hakkında çok fazla şey ifade eder: A, B ve B, C yaptığı takdirde, A, C'yi yapar. "A, C", daha üst seviye bir testtir. Örneğin, aşağıdaki meşru iş kodunu göz önünde bulundurun:

public void LoginUser (string username, string password) {
    var user = db.FetchUser (username);

    if (user.Password != password)
        throw new Exception ("invalid password");

    var roles = db.FetchRoles (user);

    if (! roles.Contains ("member"))
        throw new Exception ("not a member");

    Session["user"] = user;
}

İlk bakışta bu, ünite testi için harika bir yöntem gibi gözüküyor, çünkü çok net bir amacı var. Ancak, yaklaşık 5 farklı şey yapar. Her şeyin geçerli ve geçersiz bir durumu vardır ve birim testlerinde devasa bir permütasyon gerçekleştirir. İdeal olarak bu daha da bozulur:

public void LoginUser (string username, string password) {

    var user = _userRepo.FetchValidUser (username, password);

    _rolesRepo.CheckUserForRole (user, "member");

    _localStorage.StoreValue ("user", user);
}

Şimdi birimlere düştük. Bir ünite testi neyin _userRepogeçerli davranış olarak kabul FetchValidUserettiği ile ilgili değil, sadece onunla ilgilenir . Geçerli bir kullanıcının tam olarak neyi oluşturduğundan emin olmak için başka bir test kullanabilirsiniz. Benzer şekilde CheckUserForRole... testinizi Rol yapısının nasıl göründüğünü bilmekten aldınız. Ayrıca tüm programınızı kesinlikle bağlı kalmanızdan aldınız Session. Buradaki tüm kayıp parçaları şöyle görünür:

class UserRepository : IUserRepository
{
    public User FetchValidUser (string username, string password)
    {
        var user = db.FetchUser (username);

        if (user.Password != password)
            throw new Exception ("invalid password");

        return user;
    }
}

class RoleRepository : IRoleRepository
{
    public void CheckUserForRole (User user, string role)
    {
        var roles = db.FetchRoles (user);

        if (! roles.Contains (role))
            throw new Exception ("not a member");
    }
}

class SessionStorage : ILocalStorage
{
    public void StoreValue (string key, object value)
    {
        Session[key] = value;
    }
}

Yenileme yaparak, aynı anda birkaç şey başardınız. Program, altta yatan yapıların ayrılmasını (NoSQL için veritabanı katmanını daraltabilirsiniz) ayırmayı veya Sessioniş parçacığı güvenli ya da her neyse, bir kez daha sorunsuz bir şekilde kilitlemeyi eklemeyi desteklemektedir . Ayrıca şimdi bu üç bağımlılık için yazma konusunda kendinize çok açık testler yaptınız.

Bu yardımcı olur umarım :)


13

Şu anda çoğunlukla ~ 10 boolean ve bir kaç inç alan ve "bunun sonucunda bir int sonuç veren" prosedürel "fonksiyonları kodluyorum, yapabileceğim tek ünite testi sadece testteki algoritmayı yeniden kodlamak gibi hissediyorum

Prosedürel işlevlerinizden her birinin deterministik olduğundan eminim, bu nedenle verilen her bir giriş değeri kümesi için belirli bir int sonucu döndürür. İdeal olarak, belirli girdi değerleri setleri için hangi sonucu almanız gerektiğini çözebileceğiniz fonksiyonel bir spesifikasyon olacaktır. Bunun olmaması durumunda, belirli girdi değerleri için ruby ​​kodunu (doğru çalıştığı tahmin edilir) çalıştırabilir ve sonuçları kaydedebilirsiniz. O zaman, sonuçları SABİT KORUMA testine almanız gerekir. Testin, kodunuzun gerçekten de doğru olduğu bilinen sonuçlar ürettiğinin bir kanıtı olması gerekiyor .


Mevcut kodu çalıştırmak ve sonuçları kaydetmek için +1. Bu durumda, muhtemelen pragmatik yaklaşım budur.
MarkJ

12

Çünkü başka hiç kimse gerçek bir örnek vermemiş gibi görünüyor:

    public void testRoman() {
        RomanNumeral numeral = new RomanNumeral();
        assert( numeral.toRoman(1) == "I" )
        assert( numeral.toRoman(4) == "IV" )
        assert( numeral.toRoman(5) == "V" )
        assert( numeral.toRoman(9) == "IX" )
        assert( numeral.toRoman(10) == "X" )
    }
    public void testSqrt() {
        assert( sqrt(4) == 2 )
        assert( sqrt(9) == 3 )
    }

Diyorsun:

Bu testin tamamen yararsız olduğunu hissediyorum çünkü istenen sonucu manuel olarak hesaplamanız ve test etmeniz gerekiyor

Ancak mesele şu ki, manuel hesaplamalar yaparken kodlama yaparken hata yapma (veya en azından hatalarınızı farketme olasılığınız) çok daha düşüktür.

Roma dönüşüm kodunu ondalık basamağınızda bir hata yapma olasılığı nedir? Oldukça muhtemel. El ile ondalık sayıyı el ile sayıya dönüştürürken hata yapma olasılığınız nedir? Pek olası değil. Bu yüzden manuel hesaplamalara karşı test yapıyoruz.

Karekök işlevini uygularken hata yapma olasılığınız nedir? Oldukça muhtemel. Elle bir karekök hesaplarken hata yapma olasılığınız nedir? Muhtemelen daha muhtemel. Ancak sqrt ile cevapları almak için bir hesap makinesi kullanabilirsiniz.

FYI Halen ~ 10 boolean ve birkaç inç alan ve bana bu konuda bir int sonuç veren çoğunlukla "usule uygun" fonksiyonları kodluyorum, yapabileceğim tek ünite testinde sadece algoritmayı yeniden kodlamak olacağını hissediyorum Ölçek

Bu yüzden burada neler olduğu hakkında spekülasyon yapacağım. İşlevleriniz oldukça karmaşık, bu nedenle girdilerden çıkışın ne olması gerektiğini anlamak zor. Bunu yapabilmek için, çıktının ne olduğunu bulmak için fonksiyonu (kafanızda) manuel olarak uygulamanız gerekir. Anlaşılır, bu biraz işe yaramaz ve hataya açık görünüyor.

Anahtar, doğru çıktıları bulmak istediğiniz olmasıdır. Ancak bu çıktıları doğru olduğu bilinen bir şeye karşı test etmeniz gerekir. Bunu hesaplamak için kendi algoritmanızı yazmanın faydası yok çünkü bu çok iyi bir yanlışlık olabilir. Bu durumda değerleri elle hesaplamak çok zor.

Yakut koduna geri döner ve bu orijinal fonksiyonları çeşitli parametrelerle yürütürdüm. Yakut kodun sonuçlarını alıp, birim testine koyardım. Bu şekilde manuel hesaplamayı yapmanız gerekmez. Ancak orijinal koda karşı test yapıyorsunuz. Bu sonuçların aynı kalmasına yardımcı olmalı, ancak orijinalinde hatalar varsa size yardımcı olmayacaktır. Temel olarak, orijinal kodu sqrt örneğinde hesap makinesi gibi kullanabilirsiniz.

Taşımakta olduğunuz kodu gösterirseniz, soruna nasıl yaklaşılacağı konusunda daha ayrıntılı geri bildirimde bulunabiliriz.


Ve eğer Ruby kodunun yeni kodunuzda olmadığını bilmediğiniz bir hata varsa ve kodunuz Ruby çıktılarını temel alan bir birim testinde başarısız olursa, neden başarısız olduğuna dair araştırma sonuçta sizi haklı çıkarır ve sonuç olarak gizli Ruby hata bulundu. Yani bu oldukça havalı.
Adam Wuerl

11

Yapabileceğim tek ünite testi, testteki algoritmayı tekrar kodlamak gibi olacak gibi hissediyorum

Bu kadar basit bir sınıf için neredeyse haklısın.

Daha karmaşık bir hesap makinesi için deneyin .. Bir bowling puanı hesap makinesi gibi.

Birim testlerinin değeri, test edilecek farklı senaryolara sahip daha karmaşık "iş" kurallarınız olduğunda daha kolay görülür.

Değirmen hesap makinesinin bir çalışmasını test etmemeniz gerektiğini söylemiyorum (Hesap makineniz 1/3 gibi değerlerle gösterilemiyor mu? Sıfırla bölmeyle ne işe yarıyor?) kapsama almak için daha fazla dallı bir şeyi test ediyorsanız daha net bir şekilde değer verin.


4
Dikkat etmek için +1, karmaşık fonksiyonlar için daha kullanışlı hale gelir. Adder.add () öğesini kayan nokta değerlerine genişletmeye karar verirseniz ne olur? Matrisler? Leger hesap değerleri?
joshin4colours

6

% 100 kod kapsamındaki dindar zealotriye rağmen, her yöntemin birim test edilmemesi gerektiğini söyleyeceğim. Yalnızca anlamlı iş mantığı içeren işlevler. Basitçe sayı ekleyen bir fonksiyonun test edilmesi anlamsızdır.

Şu anda çoğunlukla ~ 10 boolean ve bir kaç inç alan ve bana dayanan int sonucunu veren "usule uygun" fonksiyonları kodluyorum.

İşte asıl problemin burada. Birim testi doğal olmayan bir şekilde zor veya anlamsız görünüyorsa, tasarım hatası nedeniyle muhtemeldir. Daha fazla nesne yönelimli olsaydı, yöntem imzalarınız o kadar büyük olmazdı ve test edilecek daha az girdi vardı.

OO'ma girmeme gerek yok, prosedürel programlamaya göre daha üstün ...


Bu durumda, yöntemin "imzası" büyük değildir, sadece bir sınıf üyesi olan std :: vector <bool> 'dan okudum. Ayrıca (muhtemelen kötü tasarlanmış) yakut kodunu (yapmadığım)
taşıdığımı da söylemeliydim

2
@lezebulon Tek bir yöntem için kabul etmek için olası birçok girdi varsa, o zaman o yöntemi çok fazla yapıyor demektir .
maple_shaft

3

Benim bakış açıma göre, ünite testleri küçük engerek sınıfınızda bile kullanışlıdır: algoritmayı "yeniden kodlamayı" düşünmeyin ve bunu bildiğiniz tek bilginin bulunduğu kara bir kutu olarak düşünün (eğer alışkınsanız) hızlı çarpma ile, daha hızlı bilirsiniz, ancak "a * b") ve genel arayüzünüzü kullanmaktan daha karmaşık denemeler yaparsınız. Kendine "Neyin ters gidebilir ki?" Diye sormalısın.

Çoğu durumda sınırda olur (bu kalıpları zaten eklemeye çalıştığınızı test ediyorum ++, -, + -, 00 - - -, 0+, 0-, +0, -0. MAX_INT ve MIN_INT'te orada eklerken veya çıkarırken (negatif eklerken) neler olduğunu düşünün. Veya sınamalarınızın sıfıra yakın ve tam olarak ne olduğuna tam olarak bakmasını sağlamaya çalışın.

Sonuçta sır, basit sınıflar için çok basit (belki de daha karmaşık olanlar için);): sınıfınızın sözleşmelerini düşünün (sözleşmeye göre tasarıma bakın) ve sonra onlara karşı test edin. Faturalarınızı ne kadar iyi tanırsanız, sınav öncesi ve sonrası sınavlarınız "tamamlayıcı" olacaktır.

Test sınıflarınız için ipucu: Bir yöntemde yalnızca bir tane eşlik yazmayı deneyin. Kod değiştirdikten sonra testiniz başarısız olduğunda en iyi geri bildirimi almak için yöntemlere iyi adlar verin (ör. "TestAddingToMaxInt", "testAddingTwoNegatives").


2

El ile hesaplanmış bir dönüş değeri test etmek veya beklenen dönüş değerini hesaplamak için testte mantığı çoğaltmak yerine, beklenen bir özellik için dönüş değerini test edin.

Örneğin, bir matrisi tersine çeviren bir yöntemi test etmek istiyorsanız, giriş değerinizi el ile ters çevirmek istemezseniz, dönüş değerini girişle çarpmanız ve kimlik matrisini aldığınızı kontrol etmeniz gerekir.

Bu yaklaşımı yönteminize uygulamak için, dönüş değerinin girdilere göre hangi özelliklere sahip olacağını belirlemek için amacını ve anlamını göz önünde bulundurmanız gerekir.


2

Birim testleri bir verimlilik aracıdır. Bir değişiklik isteği alırsınız, uygularsınız, sonra kodunuzu birim test gambitinde çalıştırın. Bu otomatik test zaman kazandırır.

I feel that this test is totally useless, because you are required to manually compute the wanted result and test it, I feel like a better unit test here would be

Bir görüş noktası. Örnekteki test, bir sınıfın nasıl başlatılacağını ve bir dizi test boyunca nasıl çalıştırılacağını gösterir. Tek bir uygulamanın önemsizliğine odaklanmak, ağaçlar için ormanı kaçırıyor.

Can someone provide me with an example where unit testing is actually useful?

Bir Çalışan varlığınız var. Varlık bir ad ve adres içeriyor. İstemci bir ReportsTo alanı eklemeye karar verir.

void TestBusinessLayer()
{
   int employeeID = 1234
   Employee employee = Employee.GetEmployee(employeeID)
   BusinessLayer bl = new BusinessLayer()
   Assert.isTrue(bl.Add(employee))//assume Add returns true on pass
}

Bu, bir çalışanla çalışmak için BL'nin temel bir testidir. Kod, az önce yaptığınız şema değişikliğini geçecek / başarısız olacaktır. Unutma, testin yaptığı tek şey bu değil. Kodun üzerinden geçmek ayrıca istisnaların kabarık olmamasını da sağlar.

Zamanla, testleri yerinde yapmak, genel olarak değişiklik yapmayı kolaylaştırır. Kod istisnalar ve yaptığınız iddialara karşı otomatik olarak test edilir. Bu, bir QA grubunun manuel testiyle yapılan ek yüklerin çoğundan kaçınır. Kullanıcı arayüzünü otomatikleştirmek hala oldukça zor olmakla birlikte, diğer katmanlar erişim değiştiricileri doğru kullandığınızı varsayarsak genellikle çok kolaydır.

I feel like the only unit testing I could do would be to simply re-code the algorithm in the test.

İşlemsel mantık bile bir fonksiyonun içine kolayca yerleştirilebilir. Kapsülleyin, örneklendirin ve test edilecek int / ilkelden geçirin (veya sahte nesne). Kodu bir Birim Testine yapıştırmayın. Bu DRY'yi yener. Ayrıca, kodu tamamen test etmediğinizden, ancak kodun bir kopyasından dolayı testi tamamen kaybeder. Test edilmesi gereken kod değişirse, test yine de geçer!


<pedantry> "gamut", "gambit" değil. </
pedantry

@chao lol her gün yeni bir şey öğrenmek.
P.Brian.Mackey

2

Örneğinizi alarak (bir miktar yeniden düzenleme ile),

assert(a + b, math.add(a, b));

yardımcı olmuyor:

  • math.addDahili olarak nasıl davrandığını anlamak ,
  • Kenar davalarında ne olacağını biliyorum.

Söylediği gibi oldukça:

  • Eğer yöntem ne yaptığını bilmek istiyorsanız, gidip (evet, çünkü kendinizi kaynak kod satır yüzlerce görmek math.add edebilir ; aşağıya bakınız LOC yüzlerce içerir).
  • Yöntemin doğru çalışıp çalışmadığını bilmek istemiyorum. Beklenen ve gerçek değerlerin gerçekten beklediğimden farklı olması sorun değil .

Bu ayrıca, aşağıdaki gibi testler eklemeniz gerekmediği anlamına gelir:

assert(3, math.add(1, 2));
assert(4, math.add(2, 2));

İlk iddiada bulunduklarında, ya da en azından bir kez yardımcı olmazlar, ikincisi işe yarar bir şey getirmez.

Bunun yerine, ne hakkında:

const numeric Pi = 3.1415926535897932384626433832795;
const numeric Expected = 4.1415926535897932384626433832795;
assert(Expected, math.add(Pi, 1),
    "Adding an integer to a long numeric doesn't give a long numeric result.");
assert(Expected, math.add(1, Pi),
    "Adding a long numeric to an integer doesn't give a long numeric result.");

Bu kendi kendini açıklayıcıdır ve hem sizin hem de kaynak kodunu daha sonra koruyacak olan kişi için çok faydalıdır. Bu kişinin math.addkodu basitleştirmek ve performansı optimize etmek için küçük bir değişiklik yaptığını ve aşağıdaki gibi test sonucunu gördüğünü hayal edin :

Test TestNumeric() failed on assertion 2, line 5: Adding a long numeric to an
integer doesn't give a long numeric result.

Expected value: 4.1415926535897932384626433832795
Actual value: 4

bu kişi derhal yeni değiştirilen yöntemin argümanların sırasına bağlı olduğunu anlayacaktır: ilk argüman bir tamsayı ve ikincisi uzun bir sayısal ise, sonuç bir tamsayı olurken, uzun bir sayısal bekleniyordu.

Aynı şekilde, 4.141592ilk iddiadaki gerçek değeri elde etmek kendi kendini açıklayıcı niteliktedir : yöntemin büyük bir hassasiyetle başa çıkmasının beklendiğini biliyorsunuz , ancak aslında başarısız oluyor.

Aynı nedenden ötürü, aşağıdaki iki iddia bazı dillerde anlamlı olabilir:

// We don't expect a concatenation. `math` library is not intended for this.
assert(0, math.add("Hello", "World"));

// We expect the method to convert every string as if it was a decimal.
assert(5, math.add("0x2F", 5));

Ayrıca, ne hakkında:

assert(numeric.Infinity, math.add(numeric.Infinity, 1));

Kendinden açıklamalı: Metodunuzun sonsuzluğa doğru şekilde baş edebilmesini istersiniz. Devam sonsuz ötesinde veya istisna atan beklenen bir davranış değildir.

Ya da belki, dilinize bağlı olarak, bu daha mantıklı olur?

/**
 * Ensures that when adding numbers which exceed the maximum value, the method
 * fails with OverflowException, instead of restarting at numeric.Minimum + 1.
 */
TestOverflow()
{
    UnitTest.ExpectException(ofType(OverflowException));

    numeric result = math.add(numeric.Maximum, 1));

    UnitTest.Fail("The tested code succeeded, while an OverflowException was
        expected.");
}

1

Ekleme gibi çok basit bir işlev için test yapmak gereksiz olabilir, ancak işlevleriniz daha karmaşık hale geldikçe, test etmenin neden gerekli olduğu gittikçe daha belirgin hale gelir.

Programlama yaparken ne yaptığınızı düşünün (ünite testi olmadan). Genellikle bir kod yazar, çalıştırır, çalıştığını görür ve bir sonraki şeye geçersiniz, değil mi? Daha fazla kod yazarken, özellikle çok büyük bir sistemde / GUI / web sitesinde, "çalışıp çalışıp çalışmadığını görmek" konusunda daha fazla şey yapmanız gerektiğini görürsünüz. Bunu denemek ve denemek zorundasın. Daha sonra birkaç değişiklik yapın ve aynı şeyleri tekrar denemelisiniz. “Çalışıp çalışıp çalışmadığını görmek” kısmını otomatikleştiren ünite testleri yazarak zaman kazanabileceğiniz çok açık bir hale geldi.

Projeleriniz büyüdükçe büyüdükçe, "koşup çalışıp çalışmadığını görmek zorunda" sayılarınız gerçekçi olmaz. Böylece sadece GUI / projenin birkaç ana bileşenini çalıştırıp deniyor ve ardından her şeyin yolunda gitmesini umuyorsunuz. Bu felaket için bir reçetedir. Elbette siz, bir insan olarak, GUI kelimenin tam anlamıyla yüzlerce kişi tarafından kullanılıyorsa, müşterilerinizin kullanabileceği her olası durumu defalarca test edemezsiniz. Ünite testleri yaptırdıysanız, testi kararlı sürümü çıkarmadan önce ya da merkezi bir depoya koymadan önce (işyerinizde bir tane kullanıyorsa) çalıştırabilirsiniz. Ve daha sonra bulunan herhangi bir hata varsa, gelecekte kontrol etmek için bir ünite testi ekleyebilirsiniz.


1

Ünite testlerinin yazılmasının yararlarından biri, sizi ileri durumlar hakkında düşünmeye zorlayarak daha sağlam kod yazmanıza yardımcı olmasıdır. Tamsayı taşması, ondalık kesme ya da parametreler için boş değerlerin kullanılması gibi bazı uç durumlarda test etmeye ne dersiniz?


0

Belki add () 'in ADD talimatıyla uygulandığını varsayıyorsunuzdur. Küçük bir programcı veya donanım mühendisi, ANDS / ORS / XORS, bit ters çevirmeleri ve kaymaları kullanarak add () işlevini yeniden uyguladıysa, ADD komutuna karşı test etmek isteyebilirsiniz.

Genel olarak, add () veya test altındaki birimi, rasgele bir sayı veya çıktı üreteci ile değiştirirseniz, bir şeyin kırıldığını nasıl bilebilirdiniz? Bu bilgiyi birim testlerinizde kodlayın. Kimse kırılıp kırılmadığını söyleyemezse, rand () kodunu kontrol edip eve gitmeniz yeterlidir.


0

Tüm cevaplar arasında bunu kaçırmış olabilirim, ama bana göre, Birim Testinin arkasındaki ana itici güç, bugün bir yöntemin doğruluğunu kanıtlamaktan daha az, ancak bunu değiştirdiğinizde bu yöntemin sürekli doğruluğunu kanıtlamasından kaynaklanıyor .

Bazı koleksiyonlardaki öğelerin sayısını döndürmek gibi basit bir işlevi kullanın. Bugün, listeniz iyi bildiğiniz bir iç veri yapısına dayandığında, bu yöntemin acı verici bir şekilde açık olduğunu düşünebilirsiniz, bunun için bir teste ihtiyacınız olmaz. Sonra, birkaç ay veya yıl içinde, siz (veya bir başkası ) için [s] karar yerine iç liste yapısı. GetCount () öğesinin doğru değeri döndürdüğünü bilmeniz gerekir.

Ünite Testlerinin gerçekten kendine geldiği yer.

Kodunuzun iç uygulamasını değiştirebilirsiniz, ancak bu kodun herhangi bir tüketicisine, sonuç aynı kalı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.