Aracılığıyla paylaş


İzlenecek yol: Yönetilen Kod için Birim Testleri Oluşturma ve Çalıştırma

Bu açıklama Microsoft birim test framework'ü kullanılarak yönetilen kod ve Visual Studio Test Explorer için birim testler serisini oluşturma, çalıştırma ve özelleştirmeyi adım adım anlatmaktadır. Geliştirilmekte olan bir C# projesi ile başlayın, kodunu çalıştıran testi oluşturun, testi çalıştırın ve sonuçları inceleyin. Daha sonra proje kodunu değiştirin ve testi yeniden çalıştırın.

Bu konu aşağıdaki bölümleri içerir:

Yönergeyi hazırla

Bir Birim Test Projesi Oluşturma

Test sınıfı oluşturma

İlk test yöntemini oluşturma

Testi oluşturun ve çalıştırın

Kodunuzu düzeltin ve testinizi yeniden çalıştırın

Kodunuzu geliştirmek için birim testleri kullanın

Not

Bu açıklama yönetilebilir kod için Microsoft birim test framework'ünün kullanımını göstermektedir.Test Explorer ayrıca Test Explorer için bağdaştırıcıları olan üçüncü parti birim test çerçevelerinin testlerini yürütebilir.Daha fazla bilgi için, Nasıl yapılır: üçüncü taraf birim Test Frameworks yükleyin

Not

Testleri komut satırından nasıl çalıştıracağınız hakkında bilgi almak için bkz: İzlenecek Yol: Komut Satırı Test Yardımcı Programını Kullanmak.

Önkoşullar

Yönergeyi hazırla

Yönergeyi hazırlamak için

  1. Visual Studio 2012 öğesini açın.

  2. Dosya menüsünde, Yeni 'nin üzerine gelin ve Proje'yi tıklayın.

    Yeni Proje iletişim kutusu görüntülenir.

  3. Yüklü Şablonlar altından Visual C# seçin.

  4. Uygulama türleri listesinden Class Library'ye tıklayın.

  5. İsim kutusuna Banka yazın ve Tamam'ı tıklayın.

    Not

    "Banka" adı zaten kullanılıyorsa, proje için başka bir ad seçin.

    Yeni Banka projesi yaratılır ve Solution Explorer'da Class1.cs dosyası açılarak Kod Düzenleyicisi'nde görüntülenir.

    Not

    Eğer Class1.cs dosyası Kod Düzenleyicisi'nde açılmazsa, açmak için Solution Explorer'da Class1.cs dosyasını çift tıklatın.

  6. Kaynak kodu Birim Testleri Oluşturmak için Örnek Proje'dan kopyalayın.

  7. Orijinal Class1.cs dosyasının içeriğini Birim Testleri Oluşturmak için Örnek Proje öğesindeki kodla değiştirin.

  8. Dosyayı BankAccount.cs olarak kaydedin.

  9. Yapı menüsünde, Çözümü Derle'yi tıklatın.

Şu anda Banka adında bir projeniz var. Kaynak kodu test etmek için ve onunla birlikte test etmek için araçlar içerir. Banka için isim alanında, BankAccountNS, public sınıf içeren BankAccount, aşağıdaki prosedürlerde test edilecek yöntemler.

Bu hızlı başlangıçta, Debit yöntemine odaklanıyoruz. Debit yöntemi hesap kapatıldığında çağırılır ve aşağıdaki kodu içerir:

// method under test
public void Debit(double amount)
{
    if(amount > m_balance)
    {
        throw new ArgumentOutOfRangeException("amount");
    }
    if (amount < 0)
    {
        throw new ArgumentOutOfRangeException("amount");
    }
    m_balance += amount;
}

Bir Birim Test Projesi Oluşturma

Prerequisite: İzlenecek Yola Hazırlanma'nın adımlarını takip edin.

