Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
MSTest tillhandahåller en väldefinierad livscykel för testklasser och testmetoder, så att du kan utföra konfigurations- och nedrullningsåtgärder i olika skeden av testkörningen. Genom att förstå livscykeln kan du skriva effektiva tester och undvika vanliga fallgropar.
Livscykelöversikt
Livscykeln grupperas i fyra steg, som körs från högsta nivå (sammansättning) till lägsta nivå (testmetod):
- Sammansättningsnivå: Körs en gång när testsammansättningen läses in och tas bort
- Klassnivå: Körs en gång per testklass
- Global testnivå: Körs före och efter varje testmetod i sammansättningen
- Testnivå: Körs för varje testmetod (inklusive varje datarad i parametriserade tester)
Livscykel på sammansättningsnivå
Metoder för assembly-livscykel körs en gång när testassemblyn läser in och avläser. Använd dessa för dyra engångskonfigurationer som databasinitiering eller start av tjänsten.
AssemblyInitialize och 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!);
}
}
Kravspecifikation
- Metoderna måste vara
public static - Returtyp:
void,TaskellerValueTask(MSTest v3.3+) -
AssemblyInitializekräver enTestContextparameter -
AssemblyCleanupaccepterar noll parametrar eller enTestContextparameter (MSTest 3.8+) - Endast ett av varje attribut tillåts per sammansättning
- Måste finnas i en klass som är markerad med
[TestClass]
Tips/Råd
Relaterade analysverktyg:
-
MSTEST0012 – verifierar
AssemblyInitializesignaturen. -
MSTEST0013 – verifierar
AssemblyCleanupsignaturen.
Livscykel på klassnivå
Klasslivscykelmetoder körs en gång per testklass, före och efter alla testmetoder i den klassen. Använd dessa för konfiguration som delas mellan tester i en klass.
ClassInitialize och 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()
{
var response = await _client!.GetAsync("/users");
Assert.IsTrue(response.IsSuccessStatusCode);
}
}
Kravspecifikation
- Metoderna måste vara
public static - Returtyp:
void,TaskellerValueTask(MSTest v3.3+) -
ClassInitializekräver enTestContextparameter -
ClassCleanupaccepterar noll parametrar eller enTestContextparameter (MSTest 3.8+) - Endast ett av varje attribut tillåts per klass
Arvsbeteende
Kontrollera om ClassInitialize körs för härledda klasser med hjälp av InheritanceBehavior:
[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
}
}
| InheritanceBehavior | Description |
|---|---|
None (standardinställning) |
Initiera endast körningar för deklareringsklassen |
BeforeEachDerivedClass |
Initiera exekveringar före varje härledd klass |
Tips/Råd
Relaterade analysverktyg:
-
MSTEST0010 – verifierar
ClassInitializesignaturen. -
MSTEST0011 – verifierar
ClassCleanupsignaturen. -
MSTEST0034 – rekommenderar att du använder
ClassCleanupBehavior.EndOfClass.
Global livscykel på testnivå
Anmärkning
Globala livscykelattribut för test introducerades i MSTest 3.10.0.
Globala testlivscykelmetoder körs före och efter varje testmetod i hela sammansättningen, utan att behöva lägga till kod i varje testklass.
GlobalTestInitialize och 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}");
}
}
Kravspecifikation
- Metoderna måste vara
public static - Returtyp:
void,TaskellerValueTask - Måste ha exakt en
TestContextparameter - Måste finnas i en klass som är markerad med
[TestClass] - Flera metoder med dessa attribut tillåts i hela sammansättningen
Anmärkning
När det finns flera metoder av typen GlobalTestInitialize eller GlobalTestCleanup, garanteras inte körningsordningen.
TimeoutAttribute Stöds inte på GlobalTestInitialize metoder.
Tips/Råd
Relaterat analysverktyg: MSTEST0050 – validerar globala testfixturmetoder.
Livscykel på testnivå
Livscykel på testnivå körs för varje testmetod. För parametriserade tester körs livscykeln för varje datarad.
Installationsfas
Använd TestInitialize eller en konstruktor för konfiguration per test:
[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()
{
var result = _calculator!.Add(2, 3);
Assert.AreEqual(5, result);
}
}
Konstruktor jämfört med TestInitialize:
| Aspekt | Konstruktor | TestInitialize |
|---|---|---|
| Async-stöd | Nej | Yes |
| Stöd för timeout | Nej | Ja (med [Timeout] attribut) |
| Körningsordning | Först | Efter konstruktor |
| Arv | Bas som sedan härleds | Bas som sedan härleds |
| Undantagsbeteende | Cleanup och Dispose körs inte (det finns ingen instans) | Rensning och bortskaffning körs fortfarande |
Tips/Råd
Vilken metod ska jag använda? Konstruktorer är vanligtvis att föredra eftersom de gör att du kan använda fälten readonly, vilket säkerställer oföränderlighet och gör din testklass lättare att förstå. Använd TestInitialize när du behöver asynkron initiering eller timeout-stöd.
Du kan också kombinera båda metoderna: använd konstruktorn för enkel synkron initiering av fält och readonly för ytterligare asynkron konfiguration som är beroende av TestInitialize dessa fält.
Du kan också aktivera kodanalyserare för att framtvinga en konsekvent metod:
- MSTEST0019 – Föredrar TestInitialisera metoder framför konstruktorer
- MSTEST0020 – Föredrar konstruktorer framför TestInitialize-metoder
Utförandefas
Testmetoden körs när installationen har slutförts. För async testmetoder väntar MSTest på den returnerade Task eller ValueTask.
Varning
Asynkrona testmetoder har inte någon SynchronizationContext som standard. Detta gäller inte för UITestMethod tester i UWP och WinUI, som körs på användargränssnittstråden.
Klareringsfas
Använd TestCleanup eller IDisposable/IAsyncDisposable för rensning per test:
[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()
{
var response = await _client!.GetAsync("https://example.com");
Assert.IsTrue(response.IsSuccessStatusCode);
}
}
Körningsordning för rensning (härledd till bas):
-
TestCleanup(härledd klass) -
TestCleanup(basklass) -
DisposeAsync(om det implementeras) -
Dispose(om det implementeras)
Tips/Råd
Du kan också aktivera kodanalyserare för att tillämpa en konsekvent rensningsmetod:
- MSTEST0021 – Föredra Dispose framför TestCleanup-metoder
- MSTEST0022 – Föredrar TestCleanup framför borttagningsmetoder
Om du har icke-MSTest-analysverktyg aktiverade, till exempel .NET-kodanalysregler, kan CA1001 föreslå att du implementerar borttagningsmönstret när testklassen äger disponibla resurser. Detta är ett förväntat beteende och du bör följa analysatorns vägledning.
Slutför testnivåbeställning
- Skapa en instans av testklassen (konstruktor)
- Ange
TestContextegenskap (om det finns) - Kör
GlobalTestInitializemetoder - Utför
TestInitialize-metoder (från bas till härledd) - Kör testmetod
- Uppdatera
TestContextmed resultat (till exempelOutcomeegenskap) - Kör
TestCleanupmetoder (från härledda till bas) - Kör
GlobalTestCleanupmetoder - Kör
DisposeAsync(om det implementeras) - Kör
Dispose(om det implementeras)
Tips/Råd
Relaterade analysverktyg:
-
MSTEST0008 – validerar
TestInitializesignaturen. -
MSTEST0009 – validerar
TestCleanupsignaturen. - MSTEST0063 – validerar konstruktorn för testklassen.
Metodtips
Använd lämpligt omfång: Placera konfigurationen på den högsta nivån som är lämplig för att undvika redundant arbete.
Håll installationen snabb: Långvarig installation påverkar alla tester. Överväg lat initiering för dyra resurser.
Rensa ordentligt: Rensa alltid resurser för att förhindra testinterferens och minnesläckor.
Hantera asynkront på rätt sätt: Använd
async Taskreturtyper, inteasync void, för asynkrona metoder.Överväg testisolering: Varje test bör vara oberoende. Undvik delat föränderligt tillstånd mellan tester.
Använd GlobalTest sparsamt: Globala livscykelmetoder körs för varje test, så håll dem lätta.