Domanda

Ho una classe che elabora 2 file XML e produce un file di testo.

Vorrei scrivere un mucchio di test unitari / di integrazione che possono superare o fallire individualmente per questa classe che procede come segue:

  1. Per gli input A e B, generare l'output.
  2. Confronta i contenuti del file generato con i contenuti previsti output
  3. Quando i contenuti effettivi differiscono dai contenuti previsti, non riesci e visualizzano alcune utili informazioni sulle differenze.

Di seguito è riportato il prototipo della classe insieme al mio primo colpo ai test unitari.

Esiste un modello che dovrei usare per questo tipo di test o le persone tendono a scrivere miliardi di funzioni TestX ()?

Esiste un modo migliore per convincere le differenze di file di testo da NUnit? Dovrei incorporare un algoritmo diff file di testo?


class ReportGenerator
{
    string Generate(string inputPathA, string inputPathB)
    {
        //do stuff
    }
}

[TextFixture]
public class ReportGeneratorTests
{
     static Diff(string pathToExpectedResult, string pathToActualResult)
     {
         using (StreamReader rs1 = File.OpenText(pathToExpectedResult))
         {
             using (StreamReader rs2 = File.OpenText(pathToActualResult))
             {
                 string actualContents = rs2.ReadToEnd();
                 string expectedContents = rs1.ReadToEnd();                  

                 //this works, but the output could be a LOT more useful.
                 Assert.AreEqual(expectedContents, actualContents);
             }
         }
     }

     static TestGenerate(string pathToInputA, string pathToInputB, string pathToExpectedResult)
     {
          ReportGenerator obj = new ReportGenerator();
          string pathToResult = obj.Generate(pathToInputA, pathToInputB);
          Diff(pathToExpectedResult, pathToResult);
     }

     [Test]
     public void TestX()
     {
          TestGenerate("x1.xml", "x2.xml", "x-expected.txt");
     }

     [Test]
     public void TestY()
     {
          TestGenerate("y1.xml", "y2.xml", "y-expected.txt");
     }

     //etc...
}

Aggiornamento

Non sono interessato a testare la funzionalità diff. Voglio solo usarlo per produrre errori più leggibili.

È stato utile?

Soluzione

Come per i test multipli con dati diversi, utilizzare l'estensione NUnit RowTest:

using NUnit.Framework.Extensions;

[RowTest]
[Row("x1.xml", "x2.xml", "x-expected.xml")]
[Row("y1.xml", "y2.xml", "y-expected.xml")]
public void TestGenerate(string pathToInputA, string pathToInputB, string pathToExpectedResult)
 {
      ReportGenerator obj = new ReportGenerator();
      string pathToResult = obj.Generate(pathToInputA, pathToInputB);
      Diff(pathToExpectedResult, pathToResult);
 }

Altri suggerimenti

Probabilmente stai chiedendo il test con " oro " dati. Non so se esiste un termine specifico per questo tipo di test accettato in tutto il mondo, ma è così che lo facciamo.

Crea la classe del dispositivo base. Fondamentalmente ha "void DoTest (string fileName)", che leggerà il file specifico in memoria, eseguirà il metodo di trasformazione astratto "string Transform (testo stringa)", quindi leggerà fileName.gold dallo stesso posto e confronterà il testo trasformato con ciò che era previsto. Se il contenuto è diverso, genera un'eccezione. L'eccezione generata contiene il numero di riga della prima differenza, nonché il testo della riga prevista ed effettiva. Poiché il testo è stabile, in genere si tratta di informazioni sufficienti per individuare immediatamente il problema. Assicurati di contrassegnare le linee con " Previsto: " e " Actual: " ;, o indovinerai per sempre quale è quando guardi i risultati del test.

Quindi, avrai specifici dispositivi di prova, in cui implementerai il metodo Transform che fa il lavoro giusto, e quindi avrai test che assomigliano a questo:

[Test] public void TestX() { DoTest("X"); }
[Test] public void TestY() { DoTest("Y"); }

Il nome del test fallito ti dirà immediatamente cosa non funziona. Naturalmente, è possibile utilizzare il test di riga per raggruppare test simili. Avere test separati aiuta anche in una serie di situazioni come ignorare i test, comunicare i test ai colleghi e così via. Non è un grosso problema creare uno snippet che creerà test per te in un secondo, impiegherai molto più tempo a preparare i dati.

Quindi avrai anche bisogno di alcuni dati di test e un modo in cui il tuo dispositivo di base lo troverà, assicurati di impostare delle regole per il progetto. Se il test fallisce, scarica l'output effettivo sul file vicino al gold e cancellalo se il test passa. In questo modo è possibile utilizzare lo strumento diff quando necessario. Quando non vengono trovati dati sull'oro, il test fallisce con il messaggio appropriato, ma l'output effettivo viene comunque scritto, quindi puoi verificare che sia corretto e copiarlo per diventare "gold".

Probabilmente scriverei un test unitario che contiene un loop. All'interno del ciclo, avrei letto 2 file xml e un file diff, quindi diff file xml (senza scriverlo sul disco) e confrontato con il file diff letto dal disco. I file sarebbero numerati, ad es. a1.xml, b1.xml, diff1.txt; a2.xml, b2.xml, diff2.txt; a3.xml, b3.xml, diff3.txt, ecc. e il ciclo si interrompe quando non trova il numero successivo.

Quindi, puoi scrivere nuovi test semplicemente aggiungendo nuovi file di testo.

Invece di chiamare .AreEqual puoi analizzare tu stesso i due flussi di input, tenere un conteggio di linea e colonna e confrontare i contenuti. Non appena trovi una differenza, puoi generare un messaggio come ...

  

Riga 32 Colonna 12 - Trovato 'x' quando era previsto 'y'

Puoi facoltativamente migliorarlo visualizzando più righe di output

  

Differenza alla riga 32 Colonna 12, prima differenza mostrata
  A = questa è una t x st
  B = questo è un e m

Nota, di norma, in genere genererei attraverso il mio codice solo uno dei due flussi che hai. L'altro prenderei da un file di test / testo, dopo aver verificato con occhio o altro metodo che i dati contenuti sono corretti!

Probabilmente userei XmlReader per scorrere i file e confrontarli. Quando colgo una differenza, visualizzo un XPath nella posizione in cui i file sono diversi.

PS: Ma in realtà mi è sempre bastato fare una semplice lettura dell'intero file su una stringa e confrontare le due stringhe. Per la segnalazione è sufficiente vedere che il test ha avuto esito negativo. Quindi quando eseguo il debug di solito diffondo i file usando Araxis Merge per vedere esattamente dove Ho dei problemi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top