MSTestasserties

Gebruik de Assert klassen van de Microsoft.VisualStudio.TestTools.UnitTesting naamruimte om specifieke functionaliteit te verifiëren. Een testmethode oefent de code in uw toepassing, maar rapporteert de juistheid alleen wanneer u instructies opneemt Assert.

Overzicht

MSTest biedt drie assertieklassen:

Class Purpose
Assert Algemene asserties voor waarden, typen en uitzonderingen.
StringAssert String-specifieke asserties voor patronen, subtekenreeksen en vergelijkingen.
CollectionAssert Verzamelingsverklaringen voor het vergelijken en valideren van verzamelingen.

Belangrijk

Gebruik de Assert klasse altijd voor nieuwe code. De StringAssert en CollectionAssert klassen worden waarschijnlijk afgeschaft in een toekomstige release. Ze worden voornamelijk onderhouden voor achterwaartse compatibiliteit, maar worden niet aanbevolen omdat het opdelen van asserties over drie typen de vindbaarheid schaadt.

Alle assertiemethoden accepteren een optionele berichtparameter die wordt weergegeven wanneer de assertie mislukt, zodat u de oorzaak kunt identificeren:

Assert.AreEqual(expected, actual, "Values should match after processing");

De Assert klasse

Gebruik de Assert-klasse om te controleren of de code onder test werkt zoals verwacht.

Opmerking

Vanaf MSTest 4.0 worden de argumentexpressie door alle Assert API's vastgelegd en opgenomen in foutberichten. Deze ondersteuning biedt uitgebreidere diagnostische gegevens zonder handmatige message parameter.

Algemene assertiemethoden

[TestMethod]
public async Task AssertExamples()
{
    // Equality
    Assert.AreEqual(5, calculator.Add(2, 3));
    Assert.AreNotEqual(0, result);

    // Reference equality
    Assert.AreSame(expected, actual);
    Assert.AreNotSame(obj1, obj2);

    // Boolean conditions
    Assert.IsTrue(result > 0);
    Assert.IsFalse(string.IsNullOrEmpty(name));

    // Null checks
    Assert.IsNull(optionalValue);
    Assert.IsNotNull(requiredValue);

    // Type checks
    Assert.IsInstanceOfType<IDisposable>(obj);
    Assert.IsNotInstanceOfType<string>(obj);

    // Exception testing (MSTest v3.8+)
    Assert.ThrowsExactly<ArgumentNullException>(() => service.Process(null!));
    await Assert.ThrowsExactlyAsync<InvalidOperationException>(
        async () => await service.ProcessAsync());
}

De methode Assert.That

Vanaf MSTest 4.0 evalueert Assert.That elke Booleaanse expressie en produceert het een duidelijke foutmelding. Voor uitgebreidere diagnostische gegevens gebruikt Assert.That[CallerArgumentExpression] om de tekst van de expressie automatisch vast te leggen.

Assert.That(order.Total > 0);

Beschikbare API's

Opmerking

Vanaf MSTest 3.8 omvatten asserties voor verzamelingen Assert.Contains, Assert.DoesNotContain, Assert.HasCount, Assert.IsEmpty, Assert.IsNotEmpty en Assert.ContainsSingle.

Vanaf MSTest 3.10 zijn vergelijkingsverklaringen onder andere Assert.IsInRange, , Assert.IsGreaterThan, Assert.IsGreaterThanOrEqualToAssert.IsLessThan, , Assert.IsLessThanOrEqualToen . Assert.IsPositiveAssert.IsNegative

Vanaf MSTest 3.10 omvatten asserties voor tekenreeksvergelijking Assert.StartsWith, Assert.EndsWith, Assert.MatchesRegex, Assert.DoesNotStartWith, Assert.DoesNotEndWith en Assert.DoesNotMatchRegex.

Vanaf MSTest 4.1 moeten Assert.IsExactInstanceOfType en Assert.IsNotExactInstanceOfType exact hetzelfde type hebben. Anders dan Assert.IsInstanceOfTypekomen deze methoden niet overeen met afgeleide typen.

Nieuwe verzamelings- en gelijkwaardigheidsverklaringen in MSTest 4.3

Opmerking

