Aracılığıyla paylaş


.NET için birim testleri oluşturma ve çalıştırma

Bu makalede, yönetilen kod için Microsoft birim testi çerçevesini ve Visual Studio Test Gezginikullanarak bir dizi birim testi oluşturma, çalıştırma ve özelleştirme adımları gösterilmektedir. Geliştirme aşamasında olan bir C# projesiyle başlarsınız, kodunu kullanan testler oluşturur, testleri çalıştırır ve sonuçları incelersiniz. Ardından proje kodunu değiştirir ve testleri yeniden çalıştırırsınız. Bu adımları izlemeden önce bu görevlere kavramsal bir genel bakış istiyorsanız bkz. Birim testi temel bilgileri.

Bu makalede, birim testlerinin el ile nasıl oluşturulacağı açıklanmaktadır. Mevcut koddan otomatik olarak test oluşturmak istiyorsanız aşağıdaki makalelere bakın:

Önkoşullar

Visual Studio , .NET masaüstü geliştirme iş yüküyle birlikte yüklenmelidir.

Test etmek için proje oluşturma

  1. Visual Studio'yu açın.

  2. Başlangıç penceresinde yeni proje oluştur seçin.

  3. .NET için C# Konsol Uygulaması proje şablonunu arayıp seçin ve ardından İleri'ye tıklayın.

    Konsol Uygulaması şablonunu görmüyorsanız, .NET masaüstü geliştirme iş yükünü yüklemek için Visual Studio Yükleyicisi'ni kullanın.

  4. Projeyi Bankasıolarak adlandırın ve sonra İleridüğmesine tıklayın.

  5. Önerilen hedef çerçeveyi veya .NET 8'i seçin ve ardından Oluştur'useçin.

    Banka projesi oluşturulur ve kod düzenleyicisinde Program.cs dosyası açık Çözüm Gezgini görüntülenir.

    Not

    Düzenleyicide Program.cs dosyası açık değilse, açmak için Çözüm Gezgini'nde Program.cs dosyasına çift tıklayın.

  6. Program.cs içeriğini, BankAccount sınıfını tanımlayan aşağıdaki C# koduyla değiştirin:

    using System;
    
    namespace BankAccountNS
    {
        /// <summary>
        /// Bank account demo class.
        /// </summary>
        public class BankAccount
        {
            private readonly string m_customerName;
            private double m_balance;
    
            private BankAccount() { }
    
            public BankAccount(string customerName, double balance)
            {
                m_customerName = customerName;
                m_balance = balance;
            }
    
            public string CustomerName
            {
                get { return m_customerName; }
            }
    
            public double Balance
            {
                get { return m_balance; }
            }
    
            public void Debit(double amount)
            {
                if (amount > m_balance)
                {
                    throw new ArgumentOutOfRangeException("amount");
                }
    
                if (amount < 0)
                {
                    throw new ArgumentOutOfRangeException("amount");
                }
    
                m_balance += amount; // intentionally incorrect code
            }
    
            public void Credit(double amount)
            {
                if (amount < 0)
                {
                    throw new ArgumentOutOfRangeException("amount");
                }
    
                m_balance += amount;
            }
    
            public static void Main()
            {
                BankAccount ba = new BankAccount("Mr. Bryan Walton", 11.99);
    
                ba.Credit(5.77);
                ba.Debit(11.22);
                Console.WriteLine("Current balance is ${0}", ba.Balance);
            }
        }
    }
    
  7. Çözüm Gezgini'nde sağ tıklayıp Yeniden Adlandır'ı seçerek dosyayı BankAccount.cs olarak yeniden adlandırın.

  8. Derleme menüsünde Çözümü Derle üzerine tıklayın (veya Ctrl + SHIFT + Btuşlarına basın).

Artık test edebilirsiniz yöntemleri olan bir projeniz var. Bu makalede testler Debit yöntemine odaklanır. Debit yöntemi, bir hesaptan para çekildiğinde çağrılır.