Bir birim test projesi oluşturma

  1. Menü çubuğundaki Dosya 'dan, Ekle'yi seçin ve sonra Yeni Proje'yi seçin.

  2. Yeni Proje diyalog kutusunda, Yüklenenler 'i genişletin, Visual C# 'ı genişletin ve sonra Test 'i seçin.

  3. Şablonlar listesinden Birim Test Projesi 'ni seçin.

  4. Ad kutusuna BankTest yazın ve sonra Tamam 'ı seçin.

    BankTests projesi Banka çözümüne eklenir.

  5. BankTests projesinde, Banka çözümüne bir başvuru ekleyin.

    Solution Explorer'da Başvurular 'ı seçin BankTests projesinin içinden ve sonra bağlam menüsünden Başvuru Ekle... 'yi seçin.

  6. Reference Manager iletişim kutusunda, Çözüm 'ü genişletin ve sonra Banka öğesini işaretleyin.

Test sınıfı oluşturma

BankAccount sınıfını doğrulamak için bir sınıfa ihtiyacımız var. Proje şablonu tarafından oluşturulan UnitTest1.cs'yi kullanabiliriz, ama dosyaya ve sınıfa daha açıklayıcı isimler vermeliyiz. Bunu Solution Explorer'da dosyayı yeniden adlandırma işlemiyle tek adımda yapabiliriz.

Sınıf dosyasını yeniden adlandırma

Solution Explorer'da, BankTests projesindeki UnitTest1.cs dosyasını seçin. Bağlam menüsünden Yeniden Adlandır 'ı seçin ve sonra dosyayı BankAccountTests.cs olarak yeniden adlandırın. Eğer projedeki 'UnitTest1' kod elemanlarının bütün başvurularını yeniden adlandırmak istiyorsanız çıkan iletişim kutusunda Evet 'i seçin. Bu adım sınıfın adını BankAccountTest olarak değiştirir.

BankAccountTests.cs dosyası şimdi şu kodu içerir:

// unit test code
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace BankTests
{
    [TestClass]
    public class BankAccountTests
    {
        [TestMethod]
        public void TestMethod1()
        {
        }
    }
}

Test altındaki projeye using deyimini ekleyin

Ayrıca using deyimi tam nitelikli adları olmadan da sınıfı test altındaki projeye çağırmak için bize izin verir. Sınıf dosyasının en üstüne ekleyin:

using BankAccountNS

ms182532.collapse_all(tr-tr,VS.110).gifTest sınıfı gereksinimleri

Test sınıfı için minimum gereksinimler şunlardır:

  • [TestClass] özniteliği Test Explorer'da çalıştırmak istediğiniz birim test yöntemlerini içeren herhangi sınıflar içindeki yönetilen kod için Microsoft birim test framework'ü gereklidir.

  • Explorer çalıştırmak için Test istediğiniz her test yöntemi olmalıdır [TestMethod]özniteliği.

Sizde olmayan bir birim test projesi diğer sınıflarda olabilir [TestClass] özniteliği ve test sınıflarında bulunmayan diğer yöntemleri olabilir [TestMethod] özniteliği. Bu sınıflar ve yöntemler test yöntemlerinizi kullanabilirsiniz.

İlk test yöntemini oluşturma

Bu yönergede, BankAccount sınıfındaki Debit yönteminin davranışlarını doğrulamak için birim test yöntemi yazacağız. Bu yöntem yukarıda listelenmiştir.

Test altındaki yöntemi analiz ederek, denetlenmesi gereken en az üç davranış olduğunu belirliyoruz:

  1. Eğer kredi tutarı bakiyeden büyükse yöntem [ArgumentOutOfRangeException] fırlatır.

  2. Ayrıca kredi tutarı sıfırdan küçükse ArgumentOutOfRangeException fırlatır.

  3. Eğer 1.) ve 2.) deki kontroller sağlanmışsa, yöntem hesap bakiyesini tutardan çıkarır.

İlk testimizde, hesaptan doğru bir tutar çekilmesi için geçerli bir tutarın (birisi hesap bakiyesinden daha az, diğeri sıfırdan büyük) doğrulamasını yaptık.

