Test dell'unità di scrittura per una classe che avvia l'EXE esterno

9

Ho scritto una classe C # che viene utilizzata per avviare un elenco di EXE (non uno dei miei - EXE di terze parti che devo eseguire) e mantenerli in esecuzione (controlleremo di tanto in tanto per assicurarmi che sia ancora in esecuzione e avviarli in caso contrario.

Sono in grado di testare la logica di base dell'aggiunta, della rimozione, ecc. Come collaudo l'unità che il lavoro effettivo di mantenere i file EXE funzionerà?

Il mio pensiero iniziale è di avviare un EXE fittizio che si chiude da solo dopo 1 secondo, quindi usarlo per testare. È fuori dal regno dei test unitari?

    
posta MattW 02.08.2012 - 15:55
fonte

4 risposte

12

My initial thought is to start some dummy EXE that closes itself after 1 second, then use that to test. Is that out of the realm of Unit Testing?

Questo è un buon test? Certo, quindi crearlo. È "un test unitario" nel vero senso della parola? Io non la penso così, chiamerei questo un "test di sistema" o qualcosa del genere, ma questo non rende il test meno prezioso.

    
risposta data 02.08.2012 - 16:01
fonte
9

Deridilo a un livello superiore a quello. Crea una classe proxy intorno a Process.Start() , falla finita nel test e controlla l'input.

public interface IProcessProxy
{
     ProcessInfo Start(string application, string[] arguments);
}

public class ProcessProxy : IProcessProxy
{
    public ProcessInfo Start(string application, string[] arguments)
    {
        return Process.Start(application, arguments);
    }
}

// You could use a mocking framework for this, but for the purposes
// of this example ...
public class FakeProcessProxy : IProcessProxy
{
    private string _expectedApplication;
    private string[] _expectedArguments;
    private ProcessInfo response;

    public FakeProxy(string expectedApplication, string[] expectedArguments, ProcessInfo response)
    {
         _expectedApplication = expectedApplication;
         _expectedArguments = expectedArguments;
    }

    public ProcessInfo Start(string application, string[] arguments)
    {
         // compare input to expectations and throw exception if not matching
         return _response;
    }
}

// You can also use an IoC framework to inject your IProcessProxy, but I won't.
public class ClassUnderTest
{
    public ClassUnderTest(IProcessProxy proxy)
    {
        _proxy = proxy;
    }

    public ClassUnderTest() : this(new ProcessProxy())
    {
    }

    public void MethodUnderTest()
    {
        // Do stuff

        ProcessInfo process = _proxy.Start(@"C:\Program Files\App\App.exe", new[] { "arg1", "arg2" });
        process.WaitForExit();

        if (process.ExitCode == 0)
        {
            // Act on success
        }
        else
        {
            // Act on failure
        }
    }   
}

Ovunque sia necessario consumare ClassUnderTest nel codice dell'applicazione, utilizzare il costruttore predefinito. Nei test, passare un FakeProcessProxy all'altro costruttore, utilizzando i parametri di avvio del proxy previsti e il risultato del test nel costruttore del falso.

    
risposta data 02.08.2012 - 16:19
fonte
4

Quando rigorosamente seguendo la filosofia di unittesting (enfasi su unità ), non dovresti creare un file Exe, ma testare se la tua classe chiama le interfacce per generare spawn e monitorare questo processo correttamente. Dopotutto, vuoi testare la tua classe, non la libreria responsabile della gestione dei processi.

Ma da un punto di vista pragmatico, il tuo approccio va bene, anche se 1 secondo sembra essere un po 'lungo.

    
risposta data 02.08.2012 - 16:00
fonte
1

Ho fatto qualcosa di simile, ma ho appena chiamato ping localhost . Salva la seccatura di mettere gli eseguibili sul tuo build server

    
risposta data 07.12.2018 - 14:05
fonte

Leggi altre domande sui tag