De volgende assertiemethoden zijn geïntroduceerd in MSTest 4.3.0.

  • Assert.AreSequenceEqual / Assert.AreNotSequenceEqual — vergelijking van elementen. Geef door SequenceOrder.InAnyOrder om de volgorde van elementen te negeren.
  • Assert.AreEquivalent / Assert.AreNotEquivalent — grondige structurele vergelijking van twee objecten of verzamelingen.
  • Assert.ContainsAll / Assert.DoesNotContainAll — bevestig dat een verzameling elk verwacht element bevat (of niet bevat).
  • Assert.AreAllNotNull — controleer of elk element van een verzameling niet null is.
  • Assert.AreAllDistinct — bevestig dat alle elementen van een verzameling verschillend zijn.
  • Assert.AreAllOfType — bevestig dat elk element van een verzameling van een verwacht type is.

Gebruik bij het vergelijken van verzamelingen liever deze methoden dan Assert.AreEqual, omdat daarmee referenties in plaats van elementen worden vergeleken.

MSTest 4.3 voegt ook het volgende toe:

  • De experimentele Assert.AddValueFormatter API om aan te passen hoe waarden worden weergegeven in foutberichten voor asserties.
  • Span<T> en Memory<T> overbelasting voor Assert.HasCount.
  • Foutberichten voor gestructureerde assertie voorAssert.IsTrue, Assert.IsFalseen Assert.IsNullAssert.IsNotNulldie de geëvalueerde expressie bevatten.
  • Overloads voor berichten met geïnterpoleerde tekenreeksen voor de async Assert.ThrowsAsync/Assert.ThrowsExactlyAsync-methoden, en afwijzing van ValueTask<TResult>-retournerende delegates die anders niet zouden worden afgewacht.
  • Volledige uitzonderingsdetails, waaronder stacktraceringen en interne uitzonderingen, in Assert.Throws* foutberichten.
  • Assertiefoutstacks die MSTest-implementatieframes verbergen en ingebouwde numerieke waarden weergeven met volledige precisie.

Assert.AddValueFormatter retourneert een IDisposable registratie. Verwijder de registratie om de formatter te verwijderen. De formatter is alleen van toepassing op de huidige asynchrone context, zodat parallelle tests verschillende formatters kunnen gebruiken zonder elkaars uitvoer te wijzigen. Omdat de API experimenteel is in MSTest 4.3, bevestigt of onderdrukt u de MSTESTEXP diagnose voordat u deze gebruikt.

Zachte asserties met Assert.Scope()

Belangrijk