Test yöntem oluşturmak için

  1. using BankAccountNS; ifadesini BankAccountTests.cs dosyasına ekleyin

  2. Aşağıdaki yöntemi BankAccountTests sınıfına ekleyin.

    // unit test code
    [TestMethod]
    public void Debit_WithValidAmount_UpdatesBalance()
    {
        // arrange
        double beginningBalance = 11.99;
        double debitAmount = 4.55;
        double expected = 7.44;
        BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);
    
        // act
        account.Debit(debitAmount);
    
        // assert
        double actual = account.Balance;
        Assert.AreEqual(expected, actual, 0.001, "Account not debited correctly");
    }
    

Yöntem oldukça basittir. Yeni bir başlangıç bakiyesi ve geçerli bir geri alma miktarı olan BankAccount nesnesi oluşturuyoruz. Yönetilen kod için Microsoft birim test framework'ünde kullandığımız AreEqual yöntemi beklediğimiz bitiş bakiyesini doğrular.

ms182532.collapse_all(tr-tr,VS.110).gifTest yöntemi gereksinimleri

Test yönteminin aşağıdaki gereksinimleri karşılaması gerekir:

  • Yöntem [TestMethod] özniteliği ile donatılmış olmalıdır.

  • Yöntem void döndürmelidir.

  • Yöntemin parametreleri olamaz.

Testi oluşturun ve çalıştırın

Testi oluşturup çalıştırmak için

  1. Build menüsünden Build Solution'ı seçin.

    Eğer hata yoksa, Not Run Tests grubunda listelenen Debit_WithValidAmount_UpdatesBalance'lı UnitTestExplorer penceresi görünür. Eğer Test Explorer başarılı bir oluşturmadan sonra görünmüyorsa, Test menüsünden Windows'u seçin ve sonra Test Explorer'ı seçin.

  2. Test için Run All 'ı seçin. Test çalışırken pencerenin en üstündeki durum çubuğunda bir animasyon görünür. Test çalışmasının sonunda, eğer bütün yöntemler geçerse çubuk yeşile veya herhangi bir test başarısız olursa kırmızıya döner.

  3. Bu durumda, test başarısızdır. Bu yöntem Başarısız Testler'e taşınır. grup. Pencerenin en altında ayrıntıları görüntülemek için Test Explorer'dan yöntemi seçin.

Kodunuzu düzeltin ve testinizi yeniden çalıştırın

Test sonuçlarını analiz edin

Test sonucu hatayı açıklayan bir mesaj içerir. AreEquals yöntemi için, mesaj neyin beklendiğini (**Beklenen <XXX>**parametresi) ve gerçekten alınan ( Gerçek <YYY> parametresi) gösterir. Bakiyenin başlangıç bakiyesinden azalmasını bekliyorduk, ama bunun yerine mevzuat oranında artırmıştır.

Debit kodunun yeniden incelemesi birim testinin hata bulma konusunda başarılı olduğunu gösterir. Çıkarılması gerektiğinde geri çekme miktarı hesap bakiyesine eklenir.

Hatayı düzeltin

Hatayı düzeltmek için, basitçe çizgiyi değiştirin

m_balance += amount;

ile

m_balance -= amount;

Testi yeniden çalıştırın

Test Explorer'da Run All seçin ve testi yeniden çalıştırın. Kırmızı/yeşil çubuk yeşile döner ve test Geçen Testler grubuna taşınır.

Kodunuzu geliştirmek için birim testleri kullanın

Bu bölümde analizin yinelemeli sürecinin, birim test geliştirme ve yeniden işlemesinin üretim kodunuzun nasıl daha sağlam ve verimli hale getirebileceğiniz konusunda yardım etmektedir.

Sorunları analiz edin

Debit yönteminin geçerli tutarı doğruca onayladığı test yöntemini oluşturduktan sonra, orijinal analizdeki kalan durumlara dönebiliriz:

  1. Eğer kredi tutarı bakiyeden büyükse yöntem ArgumentOutOfRangeException fırlatır.

  2. Ayrıca kredi tutarı sıfırdan küçükse ArgumentOutOfRangeException fırlatır.

Test yöntemleri oluşturma

Bu sorunları gidermek için oluşturulan ilk test yöntemi denemesi umut verici görünüyor:

//unit test method
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange()
{
    // arrange
    double beginningBalance = 11.99;
    double debitAmount = -100.00;
    BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);

    // act
    account.Debit(debitAmount);

    // assert is handled by ExpectedException
}

Doğru istisnanın fırlatılmasını savunmak için ExpectedExceptionAttribute özniteliğini kullanırız. Bir ArgumentOutOfRangeException fırlatılana kadar özellik testin başarısız olmasına sebep olabilir. Testi hem pozitif hem de negatif debitAmount değerleriyle çalıştırın ve sonra test altındaki yöntemin miktar sıfırdan küçükse doğru davrandığını gösterecek şekilde genel ApplicationException fırlatması için geçici olarak değiştirin. Çekilen miktarın bakiyeden büyük olduğu zaman test etmek için, bütün ihtiyacımız olan:

  1. Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange isimli yeni bir test yöntemi oluşturun.

  2. Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange öğesindeki yöntem gövdesini yeni yönteme kopyalayın.

  3. debitAmount 'u bakiyeden büyük bir sayı olarak ayarlayın.

Testi çalıştırın.

debitAmount için farklı değerlerle iki yöntemi çalıştırmak testlerin olması gerektiği gibi kalan durumlarla işlendiğini göstermektedir. Üç testi de çalıştırmak bizim orijinal analizimizdeki durumların doğru şekilde ele alındığını doğrular.

Analize devam edin

Bununla birlikte, son iki test yöntemleri ayrıca rahatsızlık vericidir. Testler çalıştırılırken test altındaki hangi koddaki koşulun fırlattığı konusunda kesin bir şey söyleyemeyiz. İki koşulun ayırımı herhangi bir şekilde yardımcı olacaktır. Problem hakkında biraz daha düşündüğümüzde, testteki hangi koşulun ihlal edilmesinin bizim güvenimizi arttıracağı belirginleşir. Bu bilgi ayrıca test altındaki yöntem tarafından fırlatılan istisnanın işlenmesi konusunda üretim mekanizmasına çok yardımcı olacaktır. yöntem fırlattığında daha fazla bilgi üretmek bütün kaygılarınıza yardımcı olur, ama ExpectedException özniteliği bu bilgiyi sağlayamaz.

Test altındaki yönteme tekrar baktığımızda, iki koşulun da argümanın adını parametre olarak alan ArgumentOutOfRangeException yapıcısını kullandığını görürüz:

throw new ArgumentOutOfRangeException("amount");

MSDN Kitaplığı'nın aramasından, bir yapıcının çok daha zengin bilgi raporları var olduğunu keşfedeceksiniz. ArgumentOutOfRangeException(String, Object, String) argümanın adını, argüman değerini ve kullanıcı tanımlı mesajı içerir. Bu bu yapıcıyı kullanarak test altındaki yöntemi yeniden oluşturabiliriz. Daha iyisi, hataları belirtmek için genel olarak kullanılabilen tür üyelerini kullanabiliriz.

Test altındaki kodun yeniden oluşturulması

Sınıf kapsamındaki hata mesajları için öncelikle iki sabit tanımlayalım:

// class under test
public const string DebitAmountExceedsBalanceMessage = "Debit amount exceeds balance";
public const string DebitAmountLessThanZeroMessage = "Debit amount less than zero";

Sonra Debit yöntemi içerisindeki iki koşullu ifadeyi değiştirelim:

// method under test
// ...
    if (amount > m_balance)
    {
        throw new ArgumentOutOfRangeException("amount", amount, DebitAmountExceedsBalanceMessage);
    }

    if (amount < 0)
    {
        throw new ArgumentOutOfRangeException("amount", amount, DebitAmountLessThanZeroMessage);
    }
// ...

Test yöntemlerini yeniden oluşturun