Birim testi projesi oluşturma

  1. Dosya menüsünde Ekle>Yeni Projeseçin.

    Bahşiş

    Çözüm Gezgini içinde çözüme sağ tıklayabilir ve >Yeni Projeekle seçebilirsiniz.

  2. Arama kutusuna test yazın, dil olarak C# seçin ve sonra .NET için C# MSTest Test Projesi şablonunu seçin, ardından İleri 'ye tıklayın.

    Not

    Visual Studio 2019 sürüm 16.9'da, MSTest proje şablonu Birim Test Projesi.

  3. Projeyi BankTests adlandırın ve İleritıklayın.

  4. Önerilen hedef çerçeveyi veya .NET 8'i seçin ve ardından Oluştur'useçin.

    Visual Studio 2022 sürüm 17.10'dan başlayarak bir test çalıştırıcısı da seçebilirsiniz. Test çalıştırıcısı için VSTest veya MSTestseçebilirsiniz. Test çalıştırıcıları arasındaki farklar hakkında daha fazla bilgi için bkz. Microsoft.Testing.Platform ve VSTest karşılaştırması.

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

  5. BankTests projesinde, Bank projesine bir referans ekleyin.

    Çözüm GezginiBankTests projesinin altında Bağımlılıklar'ı seçin ve ardından sağ tıklama menüsünden Başvuru Ekle (veya Proje Başvurusu Ekle ) seçin.

  6. Başvuru Yöneticisi iletişim kutusunda Projeler genişletin, çözüm seçin ve Banka öğesini işaretleyin.

  7. Tamamseçin.

Test sınıfı oluşturma

BankAccount sınıfını doğrulamak için bir test sınıfı oluşturun. Proje şablonu tarafından oluşturulan UnitTest1.cs dosyasını kullanabilirsiniz, ancak dosyaya ve sınıfa daha açıklayıcı adlar verebilirsiniz.

Dosyayı ve sınıfı yeniden adlandırma

  1. Dosyayı yeniden adlandırmak için Çözüm Gezgini'nde BankTests projesindeki UnitTest1.cs dosyasını seçin. Sağ tıklama menüsünden Yeniden Adlandır'ı seçin (veya F2 tuşlarına basın) ve dosyayı BankAccountTests.csolarak yeniden adlandırın.

  2. Sınıfı yeniden adlandırmak için, imleci kod düzenleyicisindeki UnitTest1 getirin, sağ tıklayın ve Yeniden Adlandır'ı seçin (veya F2 )basın. BankAccountTests yazın ve ardından Entertuşuna basın.

BankAccountTests.cs dosyası artık aşağıdaki kodu içerir:

// The 'using' statement for Test Tools is in GlobalUsings.cs
// using Microsoft.VisualStudio.TestTools.UnitTesting;

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

Bir using deyimi ekleyin

Test altında bulunan projeye tam nitelikli adlar kullanmadan çağrı yapabilmek için test sınıfına using ifadesi ekleyin. Sınıf dosyasının en üstüne şunları ekleyin:

using BankAccountNS;

Sınıf gereksinimlerini test edin

Test sınıfı için en düşük gereksinimler şunlardır:

  • [TestClass] özniteliği, Test Gezgini'nde çalıştırmak istediğiniz birim testi yöntemlerini içeren tüm sınıflarda gereklidir.

  • Test Gezgini'nin tanımasını istediğiniz her test yönteminin [TestMethod] özniteliği olmalıdır.

Birim testi projesinde [TestClass] özniteliği olmayan başka sınıflar ve test sınıflarında [TestMethod] özniteliği olmayan başka yöntemleriniz olabilir. Bu diğer sınıfları ve yöntemleri test yöntemlerinizden çağırabilirsiniz.

İlk test yöntemini oluşturma

Bu yordamda, Debit sınıfının BankAccount yönteminin davranışını doğrulamak için birim testi yöntemleri yazacaksınız.

Denetlenilmesi gereken en az üç davranış vardır:

Bahşiş

Bu makalede kullanmayacağınız için varsayılan TestMethod1 yöntemi silebilirsiniz.

Test yöntemi oluşturmak için

İlk test, geçerli bir tutarın (hesap bakiyesinden küçük ve sıfırdan büyük bir tutar) hesaptan doğru miktarı geri çektiğini doğrular. Bu BankAccountTests sınıfına aşağıdaki yöntemi ekleyin:

[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öntemi basittir: başlangıç bakiyesi olan yeni bir BankAccount nesnesi ayarlar ve ardından geçerli bir miktarı geri çeker. Bitiş bakiyesinin beklendiği gibi olduğunu doğrulamak için Assert.AreEqual yöntemini kullanır. Assert.AreEqual, Assert.IsTrueve diğerleri gibi yöntemler birim testinde sıklıkla kullanılır. Birim testi yazma konusunda daha kavramsal bilgi için bkz. Testlerinizi yazın.

Test yöntemi gereksinimleri

Test yöntemi aşağıdaki gereksinimleri karşılamalıdır:

  • [TestMethod] attributu ile dekore edilmiştir.

  • Ayrıca daha fazla bilgi olmadığı için bu öneriyi yapıyorum: "Bu void'ı döndürür."

  • Parametresi olamaz.

Testi derleme ve çalıştırma

  1. Derleme menüsünde Çözüm Derleme seçin (veya Ctrl + SHIFT + Btuşlarına basın).

  2. Test Gezgini açık değilse, üst menü çubuğundan Test >Test Gezgini (veya Test>Windows>Test Gezgini) öğesini seçerek açın (veya Ctrl + Etuşlarına basın T).

  3. Testi çalıştırmak için Tümünü Çalıştır seçin (veya Ctrl + R, V) tuşlarına basın.

    Test çalışırken, Test Gezgini penceresinin üst kısmındaki durum çubuğu animasyonludur. Test çalıştırmasının sonunda, tüm test yöntemleri geçerse çubuk yeşile veya testlerden herhangi biri başarısız olursa kırmızıya dönüşür.

    Bu durumda test başarısız olur.

  4. Pencerenin en altındaki ayrıntıları görüntülemek için Test Gezgini yöntemini seçin.

Kodunuzu düzeltme ve testlerinizi yeniden çalıştırma

Test sonucu, hatayı açıklayan bir ileti içerir. Bu iletiyi görmek için detaya gitmeniz gerekebilir. AreEqual yöntemi için, ileti nelerin beklendiğini ve gerçekte nelerin alındığını görüntüler. Bakiyenin azalmasını bekliyorsunuz, ancak bunun yerine para çekme miktarına göre arttı.

Birim testi bir hata ortaya çıkardı: para çekme miktarı hesap bakiyesine eklenmiş, fakat olarak çıkarılması gerekiyordu.

Hatayı düzeltme

Hatayı düzeltmek için BankAccount.cs dosyasında satırı değiştirin:

m_balance += amount;

ile:

m_balance -= amount;

Testi yeniden çalıştırma

Test Gezgini'nde, testi yeniden çalıştırmak için Tümünü Çalıştır seçin (veya Ctrl + RV) tuşlarına basın. Testin geçtiğini belirtmek için kırmızı/yeşil çubuk yeşile döner.

Visual Studio 2019'daki Test Gezgini'nde geçirilen testi gösteren

Visual Studio 2019'daki Test Gezgini'nde geçirilen testi gösteren

Kodunuzu geliştirmek için birim testlerini kullanma

Bu bölümde yinelemeli analiz, birim testi geliştirme ve yeniden düzenleme işlemlerinin üretim kodunuzu daha sağlam ve etkili hale getirmenize nasıl yardımcı olabileceği açıklanmaktadır.

Sorunları analiz etme

Debit yönteminde geçerli bir tutarın doğru şekilde düşüldüğünü onaylamak için bir test yöntemi oluşturdunuz. Şimdi, borç miktarının aşağıdaki durumlardan biri olması halinde yöntemin bir ArgumentOutOfRangeException hata kodu ürettiğini doğrulayın:

  • bakiyeden daha büyük veya
  • sıfırdan küçük.

Yeni test yöntemleri oluşturma ve çalıştırma

Borç tutarı sıfırdan küçük olduğunda doğru davranışı doğrulamak için bir test yöntemi oluşturun:

[TestMethod]
public void Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange()
{
    // Arrange
    double beginningBalance = 11.99;
    double debitAmount = -100.00;
    BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);

    // Act and assert
    Assert.ThrowsException<System.ArgumentOutOfRangeException>(() => account.Debit(debitAmount));
}

Doğru istisnanın atıldığını doğrulamak için ThrowsException yöntemini kullanın. Bu yöntem, bir ArgumentOutOfRangeException atılmadığı sürece testin başarısız olmasına neden olur. Test edilen yöntemi, borç tutarı sıfırdan küçük olduğunda daha genel bir ApplicationException fırlatmak için geçici olarak değiştirirseniz, test doğru şekilde davranır; yani başarısız olur.

Çekilen tutar bakiyeden büyük olduğunda durumu test etmek için aşağıdaki adımları uygulayın:

  1. Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRangeadlı yeni bir test yöntemi oluşturun.

  2. Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange'dan yöntem gövdesini yeni yönteme kopyalayın.

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

İki testi çalıştırın ve geçtiklerini doğrulayın.

Çözümlemeye devam et

