Isolare codice sottoposto a test con Microsoft Fakes

L'isolamento del codice è una strategia di test spesso implementata con strumenti come Microsoft Fakes, in cui il codice che si sta testando è separato dal resto dell'applicazione. Questa separazione viene ottenuta sostituendo parti dell'applicazione che interagiscono con il codice sottoposto a test con stub o shim. Si tratta di piccole parti di codice controllate dai test, che simulano il comportamento delle parti effettive che stanno sostituendo.

Il vantaggio di questo approccio è che consente di concentrarsi sul test delle funzionalità specifiche del codice in isolamento. Se un test non riesce, si sa che la causa si trova all'interno del codice isolato e non in un'altra posizione. Inoltre, l'uso di stub e shim, fornito da Microsoft Fakes, consente di testare il codice anche se altre parti dell'applicazione non funzionano ancora.

Requisiti

  • Visual Studio Enterprise
  • Un progetto .NET Framework
  • .NET Core, .NET 5.0 o versione successiva e supporto del progetto in stile SDK in anteprima in Visual Studio 2019 Update 6 ed è abilitato per impostazione predefinita nell'aggiornamento 8. Per altre informazioni, vedere Microsoft Fakes per i progetti in stile .NET Core e SDK.

Nota

La profilatura con Visual Studio non è disponibile per i test che usano Microsoft Fakes.

Il ruolo di Microsoft Fakes nell'isolamento del codice

Microsoft Fakes svolge un ruolo fondamentale nell'isolamento del codice fornendo due meccanismi: stub e shim.

  • Stub: vengono usati per sostituire una classe con un piccolo sostituto che implementa la stessa interfaccia. Ciò richiede che l'applicazione sia progettata in modo che ogni componente dipenda solo da interfacce, non da altri componenti.

  • Shim: vengono usati per modificare il codice compilato dell'applicazione in fase di esecuzione. Anziché effettuare una chiamata al metodo specificata, l'applicazione esegue il codice shim fornito dal test. Gli shim possono sostituire le chiamate agli assembly che non è possibile modificare, ad esempio assembly .NET.

In genere, gli stub vengono usati per le chiamate all'interno della soluzione di Visual Studio e gli shim per le chiamate ad altri assembly a cui si fa riferimento. Ciò è dovuto al fatto che all'interno della soluzione è consigliabile separare i componenti definendo le interfacce nel modo necessario per lo stub. Tuttavia, gli assembly esterni spesso non sono dotati di definizioni di interfaccia separate, quindi gli shim vengono usati.

Diagram that show Fakes replacing other components.

Consigli su Quando usare stub

Gli stub vengono in genere usati per le chiamate all'interno della soluzione di Visual Studio perché è consigliabile disaccoppiare i componenti definendo le interfacce nel modo necessario per lo stub. Tuttavia, gli assembly esterni, ad esempio System.dll, in genere non vengono forniti con definizioni di interfaccia separate, quindi gli shim vengono usati in questi casi.

L'uso degli stub comporta la progettazione dell'applicazione in modo che i diversi componenti non siano dipendenti l'uno dall'altro, ma solo dalle definizioni di interfaccia. Questo disaccoppiamento rende l'applicazione più affidabile e flessibile e consente di connettere il componente sottoposto a test alle implementazioni stub delle interfacce a scopo di test.

In pratica, è possibile generare tipi di stub dalle definizioni di interfaccia in Visual Studio, quindi sostituire il componente reale con lo stub nel test.

Consigli su Quando usare shim

Mentre gli stub vengono usati per le chiamate all'interno della soluzione Visual Studio, gli shim vengono in genere usati per le chiamate ad altri assembly a cui si fa riferimento. Questo perché gli assembly esterni, ad esempio System.dll, in genere non vengono forniti con definizioni di interfaccia separate, pertanto gli shim devono essere usati.

Esistono tuttavia alcuni fattori da considerare quando si usano gli shim:

Prestazioni: gli shim vengono eseguiti più lentamente perché riscrivono il codice in fase di esecuzione. Gli stub non hanno questo sovraccarico delle prestazioni e sono veloci quanto i metodi virtuali possono essere eseguiti.

Metodi statici, tipi sealed: è possibile usare solo gli stub per implementare le interfacce. Pertanto, i tipi stub non possono essere usati per metodi statici, metodi non virtuali, metodi virtuali sealed, metodi in tipi sealed e così via.