Bizim test yöntemimizde, öncelikle ExpectedException özniteliğini kaldırmalıyız. Onun yerinde, istisna fırlatımını yakalamalı ve doğru koşul ifadesinde fırlatıldığını doğrulamalıyız. Ancak, kalan koşullarımızı doğrulamak için iki seçenek arasında karar vermeliyiz. Örneğin, Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange yönteminde, aşağıdaki eylemlerden birini alabiliriz:

  • İstisnanın ActualValue özelliğinin ( ArgumentOutOfRangeException yapıcısının ikinci parametresi) başlangıç bakiyesinden büyük olduğunu onaylayın. Bu seçenek test yönteminin beginningBalance değişkenine karşı olan istisnanın ActualValue özelliğini, ve sonra ayrıca ActualValue öğesi sıfırdan büyük olanı gerektirir.

  • Mesajın (yapıcının üçüncü parametresi) BankAccount sınıfı içinde tanımlanan DebitAmountExceedsBalanceMessage mesajını içerdiğini onaylayın.

Microsoft birim test framework'ündeki StringAssert.Contains yöntemi bize ilk seçeneğin gereksinimleri olan hesaplamalar olmadan ikinci seçeneği doğrulamamıza olanak sağlar.

Düzeltmenin ikinci denemesi Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange gibi görünebilir:

[TestMethod]
public void Debit_WhenAmountIsGreaterThanBalance_ShouldThrowArgumentOutOfRange()
{
    // arrange
    double beginningBalance = 11.99;
    double debitAmount = 20.0;
    BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);\

    // act
    try
    {
        account.Debit(debitAmount);
    }
    catch (ArgumentOutOfRangeException e)
    {
        // assert
        StringAssert.Contains(e.Message, BankAccount. DebitAmountExceedsBalanceMessage);
    }
}

Yeniden test etme, yeniden yazma ve yeniden analiz etme

Test yöntemlerini farklı değerlerle yeniden test ettiğimizde, aşağıdaki gerçeklerle karşılaşırız:

  1. Eğer bakiyeden büyük debitAmount kullanılarak doğru hatayı yakalarsak, Contains onayı geçer, istisna ihmal edilir, ve test yöntemi geçer. İstediğimiz davranış budur.

  2. Eğer bir debitAmount kullanırsak, onaylama işlemi başarısız olur çünkü yanlış hata mesajı döndürülür. Eğer test kod yolunun altındaki yöntemin içindeki diğer noktada geçici bir ArgumentOutOfRange istisna belirtiyorsak onay ayrıca başarısız olur. Bu çok iyi.

  3. debitAmount Değeri, geçerli (yani Bakiye, sıfırdan büyük ama daha az hiçbir özel durum yakalandı, böylece assert asla yakalandı. Test yöntemi geçer. Bu iyi değildir, çünkü test yönteminin istisna fırlatmadığında başarısız olmasını istiyoruz.

Üçüncü gerçek test yöntemimizdeki bir hatadır. Bu sorunu çözmeyi denemek için, Fail onayını hiç hata fırlatılmadığı durumu işlemek için test yönteminin sonuna ekleriz.

Ama yeniden test yapmak doğru istisna yakalandığında başarısız olduğunu gösterir. catch deyimi istisnayı sıfırlar ve yöntem çalışmaya devam eder, yeni onaylama işleminde başarısız olur. Yeni sorunu gidermek için, return deyiminden sonra StringAssert ekliyoruz. Yeniden test etmek sorunların çözülüp çözülmediğini onaylar. Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange son sürümümüz aşağıdaki gibi olur:

[TestMethod]
public void Debit_WhenAmountIsGreaterThanBalance_ShouldThrowArgumentOutOfRange()
{
    // arrange
    double beginningBalance = 11.99;
    double debitAmount = 20.0;
    BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);\

    // act
    try
    {
        account.Debit(debitAmount);
    }
    catch (ArgumentOutOfRangeException e)
    {
        // assert
        StringAssert.Contains(e.Message, BankAccount. DebitAmountExceedsBalanceMessage);
        return;
    }
    Assert.Fail("No exception was thrown.")
}

Bu son bölümde, test kodumuzu geliştirme çalışmalarımız daha sağlam ve bilgilendirici test yöntemlerimiz olmasını sağladı. Ancak daha da önemlisi, fazladan yapılan analiz test altındaki projemizin daha iyi kodlanmasını sağlar.