Domanda

La mia applicazione

Ho un design dell'applicazione simile a questo:

  • Livello applicazione Web: app asp.net MVC con controller e visualizzazioni che utilizzano POCO e servizi di chiamata
  • livello di servizio: processi aziendali che utilizzano POCO e repository di chiamate
  • livello dati: repository che utilizzano POCO e comunicano con il modello sotto forma di modello EF che fa parte di questo stesso livello
  • Livello POCO: definisce tutte le classi utilizzate per l'intercomunicazione tra questi livelli

Quindi il mio livello dati è completamente trasparente all'implementazione del modello dati perché il livello superiore non utilizza affatto entità dati.

Test

Per quanto ho capito, test di unità, integrazione e sistema (in relazione ad Asp.net MVC) è questo:

  • test unitari: questo è facile.Simulare oggetti disaccoppiati e inserirli nel test unitario in modo che l'unità testata li utilizzi
  • test di integrazione - dovrebbe creare un gruppo di unità di funzionalità di produzione e deridere il resto:quindi scrivere test di integrazione che testino l'integrazione di controller, servizi e repository senza utilizzare effettivamente il database di produzione
  • test di sistema: esegui test su tutti i livelli senza alcuna simulazione, il che significa che devo utilizzare anche il database di produzione (test).

Problema

Posso facilmente vedere come scrivere test unitari e test di sistema, ma non so come scrivere test di integrazione?Forse la mia visione di questi argomenti è completamente distorta e non li capisco affatto.

Come si dovrebbero scrivere test di integrazione e di sistema per un'applicazione Asp.net MVC?
O qualche applicazione .net per quella materia?

Qualche codice che aiuta a spiegare il problema

Supponiamo che io abbia classi come:

  • TaskController chiama in TaskService
  • TaskService chiama in TaskRepository
  • TaskRepository manipolare i dati EF internamente

Quindi ecco le mie lezioni (abbreviate):

public class TaskController
{
    private ITaskService service;

    // injection constructor
    public TaskController(ITaskService service)
    {
        this.service = service;
    }

    // default constructor
    public TaskController() : this(new TaskService()) {}

    public ActionResult GetTasks()
    {
        return View(this.service.GetTasks());
    }
    ...
}

public class TaskService : ITaskService
{
    private ITaskRepository repository;

    // injection constructor
    public TaskService(ITaskRepository repository)
    {
        this.repository = repository;
    }

    // default constructor
    public TaskService() : this(new TaskRepository()) {}

    public IList<Task> GetTasks()
    {
        return this.repository.GetTasks();
    }
    ...
}

public class TaskRepository : ITaskRepository
{
    public IList<Task> GetTasks()
    {
        // code that gets tasks from EF and converts to Task POCOs
    }
    ...
}

Il test unitario è semplice e sarebbe simile a questo:

public void UnitTest()
{
    var mock = new Mock<ITaskService>();
    // other code that mocks the service

    TaskController controller = new TaskController(mock.Object);

    // do the test
}

Ma quando si tratta di un test di integrazione, come posso deridere solo alcune parti dell'integrazione?

public void IntegrationTest()
{
    // no mocking at all
    TaskController = new TaskController();
    // do some testing
}

Prima di tutto non posso semplicemente prendere in giro il database qui?Potrei prendere in giro il repository e avere un servizio e un controller reali però ...

È stato utile?

Soluzione

I test di integrazione dovrebbero testare l'integrazione tra i componenti.Mentre i test unitari testano singoli pezzi di un singolo componente, l'integrazione testa le interazioni tra i componenti e sono pensati per funzionare in tempo reale.Quindi un test di integrazione utilizzerebbe un database e qualsiasi altra dipendenza esterna, dove è meglio deridere questi servizi nei test unitari.

Il test del sistema per me sarebbe un test funzionale (un altro livello di test che utilizza qualcosa come fit) o ​​un test dell'interfaccia utente tramite uno strumento come testcomplete o lo strumento QA di Telerik.

HTH.

Altri suggerimenti

I test di integrazione che non coinvolgono l'interfaccia utente possono comunque essere scritti in NUnit, xUnit e così via.

Per ASP.NET MVC in particolare (o qualsiasi applicazione Web), è possibile utilizzare WatiN O Selenio per scrivere test di sistema/integrazione utilizzando l'interfaccia utente.

Potresti anche voler dare un'occhiata T.S.T. per test unitari T-SQL e SpecFlow se sei curioso di sapere BDD in .NET.

Nota:L'ho scritto prima che la domanda fosse aggiornata con il codice e una descrizione della situazione specifica.Non affronta più realmente la domanda, ma si spera che sia comunque interessante/utile per qualcuno.

Ho appena risposto ad una domanda correlata: Implementazione dei test di integrazione.Penso che qui abbia affrontato la questione, presentando un approccio chiaro da adottare.

Parte del problema è che i test di integrazione di livello superiore diventano troppo complessi v.velocemente.È la natura del problema, quindi preferisco assicurarmi che tutti i pezzi separati funzionino come previsto, attraverso test unitari e test di integrazione mirati a seconda della classe coinvolta.

Con quanto sopra in atto, devi solo assicurarti che i pezzi separati siano agganciati correttamente, quindi utilizzo i test completi del sistema per questo.Ciò ha il massimo effetto se il codice segue SOLID e DRY.

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