Tipi interni: sia gli stub che gli shim possono essere usati con tipi interni resi accessibili usando l'attributo InternalsVisibleToAttributeassembly .

Metodi privati: gli shim possono sostituire le chiamate ai metodi privati se tutti i tipi nella firma del metodo sono visibili. Gli stub possono sostituire solo i metodi visibili.

Interfacce e metodi astratti: gli stub forniscono implementazioni di interfacce e metodi astratti che possono essere usati nei test. Gli shim non possono instrumentare interfacce e metodi astratti perché sono privi di corpi di metodo.


Transizione di Microsoft Fakes in .NET Framework a progetti in stile SDK

Transizione dei progetti di test di .NET Framework che usano Microsoft Fakes a progetti .NET Framework, .NET Core o .NET 5+ di tipo SDK.

Sono necessarie modifiche minime in .NET Framework configurate per consentire a Microsoft Fakes di eseguire la transizione a .NET Core o .NET 5.0. I casi da considerare sono:

  • Se si usa un modello di progetto personalizzato, è necessario assicurarsi che sia di tipo SDK e di compilazione per un framework di destinazione compatibile.If you're using a custom project template, you need to ensure that it's SDK-style and build for a compatible target framework.

  • Alcuni tipi esistono in assembly diversi in .NET Framework e .NET Core/.NET 5.0 (ad esempio, System.DateTime esistono inmscorlib System/.NET Framework e System.Runtime in .NET Core e .NET 5.0) e in questi scenari è necessario modificare l'assembly fittizio.

  • Se si ha un riferimento all'assembly a un assembly fakes e al progetto di test, è possibile che venga visualizzato un avviso di compilazione relativo a un riferimento mancante simile al seguente:

    (ResolveAssemblyReferences target) ->
    warning MSB3245: Could not resolve this reference. Could not locate the assembly "AssemblyName.Fakes". Check to make sure the assembly exists on disk.
    If this reference is required by your code, you may get compilation errors.
    

    Questo avviso è dovuto alle modifiche necessarie apportate nella generazione Fakes e possono essere ignorate. È possibile evitare rimuovendo il riferimento all'assembly dal file di progetto, perché ora vengono aggiunti in modo implicito durante la compilazione.

Esecuzione di test di Microsoft Fakes

Finché gli assembly Microsoft Fakes sono presenti nella directory configurata FakesAssemblies (impostazione predefinita $(ProjectDir)FakesAssemblies), è possibile eseguire test usando l'attività vstest.

I test distribuiti con l'attività vstest .NET Core e i progetti .NET 5+ che usano Microsoft Fakes richiedono Visual Studio 2019 Update 9 Preview 20201020-06 e versioni successive.

Compatibilità e supporto per Microsoft Fakes in versioni diverse di .NET e Visual Studio

Microsoft Fakes nei progetti meno recenti destinati a .NET Framework (stile non SDK).

  • La generazione di assembly Microsoft Fakes è supportata in Visual Studio Enterprise 2015 e versioni successive.
  • I test Microsoft Fakes possono essere eseguiti con tutti i pacchetti NuGet Microsoft.TestPlatform disponibili.
  • Il code coverage è supportato per i progetti di test che usano Microsoft Fakes in Visual Studio Enterprise 2015 e versioni successive.

Microsoft Fakes in progetti .NET Framework, .NET Core e .NET 5.0 o versioni successive in stile SDK

  • Generazione di assembly Microsoft Fakes in anteprima in Visual Studio Enterprise 2019 Update 6 ed è abilitata per impostazione predefinita nell'aggiornamento 8.
  • I test Microsoft Fakes per i progetti destinati a .NET Framework possono essere eseguiti con tutti i pacchetti NuGet Microsoft.TestPlatform disponibili.
  • I test Di Microsoft Fakes per i progetti destinati a .NET Core e .NET 5.0 o versioni successive possono essere eseguiti con pacchetti NuGet Microsoft.TestPlatform con versioni 16.9.0-preview-20210106-01 e successive.
  • Il code coverage è supportato per i progetti di test destinati a .NET Framework usando Microsoft Fakes in Visual Studio Enterprise versione 2015 e successive.
  • Il supporto di code coverage per i progetti di test destinati a .NET Core e .NET 5.0 o versione successiva con Microsoft Fakes è disponibile in Visual Studio 2019 update 9 e versioni successive.