Assert.Scope() is een experimentele API. Het gebruik ervan veroorzaakt de MSTESTEXP-diagnostische melding, die u onderdrukt (bijvoorbeeld met #pragma warning disable MSTESTEXP of in het .editorconfig-bestand van uw project) om te erkennen dat de structuur en het gedrag van de API in toekomstige releases kunnen veranderen.

Standaard genereert elke bewering een AssertFailedException zodra deze mislukt, waardoor de test onmiddellijk wordt beëindigd. Assert.Scope() introduceert soepele asserties: zolang een bereik actief is, worden assertiefouten verzameld in plaats van opgeworpen, zodat de uitvoering doorgaat en u alle fouten binnen het bereik in één keer kunt zien. Wanneer de scope wordt vrijgegeven, worden de verzamelde fouten in één keer gerapporteerd:

[TestMethod]
public void ValidatePerson()
{
    using (Assert.Scope())
    {
        Assert.AreEqual("Jane", person.FirstName); // failure collected, execution continues
        Assert.AreEqual("Doe", person.LastName);   // failure collected, execution continues
        Assert.IsTrue(person.IsActive);            // failure collected, execution continues
    }
    // On Dispose, all collected failures are reported together.
}

Wanneer de scope wordt vrijgegeven:

  • Als er precies één fout is verzameld, wordt de oorspronkelijke AssertFailedException opgeworpen.
  • Als er meerdere fouten werden verzameld, wordt één AssertFailedException opgeworpen die al deze fouten omvat in een AggregateException.

Postconditions worden niet afgedwongen binnen een scope

Omdat een mislukte assertie binnen een scope niet langer een uitzondering veroorzaakt, kan code die daarna wordt uitgevoerd er niet van uitgaan dat de assertie is geslaagd. Dit geldt voor elke postconditie, inclusief nullbaarheid en typevernauwing:

using (Assert.Scope())
{
    Assert.IsNotNull(item);
    // 'item' might still be null here: the failure was collected, not thrown.
    Assert.AreEqual("expected", item.Value);
    // 'item.Value' might not equal "expected" either.
}

Als een mislukte assertie later binnen dezelfde scope tot een NullReferenceException (of een andere uitzondering) zou leiden, dan is die secundaire uitzondering een symptoom van de al geregistreerde fout, niet een aparte fout. De oorspronkelijke assertiefout wordt nog steeds gemeld wanneer de scope wordt opgeruimd.

Asserties die een waarde retourneren, retourneren null/default bij een mislukking binnen een scope

Sommige asserties geven bij succes een waarde terug; zo retourneren Throws en ThrowsExactly bijvoorbeeld de opgevangen uitzondering, en retourneert ContainsSingle het overeenkomstige element. Wanneer een van deze asserties mislukt binnen een scope, wordt de fout vastgelegd en retourneert de methode null/default in plaats van een uitzondering te genereren:

using (Assert.Scope())
{
    // No exception is thrown by the lambda, so the assertion fails. The failure is
    // collected and 'ex' is null. Accessing 'ex' below throws NullReferenceException.
    InvalidOperationException ex = Assert.Throws<InvalidOperationException>(() => { });
    _ = ex.Message; // NullReferenceException—don't use the return value in a scope
}

Vertrouw niet op de waarde die een soft assertion retourneert binnen een scope. Als u de geretourneerde waarde (zoals de opgevangen uitzondering) nodig hebt, roept u de assertie buiten het bereik aan, of past u de test zo aan dat niets afhankelijk is van de retourwaarde totdat het bereik is beëindigd.

Assert.Fail en Assert.Inconclusive gooi altijd

Fail en Inconclusive zijn nooit zacht. Ze werpen altijd onmiddellijk, zelfs binnen een scope, omdat ze een onvoorwaardelijke testuitkomst vertegenwoordigen. Gebruik een van deze voorwaarden wanneer een voorwaarde kritiek is en de rest van de test niet zinvol kan doorgaan zonder deze.

Geneste scopes worden niet ondersteund

Je kunt geen Assert.Scope()-aanroepen nesten. Slechts één assertiebereik kan tegelijk actief zijn.

De StringAssert klasse

Gebruik de StringAssert klasse om tekenreeksen te vergelijken en te onderzoeken.

Waarschuwing

De StringAssert klasse wordt waarschijnlijk afgeschaft in een toekomstige release. Het wordt alleen onderhouden voor achterwaartse compatibiliteit en wordt niet aanbevolen voor nieuwe code. Alle StringAssert methoden hebben equivalenten voor de Assert klasse, wat betere vindbaarheid biedt. Als u bestaande gebruiksrechten wilt migreren, raadpleegt u analyzer MSTEST0046.

Beschikbare API's zijn:

De CollectionAssert klasse

Gebruik de CollectionAssert klasse om verzamelingen objecten te vergelijken of om de status van een verzameling te controleren.

Waarschuwing

De CollectionAssert klasse wordt waarschijnlijk afgeschaft in een toekomstige release. Het wordt voornamelijk onderhouden voor achterwaartse compatibiliteit en wordt niet aanbevolen voor nieuwe code. Wanneer er op Assert een equivalente methode bestaat (zoals Assert.Contains, Assert.DoesNotContain of Assert.HasCount), gebruik dan Assert voor een betere vindbaarheid.

Beschikbare API's zijn:

Aangepaste asserties maken met Assert.That

De ingebouwde assertiemethoden hebben niet betrekking op elk scenario. Om de assertie-infrastructuur uit te breiden met uw eigen controles, maakt MSTest de Assert.That singleton-eigenschap beschikbaar als een uitbreidbaarheidshook. U voegt aangepaste asserties toe als C#-extensiemethoden voor het Assert exemplaartype en bellers roepen deze aan met de vertrouwde Assert.That.MyAssertion(...) syntaxis.

Voor een betere detectie kunt u projectbrede asserties organiseren in een toegewezen statische klasse. Aangepaste asserties die worden bereikt via Assert.That worden weergegeven naast de ingebouwde methoden in IntelliSense, zodat consumenten geen afzonderlijk helpertype hoeven te onthouden.

Een aangepaste assertie maken

Voeg een extensiemethode toe die is gericht op het Assert type en genereert AssertFailedException wanneer de voorwaarde mislukt:

using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

public static class CustomAssertExtensions
{
    public static void IsPrime(this Assert assert, int value)
    {
        if (value < 2 || Enumerable.Range(2, (int)Math.Sqrt(value) - 1).Any(i => value % i == 0))
        {
            throw new AssertFailedException($"Assert.That.IsPrime failed. Value <{value}> is not a prime number.");
        }
    }
}

Een aangepaste assertie gebruiken

Nadat u de naamruimte hebt geïmporteerd die uw extensiemethoden bevat, roept u uw aangepaste assertie aan via Assert.That:

[TestMethod]
public void Compute_ReturnsPrime()
{
    int result = _calculator.NextPrime(10);
    Assert.That.IsPrime(result);
}

Extensiehooks op StringAssert en CollectionAssert

De eigenschappen StringAssert.That en CollectionAssert.That bieden hetzelfde singleton-patroon voor achterwaartse compatibiliteit. Voor nieuwe aangepaste asserties moet u zich altijd richten op Assert.That. Anders erven uw helpers dezelfde vindbaarheidsproblemen als de verouderde klassen en moeten ze worden gemigreerd als StringAssert en CollectionAssert verouderd worden verklaard.

Assert.That eigenschap versus Assert.That(...) methode

Opmerking

Verwar de Assert.Thatsingleton-eigenschap, gebruikt als uitbreidbaarheidshook, niet met de Assert.That(() => condition)methode die is toegevoegd in MSTest 3.8. De laatste accepteert een Boole-expressie en produceert gedetailleerde foutberichten door de expressiestructuur te analyseren (bijvoorbeeld Assert.That(() => order.Total > 0)). De twee API's delen een naam, maar dienen verschillende doeleinden.

Beste praktijken

  • Gebruik specifieke asserties: Geef de voorkeur aan AreEqual boven IsTrue(a == b) voor betere foutmeldingen.

  • Beschrijvende berichten opnemen: Hulp bij het snel identificeren van fouten met duidelijke assertieberichten.

  • Test één ding tegelijk: Elke testmethode moet één gedrag verifiëren.

  • Gebruiken Throws/ThrowsExactly voor uitzonderingen: geef in MSTest v3.8+ de voorkeur Assert.Throwsaan , Assert.ThrowsExactlyen hun asynchrone tegenhangers (ThrowsAsync, ThrowsExactlyAsync) boven het ExpectedException kenmerk.

  • Geef de voorkeur aan Assert boven StringAssert/CollectionAssert: Gebruik voor een betere vindbaarheid en consistentie de klasse Assert. De StringAssert en CollectionAssert klassen worden waarschijnlijk afgeschaft in een toekomstige release.

  • Uitbreiden Assert.That voor aangepaste asserties: voor consistente detectie voegt u aangepaste asserties toe als uitbreidingsmethoden Assert en roept u deze aan via Assert.That. Richt nieuwe code niet op StringAssert.That of CollectionAssert.That.

Met de volgende analysen kunt u het juiste gebruik van asserties garanderen:

  • MSTEST0006 : vermijd ExpectedException kenmerk, gebruik Assert.Throws in plaats daarvan methoden.
  • MSTEST0017 - Assertieargumenten moeten in de juiste volgorde worden doorgegeven.
  • MSTEST0023 - Negeren van booleaanse beweringen is niet toegestaan.
  • MSTEST0025 - Geef de voorkeur aan Assert.Fail boven altijd-onwaar condities.
  • MSTEST0026 - Assertieargumenten moeten voorwaardelijke toegang voorkomen.
  • MSTEST0032 - Altijd waar zijnde assertiecondities controleren.
  • MSTEST0037 : gebruik de juiste assertiemethoden.
  • MSTEST0038 : vermijd Assert.AreSame met waardetypen.
  • MSTEST0039 : nieuwere Assert.Throws methoden gebruiken.
  • MSTEST0040 : vermijd het gebruik van asserties in asynchrone context.
  • MSTEST0046 - Gebruiken Assert in plaats van StringAssert.
  • MSTEST0051 - Assert.Throws moet één enkele instructie bevatten.
  • MSTEST0053 : notatieparameters vermijden Assert .
  • MSTEST0058 : vermijd asserties in vangstblokken.

Zie ook