Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
MSTest, test sınıfları ve test yöntemleri için iyi tanımlanmış bir yaşam döngüsü sağlar ve test yürütmenin çeşitli aşamalarında kurulum ve kaldırma işlemleri gerçekleştirmenizi sağlar. Yaşam döngüsünü anlamak verimli testler yazmanıza ve yaygın tuzaklardan kaçınmanıza yardımcı olur.
Yaşam döngüsüne genel bakış
Yaşam döngüsü, en yüksek düzeyden (derleme) en düşük düzeye (test yöntemi) yürütülen dört aşamaya ayrılır:
- Derleme düzeyi: Test derlemesi yüklendiğinde ve kaldırıldığında bir kez çalışır
- Sınıf düzeyi: Test sınıfı başına bir kez çalışır
- Genel test düzeyi: Derlemedeki her test yönteminden önce ve sonra çalışır
- Test düzeyi: Her test yöntemi için çalışır (parametreli testlerdeki her veri satırı dahil)
Derleme düzeyinde yaşam döngüsü
Test derlemesi yüklenip kaldırıldığında derleme yaşam döngüsü yöntemleri bir kez çalıştırılır. Veritabanı başlatma veya hizmet başlatma gibi tek seferlik pahalı kurulumlar için bunları kullanın.
AssemblyInitialize ve AssemblyCleanup
[TestClass]
public class AssemblyLifecycleExample
{
private static IHost? _host;
[AssemblyInitialize]
public static async Task AssemblyInit(TestContext context)
{
// Runs once before any tests in the assembly
_host = await StartTestServerAsync();
context.WriteLine("Test server started");
}
[AssemblyCleanup]
public static async Task AssemblyCleanup(TestContext context)
{
// Runs once after all tests complete
// TestContext parameter available in MSTest 3.8+
if (_host != null)
{
await _host.StopAsync();
}
}
private static Task<IHost> StartTestServerAsync()
{
// Server initialization
return Task.FromResult<IHost>(null!);
}
}
Gereksinimler
- Yöntemler şu şekilde olmalıdır:
public static - Dönüş türü:
void,TaskveyaValueTask(MSTest v3.3+) -
AssemblyInitializebirTestContextparametre gerektirir -
AssemblyCleanupsıfır parametre veya birTestContextparametre kabul eder (MSTest 3.8+) - Her öznitelikten yalnızca birine derleme başına izin verilir.
-
[TestClass]ile işaretlenmiş bir sınıfta olmalıdır
Tavsiye
İlgili çözümleyiciler:
-
MSTEST0012 - imzayı doğrular
AssemblyInitialize. -
MSTEST0013 - imzayı doğrular
AssemblyCleanup.
Sınıf düzeyinde yaşam döngüsü
Sınıf yaşam döngüsü yöntemleri, o sınıftaki tüm test yöntemlerinden önce ve sonra test sınıfı başına bir kez çalışır. Bir sınıftaki testler arasında paylaşılan kurulum için bunları kullanın.
ClassInitialize ve ClassCleanup
[TestClass]
public class ClassLifecycleExample
{
private static HttpClient? _client;
[ClassInitialize]
public static void ClassInit(TestContext context)
{
// Runs once before any tests in this class
_client = new HttpClient
{
BaseAddress = new Uri("https://api.example.com")
};
}
[ClassCleanup]
public static void ClassCleanup()
{
// Runs after all tests in this class complete
_client?.Dispose();
}
[TestMethod]
public async Task GetUsers_ReturnsSuccess()
{
HttpResponseMessage response = await _client!.GetAsync("/users");
Assert.IsTrue(response.IsSuccessStatusCode);
}
}
Gereksinimler
- Yöntemler şu şekilde olmalıdır:
public static - Dönüş türü:
void,TaskveyaValueTask(MSTest v3.3+) -
ClassInitializebirTestContextparametre gerektirir -
ClassCleanupsıfır parametre veya birTestContextparametre kabul eder (MSTest 3.8+) - Sınıf başına izin verilen her özniteliklerden yalnızca biri
Devralma davranışı
Türetilmiş sınıfların çalıştırılıp çalıştırılmayacağını ClassInitialize kullanarak InheritanceBehavior denetleyin.
[TestClass]
public class BaseTestClass
{
[ClassInitialize(InheritanceBehavior.BeforeEachDerivedClass)]
public static void BaseClassInit(TestContext context)
{
// Runs before each derived class's tests
}
}
[TestClass]
public class DerivedTestClass : BaseTestClass
{
[TestMethod]
public void DerivedTest()
{
// BaseClassInit runs before this class's tests
}
}
| DevralmaDavranışı | Description |
|---|---|
None (varsayılan) |
Başlatma yalnızca beyan eden sınıf için çalıştırılır. |
BeforeEachDerivedClass |
Her türetilmiş sınıftan önce işlemleri başlatma |
Tavsiye
İlgili çözümleyiciler:
-
MSTEST0010 - imzayı doğrular
ClassInitialize. -
MSTEST0011 - İmzayı doğrular
ClassCleanup. -
MSTEST0034 -
ClassCleanupBehavior.EndOfClasskullanılmasını önerir.
Genel test düzeyi yaşam döngüsü
Uyarı
Genel test yaşam döngüsü öznitelikleri MSTest 3.10.0'da sunulmuştur.
Genel test yaşam döngüsü yöntemleri, her test sınıfına kod eklemeye gerek kalmadan derlemenin tamamında her test yönteminden önce ve sonra çalışır.
GlobalTestInitialize ve GlobalTestCleanup
[TestClass]
public class GlobalTestLifecycleExample
{
[GlobalTestInitialize]
public static void GlobalTestInit(TestContext context)
{
// Runs before every test method in the assembly
context.WriteLine($"Starting test: {context.TestName}");
}
[GlobalTestCleanup]
public static void GlobalTestCleanup(TestContext context)
{
// Runs after every test method in the assembly
context.WriteLine($"Finished test: {context.TestName}");
}
}
Gereksinimler
- Yöntemler şu şekilde olmalıdır:
public static - Dönüş türü:
void,TaskveyaValueTask - Tam olarak bir
TestContextparametre olmalıdır -
[TestClass]ile işaretlenmiş bir sınıfta olmalıdır - Derlemede bu özniteliklere sahip birden çok yönteme izin verilir
Uyarı
Birden çok GlobalTestInitialize veya GlobalTestCleanup yöntem mevcut olduğunda yürütme sırası garanti değildir.
TimeoutAttribute yöntemlerinde GlobalTestInitialize desteklenmez.
Tavsiye
İlgili çözümleyici: MSTEST0050 - genel test fikstür yöntemlerini doğrular.
Test seviyesi yaşam döngüsü
Her test yöntemi için test düzeyinde yaşam döngüsü çalışır. Parametreli testler için yaşam döngüsü her veri satırı için çalışır.
Kurulum aşaması
Test başına kurulum için TestInitialize veya bir yapıcı kullanın.
[TestClass]
public class TestLevelSetupExample
{
private Calculator? _calculator;
public TestLevelSetupExample()
{
// Constructor runs before TestInitialize
// Use for simple synchronous initialization
}
[TestInitialize]
public async Task TestInit()
{
// Runs before each test method
// Supports async, attributes like Timeout
_calculator = new Calculator();
await _calculator.InitializeAsync();
}
[TestMethod]
public void Add_TwoNumbers_ReturnsSum()
{
int result = _calculator!.Add(2, 3);
Assert.AreEqual(5, result);
}
}
Oluşturucu ve TestInitialize karşılaştırması:
| Görünüş | Yapıcı | TestInitialize |
|---|---|---|
| Asenkron destek | Hayı | Yes |
| Zaman aşımı desteği | Hayı | Evet ([Timeout] özniteliği ile) |
| Yürütme sırası | First | Oluşturucudan sonra |
| Inheritance | Temel sonra türetilir | Temel sonra türetilir |
| Özel durum davranışı | Temizleme ve Atma çalışmıyor (örnek yok) | Temizlik ve İmha işlemleri hala çalışıyor |
Tavsiye
Hangi yaklaşımı kullanmalıyım? Oluşturucular genellikle tercih edilir çünkü alanları readonly kullanmanıza olanak tanır ve bu da değişmezliği sağlar ve test sınıfınızın anlaşılmasını kolaylaştırır. Zaman uyumsuz başlatma veya zaman aşımı desteğine ihtiyacınız olduğunda TestInitialize kullanın.
Ayrıca her iki yaklaşımı da birleştirebilirsiniz: readonly alanlarını zaman uyumlu olarak basit bir şekilde başlatmak için oluşturucuyu kullanın ve bu alanlara bağımlı ek zaman uyumsuz kurulum için TestInitialize'i kullanın.
tutarlı bir yaklaşımı zorunlu kılmak için isteğe bağlı olarak kod çözümleyicilerini etkinleştirebilirsiniz:
- MSTEST0019 - Oluşturucular yerine TestInitialize yöntemlerini tercih edin
- MSTEST0020 - TestInitialize yöntemleri yerine oluşturucuları tercih edin
Yürütme aşaması
Kurulum tamamlandıktan sonra test yöntemi yürütülür. Test yöntemleri için async MSTest döndürülen Task veya ValueTasköğesini bekler.
Uyarı
Zaman uyumsuz test yöntemlerinin varsayılan olarak bir SynchronizationContext değeri yoktur. Bu, kullanıcı arabirimi iş parçacığında çalışan UWP ve WinUI'deki testler için UITestMethod geçerli değildir.
Temizleme aşaması
Test başına temizleme için TestCleanup veya IDisposable/IAsyncDisposable kullanın.
[TestClass]
public class TestLevelCleanupExample
{
private HttpClient? _client;
[TestInitialize]
public void TestInit()
{
_client = new HttpClient();
}
[TestCleanup]
public void TestCleanup()
{
if (_client != null)
{
_client.Dispose();
}
}
[TestMethod]
public async Task GetData_ReturnsSuccess()
{
HttpResponseMessage response = await _client!.GetAsync("https://example.com");
Assert.IsTrue(response.IsSuccessStatusCode);
}
}
Temizleme yürütme sırası (temel olarak türetilir):
-
TestCleanup(türetilmiş sınıf) -
TestCleanup(temel sınıf) -
DisposeAsync(uygulandıysa) -
Dispose(uygulandıysa)
Tavsiye
tutarlı bir temizleme yaklaşımını zorunlu kılmak için isteğe bağlı olarak kod çözümleyicilerini etkinleştirebilirsiniz:
- MSTEST0021 - TestCleanup yöntemleri yerine Dispose'ı tercih edin
- MSTEST0022 - Dispose yöntemleri yerine TestCleanup'ı tercih edin
.NET kod analizi kuralları gibi MSTest dışı çözümleyiciler etkinleştirildiyse, test sınıfınız atılabilir kaynaklara sahip olduğunda atma desenini uygulamanızı öneren CA1001 görebilirsiniz. Bu beklenen bir davranıştır ve çözümleyicinin yönergelerini izlemeniz gerekir.
Test düzeyi sırasını tamamla
- Test sınıfının örneğini oluşturma (oluşturucu)
- Özelliği ayarla
TestContext(varsa) - Çalıştır
GlobalTestInitializeyöntemleri - Metotları çalıştır
TestInitialize(tabandan türetilmişe) - Test yöntemini yürütme
-
TestContextsonuçlarla güncelleştir (örneğin, birOutcomeözelliği) - Çalıştırma
TestCleanupyöntemleri (temel olarak türetilir) - Çalıştır
GlobalTestCleanupyöntemleri - Çalıştır
DisposeAsync(uygulandıysa) - Çalıştır
Dispose(uygulandıysa)
Tavsiye
İlgili çözümleyiciler:
-
MSTEST0008 - imzayı doğrular
TestInitialize. -
MSTEST0009 - imzayı doğrular
TestCleanup. - MSTEST0063 - Test sınıfı oluşturucuyu doğrular.
En iyi yöntemler
Uygun kapsamı kullanın: Yedekli çalışmalardan kaçınmak için kurulumu anlamlı olan en üst düzeye yerleştirin.
Kurulumu hızlı tutun: Uzun süre çalışan kurulum tüm testleri etkiler. Pahalı kaynaklar için yavaş başlatmayı göz önünde bulundurun.
Düzgün temizleme: Test müdahalesini ve bellek sızıntılarını önlemek için kaynakları her zaman temizleyin.
Test yalıtımını göz önünde bulundurun: Her test bağımsız olmalıdır. Testler arasında paylaşılan değişken durumdan kaçının.
GlobalTest'i tedbirli kullanın: Genel yaşam döngüsü yöntemleri her test için çalışır, bu nedenle bunları hafif tutun.