C # Test dell'unità in un singolo progetto

3

Bene, quindi sto facendo il mio primo progetto "reale" in C #. Sto sbuffando, divertendomi, un bel linguaggio che ho qui, abbastanza facile da usare, la ti da. Poi arrivo al punto in cui mi rendo conto che non esiste un modo semplice per impostare le classi di amici per i test unitari.

Bene. Questo è sfortunato.

Mi aggiro e scopro che posso saltare attraverso alcuni cerchi in fiamme ed esporre tutto a un altro assieme con:


[assembly: InternalsVisibleTo("AssemblyName")]

Ma ... questa è una app in-house piuttosto piccola che sto solo andando ad un singolo binario e non garantisce realmente più assembly. Quali altre opzioni, se ce ne sono, offre C #?

    
posta trycatch 24.03.2011 - 16:03
fonte

6 risposte

12

Qual è il problema con l'utilizzo di public di metodi e classi? I tuoi metodi dovrebbero essere incapsulati in modo appropriato e dovresti scrivere test su public e occasionalmente internal (che possono essere esposti ai tuoi assembly di test attraverso InternalsVisibleTo ) metodi.

Non dovresti provare i metodi privati. Ciò significa che stai testando i dettagli di implementazione invece di un contratto di comportamento. I tuoi test non dovrebbero preoccuparsi come si fa qualcosa, solo che fa viene fatto. Facendolo altrimenti aumenta le probabilità che i test risultino fragili e richieda una manutenzione extra quando il codice di produzione viene modificato.

Una tipica soluzione di installazione per C # è di avere un assembly (o più) per il codice di produzione e un assembly (o più) per i test. La suddivisione dell'assieme per il codice di produzione viene generalmente decisa in base alla funzionalità. Per una piccola app in-house staresti bene con una sola. Per i test, gli assembly vengono talvolta divisi in base al tipo di test eseguito - unità o integrazione.

Raccomando di seguire quel modello e di posizionare i test in un assembly separato che fa riferimento all'assembly del codice di produzione. Rendi pubbliche le tue classi / metodi e verifica quelle caratteristiche senza preoccuparti dei dettagli della loro implementazione nei test.

    
risposta data 24.03.2011 - 18:01
fonte
2

Potresti aggiungere un'ulteriore configurazione di build a Debug and Release chiamata Test o UnitTest e definire una direttiva del compilatore TEST o UNITTEST o qualsiasi altra cosa.

Quindi costruisci i tuoi test nello stesso assembly, anche nelle stesse classi se vuoi veramente testare i privati. Quindi avvolgere la classe di test oi metodi di test con #if TEST. In questo modo se costruisci come Test i test sono inclusi e il tuo assembly è testabile inclusi i privati. Crea come Debug o Release e non sono inclusi.

Forse è un po 'complicato includere test con l'assembly e non perfetto, ma l'abbiamo usato e funziona.

    
risposta data 24.03.2011 - 17:04
fonte
1

Nessuno. Non è possibile eseguire i test delle unità senza prima creare i test in un assieme. Ciò significa una delle due cose:

  • Invia tutto il codice di prova con il tuo prodotto. Non consigliato, in particolare se i tuoi test fanno qualcosa con un database.
  • Imballa il codice di prova in una DLL separata che viene utilizzata in house. Consigliato.

Anche il quadro di test unitario di Microsoft ha questa limitazione.

    
risposta data 24.03.2011 - 16:17
fonte
1
[assembly: InternalsVisibleTo("AssemblyName")]

Questo non espone tutto a un altro assembly. Questo espone membri contrassegnati come internal .

% membri dipublic sono ovviamente esposti per impostazione predefinita, tuttavia private e protected membri non lo sono.

Raccomandazione di Microsoft per unità testare metodi privati per utilizzare la reflection o i loro Accessors privati generati automaticamente: Procedura: test di un metodo privato

Per ottenere un metodo privato usando reflection:

using System.Reflection

MyClass instance = new MyClass();
MethodInfo privateMethod = instance.GetType().GetMethod("PrivateMethod", BindingFlags.NonPublic | BindingFlags.Instance);

Quindi esegui il metodo:

object returnvalue = privateMehtod.Invoke(instance, new object[] {any, parameters, the, method, needs});

Lo userò solo per test. Non lo userei per chiamare un metodo privato nel codice normale, perché è privato per un motivo.

    
risposta data 24.03.2011 - 16:46
fonte
0

Le tue altre opzioni stanno mettendo i test nello stesso assembly o rendendo più pubbliche le tue lezioni.

Personalmente, in genere vado con InternalsVisibleTo (ho appena scritto un piccolo progetto di Cmdlet Powershell con 20 test dispari e l'ho ancora fatto in quel modo). Sembra una cosa dubbiosa da fare quando lo fai per la prima volta, ma dopo un po 'diventa perfettamente naturale. Il fatto è che sei molto specifico su ciò che gli Internals saranno visibili.

    
risposta data 24.03.2011 - 16:15
fonte
0

C'è un modo migliore rispetto all'utilizzo di classi di amici. Se si utilizza MSTest, fare clic con il tasto destro del mouse su un nome di classe nella finestra dell'editor.

Nel menu contestuale che appare seleziona: Crea Accessorio privato. Quindi seleziona il tuo progetto di test.

Ciò che verrà fatto è creare una classe nel progetto di test che ti consenta di testare membri e metodi privati di una classe senza renderla pubblica.

Ecco come usi questo accessorio:

Foo foo = new Foo();

var shadowFoo = Foo_Accessor.AttachShadow(Foo);
shadowFoo._private ...

EDIT: Ecco un link su come usare gli accessor: link .

Vedi anche il mio commento per ulteriori informazioni.

    
risposta data 24.03.2011 - 17:03
fonte

Leggi altre domande sui tag