Come testare il codice di test che scarica un file da un repository github

6

Questa è la struttura della mia soluzione:

Storage.csproj
   > FileDownloader.cs
   > GitHubProvider.cs (implements IStorageProvider)
   > IStorageProvider.cs

Storage.Test.csproj
   > FileDownloaderFixture.cs

L'idea è che posso usare la classe FileDownloader , iniettarla con un IStorageProvider , chiamare myFileDownloader.Download(url) , e scaricherà il file sul filesystem.

Ora, la domanda è: come posso testare questo? Ho scritto il seguente test:

[TestClass]
    public class FileDownloaderFixture
    {
        [TestMethod]
        public void TestDownload()
        {
            //Arrange
            var storageProviderMock = new Mock<IStorageProvider>(MockBehavior.Strict);
            storageProviderMock.Setup(s => s.Download("http://host.com/file.txt")).Returns(Status.Success);
            var myFileDownloader = new FileDownloader(storageProviderMock.Object);

            //Act
            myFileDownloader.DownloadFile("http://host.com/file.txt");

            //Assert
            storageProviderMock.Verify(s => s.Download("http://host.com/file.txt"));
        }
    }

Sembra bello e pulito, ma ... è inutile. Non dimostra il fatto che il codice in GitHubProvider.Download(url) funzioni. Non utilizzo nemmeno metodi da GitHubProvider . Allora, qual è il punto?

L'unica altra idea che ho è di impostare un account GitHub di prova e amp; repository e lavorare con quello. Ma questa soluzione non funzionerà molto bene se, ad esempio, dovessi pagare per ogni accesso al repository. Che cosa allora?

    
posta Maria Ines Parnisari 19.09.2014 - 07:57
fonte

3 risposte

14

Il downloader di file ha due dipendenze esterne: una connessione a Git è dove i dati arrivano. Una connessione al file system è dove i dati si spengono.

Per essere un test unitario, il test dovrebbe essere astratto da entrambi questi collaboratori: non si desidera testare il protocollo di rete Git e non si desidera testare il codice del file system. Ciò lascia il comportamento della classe semplice e facilmente verificabile: invia comandi all'hub Git per ottenere comandi di dati e problemi sul sistema di archiviazione per scriverli. Questo è un test piuttosto primitivo, e questo è buono . Una classe dovrebbe fare una cosa, e farlo bene. idealmente, dovrebbe essere così semplice che è ovviamente corretto (e avere anche un test unitario per i casi in cui l'ovvietà è fuorviante).

Hai ragione che questo non dimostra che il tuo sistema scarica correttamente materiale. Questo è il compito di un'integrazione, accettazione o test di carico, e anche quelli necessari, ma per quanto riguarda i test unitari, non c'è nulla di sbagliato nei test che sembrano quasi banali. Il tuo progetto crescerà in complessità abbastanza presto, e senza una rete di sicurezza composta da controlli quasi banali, non puoi gestire quella crescita in modo responsabile.

    
risposta data 19.09.2014 - 08:14
fonte
5

Il tuo test non è inutile. Un test unitario FileDownloaderFixture verifica il FileDownloader non di più, non di meno. Non aspettarti che un test unitario provi più di una unità.

Per testare GitHubProvider.Download , è necessario un secondo test diverso. Poiché è coinvolta una risorsa esterna che è quasi completamente fuori controllo dall'ambiente di test, probabilmente non ha senso implementare questo test come parte della suite di test unitaria "normale". Quindi la strategia migliore per tale componente è spesso quella di fornire un test manuale o "semiautomatico", da eseguire manualmente ogni volta che si modifica qualcosa in GitHubProvider . Questo test può comportare l'uso di un account GitHub & repository. Puoi utilizzare lo strumento di test dell'unità per questo test, ma se il test manuale richiede alcuni passaggi manuali aggiuntivi, puoi anche implementare qualcosa di completamente diverso (come un piccolo programma di test con un'interfaccia utente o un'interfaccia a linea di comando semplici, qualunque sia la causa del minimo sforzo) Questo è un approccio fattibile fintanto che gli interni di GitHubProvider non sono troppo complessi.

    
risposta data 19.09.2014 - 08:46
fonte
0

The only other idea I have is to set up a test GitHub account & repository, and work with that. But this solution won't work very well if, for instance, I had to pay for each access to the repository. What then?

Il test su un conto reale è chiamato test di integrazione e non test di unità. Non è necessario un repo github per testare il download di un file tramite HTTP. Ogni server HTTP può essere sufficiente. Se hai qualche problema specifico di github, puoi creare il repository e testarlo. Dopodiché puoi supporre che l'interfaccia del github non cambierà per un lungo periodo, quindi puoi saltare questo test di integrazione eseguendo i tuoi test, perché è lento e non dipende (o meno) dai componenti che probabilmente vuoi cambiare. Probabilmente eseguirai test di integrazione tramite le modifiche alla versione del prodotto integrate nell'applicazione. Ad esempio, da una nuova versione del database, ecc ...

    
risposta data 19.09.2014 - 13:11
fonte

Leggi altre domande sui tag