Birim testi
İpucu
Bu içerik, .NET Docs'ta veya çevrimdışı olarak okunabilen ücretsiz indirilebilir bir PDF olarak bulunan .NET MAUIKullanan Kurumsal Uygulama Desenleri adlı e-Kitap'tan bir alıntıdır.
Çok platformlu uygulamalarda hem masaüstü hem de web tabanlı uygulamalara benzer sorunlar yaşanmaktadır. Mobil kullanıcılar cihazlarına, ağ bağlantılarına, hizmetlerin kullanılabilirliğine ve diğer çeşitli faktörlere göre farklılık gösterir. Bu nedenle, çok platformlu uygulamalar kalitelerini, güvenilirliklerini ve performanslarını geliştirmek için gerçek dünyada kullanabilecekleri şekilde test edilmelidir. Bir uygulamada birim testi, tümleştirme testi ve kullanıcı arabirimi testi gibi birçok test türü gerçekleştirilmelidir. Birim testi, yüksek kaliteli uygulamalar oluşturmak için en yaygın ve temel biçimdir.
Birim testi, genellikle bir yöntem olan uygulamanın küçük bir birimini alır, kodun geri kalanından yalıtır ve beklendiği gibi davrandığını doğrular. Amacı, her işlev biriminin beklendiği gibi çalıştığını ve bu nedenle hataların uygulama genelinde yayılmadığını denetlemektir. Bir hatanın oluştuğu yeri algılamak, hatanın ikincil bir hata noktasında dolaylı olarak etkisini gözlemlemekten daha verimlidir.
Birim testi, yazılım geliştirme iş akışının ayrılmaz bir parçası olduğunda kod kalitesi üzerinde en önemli etkiye sahiptir. Birim testleri, bir uygulama için tasarım belgeleri ve işlevsel belirtimler olarak görev yapabilir. Bir yöntem yazıldığı anda standart, sınır ve yanlış giriş veri durumlarına yanıt olarak yöntemin davranışını doğrulayan ve kod tarafından yapılan açık veya örtük varsayımları denetleyebilen birim testleri yazılmalıdır. Alternatif olarak, test temelli geliştirme ile birim testleri koddan önce yazılır. Test odaklı geliştirme ve bunu uygulama hakkında daha fazla bilgi için bkz. Kılavuz: Test Gezgini'ni kullanarak test odaklı geliştirme..
Not
Birim testleri regresyona karşı çok etkilidir. Başka bir ifadeyle, eskiden çalışan ancak hatalı bir güncelleştirme tarafından rahatsız edilen işlevler.
Birim testleri genellikle düzenleme eylemi-onay desenini kullanır:
Adımlar | Açıklama |
---|---|
Düzenle | Nesneleri başlatır ve test altındaki yönteme geçirilen verilerin değerini ayarlar. |
Davranmak | Gerekli bağımsız değişkenlerle test altındaki yöntemini çağırır. |
Assert | Test altındaki yönteminin eyleminin beklendiği gibi davrandığını doğrular. |
Bu düzen, birim testlerinin okunabilir, kendi kendine açıklayıcı ve tutarlı olmasını sağlar.
Bağımlılık ekleme ve birim testi
Gevşek bir şekilde bağlanmış bir mimariyi benimsemenin motivasyonlarından biri, birim testini kolaylaştırıyor olmasıdır. Bağımlılık ekleme hizmetine kaydedilen türlerden biri arabirimdir IAppEnvironmentService
. Aşağıdaki kod örneğinde bu sınıfın ana hattı gösterilmektedir:
public class OrderDetailViewModel : ViewModelBase
{
private IAppEnvironmentService _appEnvironmentService;
public OrderDetailViewModel(
IAppEnvironmentService appEnvironmentService,
IDialogService dialogService, INavigationService navigationService, ISettingsService settingsService)
: base(dialogService, navigationService, settingsService)
{
_appEnvironmentService = appEnvironmentService;
}
}
sınıfı OrderDetailViewModel
, bağımlılık ekleme kapsayıcısının IAppEnvironmentService
bir OrderDetailViewModel
nesne örneği oluşturduğunda çözümlediği türüne bağımlılığı vardır. Ancak, sınıfın birim testini IAppEnvironmentService
yapmak için gerçek sunucuları, cihazları ve yapılandırmaları kullanan bir OrderDetailViewModel
nesne oluşturmak yerine, testlerin amacı için nesnesini sahte bir nesneyle değiştirinIAppEnvironmentService
. Sahte nesne, bir nesnenin veya arabirimin aynı imzasına sahip olan, ancak birim testine yardımcı olmak için belirli bir şekilde oluşturulan nesnedir. Genellikle farklı verileri ve iş akışı senaryolarını test etmek için arabirimlerin belirli uygulamalarını sağlamak için bağımlılık ekleme ile birlikte kullanılır.
Bu yaklaşım nesnenin IAppEnvironmentService
çalışma zamanında sınıfına geçirilmesini OrderDetailViewModel
sağlar ve test edilebilirlik açısından, test zamanında bir sahte sınıfın sınıfa geçirilmesini OrderDetailViewModel
sağlar. Bu yaklaşımın temel avantajı, çalışma zamanı platformu özellikleri, web hizmetleri veya veritabanları gibi gereksiz kaynaklara gerek kalmadan birim testlerinin yürütülmesine olanak tanımasıdır.
MVVM uygulamalarını test etme
Modelleri test etme ve MVVM uygulamalarından modelleri görüntüleme, diğer tüm sınıflarla aynıdır ve aynı araçları ve teknikleri kullanır; bu, birim testi ve sahte oluşturma gibi özellikleri içerir. Ancak model ve görünüm sınıfları için tipik olan bazı desenler belirli birim testi tekniklerinden yararlanabilir.
İpucu
Her birim testiyle tek bir şey test edin. Bir testin karmaşıklığı genişledikçe bu testin doğrulanması daha da zorlaşır. Birim testini tek bir endişeyle sınırlayarak testlerimizin daha tekrarlanabilir, yalıtılmış ve daha küçük bir yürütme süresine sahip olmasını sağlayabiliriz. Daha iyi yöntemler için bkz . .NET ile birim testi en iyi yöntemleri.
Birim testi alıştırması yapmak için birimin davranışının birden fazla yönünü seçmeyin. Bunun yapılması, okunması ve güncelleştirilmesi zor olan testlere yol açar. Ayrıca bir hatayı yorumlarken kafa karışıklığına neden olabilir.
eShop çok platformlu uygulaması, iki farklı birim testi türünü destekleyen birim testi gerçekleştirmek için MSTest kullanır:
Test Türü | Öznitelik | Açıklama |
---|---|---|
TestMethod | TestMethod |
Çalıştırılacak gerçek test yöntemini tanımlar. |
DataSource | DataSource |
Yalnızca belirli bir veri kümesi için geçerli olan testler. |
eShop çoklu platform uygulamasına dahil edilen birim testleri TestMethod'dur, bu nedenle her birim testi yöntemi özniteliğiyle TestMethod
dekore edilmiştir. MSTest'e ek olarak, NUnit ve xUnit dahil olmak üzere çeşitli test çerçeveleri de mevcuttur.
Zaman uyumsuz işlevselliği test etme
MVVM desenini uygularken, görünüm modelleri genellikle hizmetlerdeki işlemleri genellikle zaman uyumsuz olarak çağırır. Bu işlemleri çağıran kod testleri genellikle gerçek hizmetler için değiştirme olarak sahteleri kullanır. Aşağıdaki kod örneği, bir sahte hizmeti görünüm modeline geçirerek zaman uyumsuz işlevselliği test etme işlemini gösterir:
[TestMethod]
public async Task OrderPropertyIsNotNullAfterViewModelInitializationTest()
{
// Arrange
var orderService = new OrderMockService();
var orderViewModel = new OrderDetailViewModel(orderService);
// Act
var order = await orderService.GetOrderAsync(1, GlobalSetting.Instance.AuthToken);
await orderViewModel.InitializeAsync(order);
// Assert
Assert.IsNotNull(orderViewModel.Order);
}
Bu birim testi, yöntem çağrıldıktan sonra örneğin özelliğinin Order
bir değere OrderDetailViewModel
sahip olup olmadığını denetlerInitializeAsync
. Yöntemi InitializeAsync
, görünüm modelinin ilgili görünümüne gidildiğinde çağrılır. Gezinti hakkında daha fazla bilgi için bkz . Gezinti.
OrderDetailViewModel
Örnek oluşturulduğunda, bir IOrderService
örneğin bağımsız değişken olarak belirtilmesi beklenebilir. Ancak, OrderService
bir web hizmetinden veri alır. Bu nedenle, sınıfının sahte bir sürümü OrderMockService
olan bir OrderService
örnek, oluşturucunun bağımsız değişkeni OrderDetailViewModel
olarak belirtilir. Ardından, işlem kullanan InitializeAsync
görünüm modelinin IOrderService
yöntemi çağrıldığında bir web hizmetiyle iletişim kurmak yerine sahte veriler alınır.
INotifyPropertyChanged uygulamalarını test etme
Arabirimin uygulanması, görünümlerin INotifyPropertyChanged
görünüm modellerinden ve modellerinden kaynaklanan değişikliklere tepki vermesine olanak tanır. Bu değişiklikler denetimlerde gösterilen verilerle sınırlı değildir; animasyonların başlatılmasına veya denetimlerin devre dışı bırakılmasına neden olan görünüm modeli durumları gibi görünümü denetlemek için de kullanılır.
Birim testi tarafından doğrudan güncelleştirilebilen özellikler, olaya bir olay işleyicisi PropertyChanged
eklenerek ve özellik için yeni bir değer ayarlandıktan sonra olayın tetiklenip tetiklenmediği denetlenerek test edilebilir. Aşağıdaki kod örneğinde bu tür bir test gösterilmektedir:
[TestMethod]
public async Task SettingOrderPropertyShouldRaisePropertyChanged()
{
var invoked = false;
var orderService = new OrderMockService();
var orderViewModel = new OrderDetailViewModel(orderService);
orderViewModel.PropertyChanged += (sender, e) =>
{
if (e.PropertyName.Equals("Order"))
invoked = true;
};
var order = await orderService.GetOrderAsync(1, GlobalSetting.Instance.AuthToken);
await orderViewModel.InitializeAsync(order);
Assert.IsTrue(invoked);
}
Bu birim testi, sınıfının yöntemini çağırır InitializeAsync
ve bu da özelliğinin OrderViewModel
güncelleştirilmeye neden olur Order
. Özellik için PropertyChanged
olayın tetiklenmiş olması koşuluyla Order
birim testi geçer.
İleti tabanlı iletişimi test etme
Gevşek bir şekilde bağlanmış sınıflar arasında iletişim kurmak için sınıfını kullanan MessagingCenter
görünüm modelleri, aşağıdaki kod örneğinde gösterildiği gibi test altındaki kod tarafından gönderilen iletiye abone olarak birim testi yapılabilir:
[TestMethod]
public void AddCatalogItemCommandSendsAddProductMessageTest()
{
var messageReceived = false;
var catalogService = new CatalogMockService();
var catalogViewModel = new CatalogViewModel(catalogService);
MessagingCenter.Subscribe<CatalogViewModel, CatalogItem>(
this, MessageKeys.AddProduct, (sender, arg) =>
{
messageReceived = true;
});
catalogViewModel.AddCatalogItemCommand.Execute(null);
Assert.IsTrue(messageReceived);
}
Bu birim testi, CatalogViewModel
yürütülmekte olan iletiye yanıt olarak iletiyi yayımlayıp yayımlamadığını AddProduct
AddCatalogItemCommand
denetler.
MessagingCenter
sınıfı çok noktaya yayın ileti aboneliklerini desteklediğinden, birim testi iletiye AddProduct
abone olabilir ve almak için bir geri çağırma temsilcisi yürütebilir. Lambda ifadesi olarak belirtilen bu geri çağırma temsilcisi, testin davranışını doğrulamak için deyimi tarafından Assert
kullanılan bir boole alanı ayarlar.
Özel durum işlemeyi test etme
Birim testleri, aşağıdaki kod örneğinde gösterildiği gibi geçersiz eylemler veya girişler için belirli özel durumların oluşturulduğunu denetleyene de yazılabilir:
[TestMethod]
public void InvalidEventNameShouldThrowArgumentExceptionText()
{
var behavior = new MockEventToCommandBehavior
{
EventName = "OnItemTapped"
};
var listView = new ListView();
Assert.Throws<ArgumentException>(() => listView.Behaviors.Add(behavior));
}
Denetimin ListView
adlı OnItemTapped
bir olayı olmadığından bu birim testi bir özel durum oluşturur.
Assert.Throws<T>
yöntemi, beklenen özel durumun türü olan T
genel bir yöntemdir. yöntemine Assert.Throws<T>
geçirilen bağımsız değişken, özel durum oluşturacak bir lambda ifadesidir. Bu nedenle, lambda ifadesinin bir ArgumentException
oluşturması koşuluyla birim testi geçer.
İpucu
Özel durum ileti dizelerini inceleyen birim testleri yazmaktan kaçının. Özel durum ileti dizeleri zaman içinde değişebilir ve bu nedenle, varlıklarını kullanan birim testleri kırılgan olarak kabul edilir.
Doğrulamayı test etme
Doğrulama uygulamasını test etmenin iki yönü vardır: doğrulama kurallarının doğru uygulanıp uygulanmadığını test etme ve sınıfın beklendiği gibi performans göstermesini ValidatableObject<T>
test etme.
Doğrulama mantığı genellikle test etmek kolaydır, çünkü genellikle çıkışın girişe bağlı olduğu kendi içinde bir işlemdir. Aşağıdaki kod örneğinde gösterildiği gibi, en az bir ilişkili doğrulama kuralına sahip her özellikte yöntemini çağırmanın Validate
sonuçları üzerinde testler olmalıdır:
[TestMethod]
public void CheckValidationPassesWhenBothPropertiesHaveDataTest()
{
var mockViewModel = new MockViewModel();
mockViewModel.Forename.Value = "John";
mockViewModel.Surname.Value = "Smith";
var isValid = mockViewModel.Validate();
Assert.IsTrue(isValid);
}
Bu birim testi, örnekteki iki ValidatableObject<T>
özelliğin de verileri olduğunda doğrulamanın MockViewModel
başarılı olup olmadığını denetler.
Doğrulamanın başarılı olup olmadığını denetlemenin yanı sıra doğrulama birimi testleri, sınıfın Value
beklendiği gibi çalıştığını doğrulamak için her IsValid
örneğin , Errors
ve ValidatableObject<T>
özelliğinin değerlerini de denetlemelidir. Aşağıdaki kod örneğinde bunu sağlayan bir birim testi gösterilmektedir:
[TestMethod]
public void CheckValidationFailsWhenOnlyForenameHasDataTest()
{
var mockViewModel = new MockViewModel();
mockViewModel.Forename.Value = "John";
bool isValid = mockViewModel.Validate();
Assert.IsFalse(isValid);
Assert.IsNotNull(mockViewModel.Forename.Value);
Assert.IsNull(mockViewModel.Surname.Value);
Assert.IsTrue(mockViewModel.Forename.IsValid);
Assert.IsFalse(mockViewModel.Surname.IsValid);
Assert.AreEqual(mockViewModel.Forename.Errors.Count(), 0);
Assert.AreNotEqual(mockViewModel.Surname.Errors.Count(), 0);
}
Bu birim testi, özelliğinde Surname
veri olmadığında ve her MockViewModel
örneğin , Value
ve IsValid
Errors
özelliği doğru ayarlandığında doğrulamanın başarısız ValidatableObject<T>
olup olmadığını denetler.
Özet
Birim testi, genellikle bir yöntem olan uygulamanın küçük bir birimini alır, kodun geri kalanından yalıtır ve beklendiği gibi davrandığını doğrular. Amacı, her işlev biriminin beklendiği gibi çalıştığını ve bu nedenle hataların uygulama genelinde yayılmadığını denetlemektir.
Test altındaki bir nesnenin davranışı, bağımlı nesnelerin davranışını simüle eden sahte nesnelerle değiştirilerek yalıtılabilir. Bu, birim testlerinin çalışma zamanı platformu özellikleri, web hizmetleri veya veritabanları gibi gereksiz kaynaklar gerektirmeden yürütülmesini sağlar
Modelleri test etme ve MVVM uygulamalarından modelleri görüntüleme, diğer sınıfların test edilmesiyle aynıdır ve aynı araçlar ve teknikler kullanılabilir.