Test edilen yöntem daha da geliştirilebilir. Geçerli uygulamayla, test sırasında hangi koşulun (amount > m_balance veya amount < 0) özel durumun oluşmasına neden olduğunu bilmemizin hiçbir yolu yoktur. Yöntemin bir yerinde bir ArgumentOutOfRangeException atıldığını biliyoruz. BankAccount.Debit'da hangi koşulun özel durumun (amount > m_balance veya amount < 0) atılmasına neden olduğunu anlayabilirsek, yöntemimizin parametrelerini doğru bir şekilde denetlediğinden emin olabiliriz, bu daha iyi olur.

Test edilen yönteme (BankAccount.Debit) yeniden bakın ve her iki koşullu deyimin de bağımsız değişkenin adını parametre olarak alan bir ArgumentOutOfRangeException oluşturucu kullandığına dikkat edin:

throw new ArgumentOutOfRangeException("amount");

Çok daha zengin bilgileri bildiren bir oluşturucu vardır: ArgumentOutOfRangeException(String, Object, String) bağımsız değişkenin adını, bağımsız değişken değerini ve kullanıcı tanımlı bir iletiyi içerir. Bu oluşturucuyu kullanmak için test altındaki yöntemi yeniden düzenleyebilirsiniz. Daha da iyisi, hataları belirtmek için genel kullanıma açık tür üyelerini kullanabilirsiniz.

Test altındaki kodu yeniden düzenleme

İlk olarak, sınıf kapsamındaki hata iletileri için iki sabit tanımlayın. Test edilen sınıfa tanımları yerleştirin, BankAccount:

public const string DebitAmountExceedsBalanceMessage = "Debit amount exceeds balance";
public const string DebitAmountLessThanZeroMessage = "Debit amount is less than zero";

Ardından, Debit yöntemindeki iki koşullu deyimi değiştirin:

if (amount > m_balance)
{
    throw new System.ArgumentOutOfRangeException("amount", amount, DebitAmountExceedsBalanceMessage);
}

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

Test yöntemlerini yeniden düzenleme

Assert.ThrowsExceptionçağrısını kaldırarak test yöntemlerini yeniden düzenleme. Çağrıyı bir Debit() bloğunda try/catch sarmalayın, beklenen özel durumu yakalayın ve ilişkili mesajını doğrulayın. Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Contains yöntemi iki dizeyi karşılaştırma olanağı sağlar.

Şimdi Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange şöyle görünebilir:

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

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

Yeniden test etme, yeniden yazma ve yeniden analiz etme

Şu anda test yöntemi olması gereken tüm durumları işlememektedir. Test altındaki yöntem Debit yöntemi, ArgumentOutOfRangeException bakiyeden daha büyük (veya sıfırdan küçük) olduğunda bir debitAmount fırlatmadıysa, test yöntemi başarılı sayılır. İstisna atılmazsa test yönteminin başarısız olmasını istediğiniz için bu senaryo iyi değildir.

Bu sonuç, test yöntemindeki bir hatadır. Sorunu çözmek için, hiçbir özel durum oluşturulmadığında durumu ele almak için test yönteminin sonuna bir Assert.Fail doğrulaması ekleyin.

Testin yeniden çalıştırılması, doğru özel durum yakalandığında testin başarısız olduğunu gösterdiğini belirtir. catch bloğu hatayı yakalar, ancak yöntem çalışmaya devam eder ve yeni Assert.Fail onayında başarısız olur. Bu sorunu çözmek için return bloğundaki StringAssert sonrasına bir catch deyimi ekleyin. Testi yeniden çalıştırmak, bu sorunu çözdüğünüzden emin olur. Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange son sürümü şöyle görünür:

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

    // Act
    try
    {
        account.Debit(debitAmount);
    }
    catch (System.ArgumentOutOfRangeException e)
    {
        // Assert
        StringAssert.Contains(e.Message, BankAccount.DebitAmountExceedsBalanceMessage);
        return;
    }

    Assert.Fail("The expected exception was not thrown.");
}

Sonuç

Test kodundaki iyileştirmeler daha sağlam ve bilgilendirici test yöntemlerine yol açtı. Ancak daha da önemlisi, test altındaki kodu da geliştirdiler.

Bahşiş

Bu makalede yönetilen kod için Microsoft birim testi çerçevesi kullanılmaktadır. Test Gezgini, Test Gezginiiçin bağdaştırıcıları olan üçüncü taraf birim test çerçevelerinden de test çalıştırabilir. Daha fazla bilgi için bkz. üçüncü taraf birim test çerçevelerini yükleme.

Testleri komut satırından çalıştırma hakkında bilgi için bkz. VSTest.Console.exe komut satırı seçenekleri.