Condividi tramite


Sviluppo di test da un modello

In Microsoft Visual Studio Ultimate è possibile utilizzare il modello requisiti e il modello architetturale per organizzare test di sistema e dei relativi componenti. In questo modo è possibile testare i requisiti che sono importanti per gli utenti e le altre parti interessate nonché aggiornare rapidamente i test quando vengono modificati i requisiti. Se si utilizza Microsoft Test Manager, è inoltre possibile gestire i collegamenti tra i modelli e i test.

Test di sistema e di sottosistema

Con test di sistema o test di accettazione si intende l'insieme di test mediante i quali si verifica se vengono soddisfatte le necessità degli utenti. Tali test riguardano il comportamento del sistema visibile esternamente anziché la progettazione interna.

I test di sistema sono molto utili nel caso in cui sia necessario estendere o riprogettare un sistema consentendo di evitare di introdurre bug quando si modifica il codice.

Quando si pianifica una qualsiasi modifica o estensione a un sistema, è utile iniziare con un set di test di sistema da eseguire nel sistema esistente. È quindi possibile estendere o modificare i test per testare i nuovi requisiti, apportare le modifiche al codice e rieseguire il set di test completo.

Quando si sviluppa un nuovo sistema, è possibile iniziare a creare i test contestualmente all'inizio dello sviluppo. Se i test vengono definiti prima di sviluppare ogni funzionalità, è possibile avviare discussioni sui requisiti in modo molto specifico.

Il test di sottosistema applica gli stessi principi ai componenti principali di un sistema. Ogni componente viene testato separatamente dagli altri componenti. l test di sottosistema sono incentrati sul comportamento visibile nelle interfacce utente o nell'API del componente.

Per ulteriori informazioni sulle modalità di esecuzione dei test, vedere Test dell'applicazione.

Derivazione dei test di sistema da un modello requisiti

È possibile creare e gestire una relazione tra i test di sistema e un modello requisiti. Per stabilire questa relazione, vengono scritti test che corrispondono agli elementi principali del modello requisiti. Visual Studio Ultimate consente di mantenere tale relazione permettendo di creare collegamenti tra i test e le parti del modello. Per ulteriori informazioni sui modelli requisiti, vedere Modellazione dei requisiti utente.

Scrivere test per ogni caso di utilizzo

Se si utilizza Microsoft Test Manager, è possibile creare un gruppo di test per ogni caso di utilizzo definito nel modello requisiti. Se ad esempio si dispone di un caso di utilizzo Ordinazione pasto che include Creazione ordine e Aggiunta elemento all'ordine, è possibile creare i test sia per i casi di utilizzo in generale che per quelli più dettagliati. Per ulteriori informazioni sui casi di utilizzo, vedere Diagrammi casi di utilizzo UML: linee guida.

Le linee guida seguenti potrebbero risultare utili:

  • Ogni caso di utilizzo deve avere diversi test, per i percorsi principali e i risultati eccezionali.

  • Quando si descrive un caso di utilizzo nel modello requisiti, è più importante definire la postcondizione, ovvero l'obiettivo da raggiungere, che descrivere in dettaglio le procedure che l'utente segue per raggiungere l'obiettivo. Ad esempio, la postcondizione dell'Ordinazione pasto potrebbe essere che un ristorante stia preparando un pasto per un cliente e che il cliente abbia pagato. La postcondizione è il criterio che i test devono verificare.

  • Basare test separati sulle clausole separate della postcondizione. Ad esempio, creare test separati per notificare l'ordine al ristorante e per accettare il pagamento dal cliente. Questa separazione offre i vantaggi seguenti:

    • Le modifiche dei diversi aspetti dei requisiti si verificano spesso indipendentemente. La creazione di test separati per i vari aspetti consente di aggiornare più facilmente i test qualora vengano modificati i requisiti.

    • Se il piano di sviluppo implementa un aspetto del caso di utilizzo prima di un altro, è possibile abilitare i test separatamente in base all'avanzamento dello sviluppo.

  • Quando si progettano i test, separare la scelta dei dati di test dal codice o dallo script che determina se la postcondizione è stata raggiunta. Il test di una funzione aritmetica semplice, ad esempio, può essere: Input 4; verificare che l'output sia 2. Progettare invece lo script come: Scegliere un input; moltiplicare l'output per se stesso e verificare che il risultato sia l'input originale. Questo stile consente di variare gli input del test senza modificare il corpo principale del test.

Collegamento di test ai casi di utilizzo

Se si utilizza Test Manager per progettare ed eseguire i test, è possibile organizzare i test in base agli elementi di lavoro requisiti, casi di utilizzo o storie utente. È possibile collegare questi elementi di lavoro ai casi di utilizzo del modello consentendo di tracciare rapidamente le modifiche dei requisiti nei test e di tenere traccia dello stato di avanzamento di ogni caso di utilizzo.

Per collegare i test a un caso di utilizzo

  1. In Test Manager creare un requisito e basare su di esso un gruppo di test. Per informazioni su come eseguire questa operazione, vedere Creazione di un piano di test utilizzando i requisiti o le storie utente.

    Il requisito creato è un elemento di lavoro in Team Foundation Server. Potrebbe essere un elemento di lavoro Storia utente, Requisito o Caso di utilizzo, a seconda del modello di processo utilizzato dal progetto con Team Foundation. Per ulteriori informazioni, vedere Pianificazione e rilevamento di progetti.

  2. Collegare l'elemento di lavoro requisito a uno o più casi di utilizzo del modello.

    In un diagramma caso di utilizzo fare clic con il pulsante destro del mouse su un caso di utilizzo, quindi scegliere Collega a elemento di lavoro. Per ulteriori informazioni, vedere Procedura: collegare elementi di modello a elementi di lavoro.

  3. Aggiungere al gruppo di test i test case che verificano i casi di utilizzo.

In genere, ogni elemento di lavoro storia utente o requisito viene collegato a diversi casi di utilizzo del modello e ogni caso di utilizzo viene collegato a diverse storie utente o diversi requisiti. Ogni storia utente o requisito riguarda infatti un set di attività che sviluppano diversi casi di utilizzo. Ad esempio, in una prima iterazione del progetto, è possibile sviluppare la storia utente di base in cui un cliente può scegliere gli elementi da un catalogo e richiederne la consegna. In un'iterazione successiva la storia potrebbe essere sviluppata in modo tale che l'utente paghi al completamento dell'ordine e il fornitore riceva i soldi dopo aver inviato i prodotti. Ogni storia aggiunge una clausola alla postcondizione del caso di utilizzo Ordinazione prodotti.

È possibile creare collegamenti separati dai requisiti alle clausole della postcondizione scrivendo le clausole in commenti separati sul diagramma caso di utilizzo. È possibile collegare ogni commento a un elemento di lavoro requisito e collegare il commento al caso di utilizzo nel diagramma.

Creare test in base ai tipi di requisiti

I tipi, ovvero classi, interfacce ed enumerazioni, di un modello requisiti descrivono i concetti e le relazioni delineando cosa gli utenti pensano dell'azienda e come comunicano la loro idea. Sono esclusi i tipi riguardanti solo la progettazione interna del sistema.

Progettare i test facendo riferimento a questi tipi di requisiti. In questo modo, quando vengono discusse le modifiche ai requisiti, è facile correlare le modifiche alle modifiche necessarie nei test. È inoltre possibile discutere dei test e dei relativi risultati direttamente con gli utenti finali e le altre parti interessate. Questo significa che le esigenze degli utenti possono essere gestite al di fuori del processo di sviluppo evitando la progettazione accidentale di test sui possibili difetti di progettazione.

Per i test manuali questa procedura implica il rispetto del vocabolario del modello requisiti negli script di test. Per i test automatizzati questa procedura implica l'utilizzo di diagrammi classi di requisiti come base per il codice del test e la creazione di funzioni di accesso e di aggiornamento per collegare il modello requisiti al codice.

Ad esempio, un modello requisiti potrebbe includere i tipi Menu, Elemento menu, Ordine e le associazioni tra di essi. Questo modello rappresenta le informazioni archiviate e gestite dal sistema di ordinazione dei pasti, ma non rappresenta le complessità dell'implementazione. Nel sistema lavorativo potrebbero esserci diverse realizzazioni di ogni tipo, nei database, nelle interfacce utente e nelle API. In un sistema distribuito potrebbero esserci diverse varianti di ogni istanza archiviata contemporaneamente in diverse parti del sistema.

Per testare un caso di utilizzo quale, ad esempio, Aggiunta elemento all'ordine, un metodo di test potrebbe includere un codice simile al seguente:

Order order = … ; // set up an order
// Store prior state:
int countBefore = order.MenuItems.Count; 
// Perform use case:
MenuItem chosenItem = …; // choose an item
AddItemToOrder (chosenItem, order); 
// Verify part of postcondition:
int countAfter = order.MenuItems.Count;
Assert (countAfter == countBefore = 1); 

Si noti che questo metodo di test utilizza le classi del modello requisiti. Le associazioni e gli attributi vengono rappresentati come proprietà .NET.

Perché questo sia possibile, è necessario che le proprietà delle classi vengano definite come funzioni di sola lettura o funzioni di accesso a cui il sistema accede per recuperare le informazioni sullo stato corrente. I metodi che simulano i casi di utilizzo come AddItemToOrder devono utilizzare il sistema tramite l'API o tramite un livello sottostante l'interfaccia utente. I costruttori di oggetti di test come Order e MenuItem devono utilizzare il sistema anche per creare gli elementi corrispondenti all'interno del sistema.

Molte delle funzioni di accesso e di aggiornamento saranno già disponibili tramite l'API normale dell'applicazione. È possibile però che sia necessario scrivere alcune funzioni aggiuntive per abilitare i test. Queste funzioni di accesso e di aggiornamento aggiuntive sono talvolta note come "strumentazione del test". Poiché dipendono dalla progettazione interna del sistema, è responsabilità degli sviluppatori del sistema fornirle, mentre i tester scrivono il codice dei test in relazione al modello requisiti.

Quando si scrivono i test automatizzati, è possibile utilizzare i test generici per eseguire il wrapping delle funzioni di accesso e di aggiornamento. Per ulteriori informazioni, vedere Creazione di un test automatizzato che avvia un eseguibile utilizzando test generici.

Test per le regole business

Alcuni requisiti non sono direttamente correlati a un caso di utilizzo. Ad esempio, l'azienda DinnerNow consente ai clienti di scegliere da molti Menu, ma richiede che in ogni Ordine tutti gli Elementi scelti appartengano a un solo Menu. È possibile esprimere questa regola business come invariante per le associazioni tra Ordini, Menu ed Elementi del modello di classe requisiti.

Una regola invariante di questo tipo gestisce non solo tutti i casi di utilizzo definiti al momento, ma anche tutti gli altri casi di utilizzo che verranno definiti successivamente. Pertanto, è utile scriverla separatamente dai casi di utilizzo e testarla separatamente dagli stessi.

È possibile scrivere una regola business invariante come commento in un diagramma classi. Per ulteriori informazioni, vedere Diagrammi classi UML: linee guida.

È possibile collegare i test a una regola business collegando il commento a un elemento di lavoro requisito o storia utente che è possibile collegare a un gruppo di test in Test Manager. Per ulteriori informazioni, vedere Associazione di test case agli elementi del modello.

I requisiti di prestazioni e gli altri requisiti di qualità del servizio possono essere indicati in commenti nei diagrammi caso di utilizzo, di attività o di sequenza e anch'essi possono essere collegati agli elementi di lavoro requisiti e ai relativi gruppi di test.

Diagrammi di sequenza e di attività per i test

Se i modelli requisiti o di architettura includono i diagrammi di sequenza o di attività, è possibile scrivere test che seguono direttamente i diagrammi.

Può talvolta rivelarsi utile progettare test che scelgono dinamicamente percorsi diversi tramite i rami e i cicli del diagramma.

Provare a verificare lo stato del sistema dopo ogni messaggio o azione. Questa operazione potrebbe richiedere una strumentazione aggiuntiva.

Derivazione dei test di sottosistema dai modelli

Nella progettazione di alto livello di un sistema di grandi dimensioni, è possibile identificare componenti o sottosistemi. Essi rappresentano le parti che possono essere progettate separatamente, che risiedono in computer diversi o che sono moduli riutilizzabili da ricombinare in vari modi. Per ulteriori informazioni, vedere Diagrammi dei componenti UML: linee guida.

A ciascun componente principale è possibile applicare gli stessi principi utilizzati per il sistema completo. In un progetto di grandi dimensioni, ogni componente può avere il proprio modello requisiti. Nei progetti più piccoli, è possibile creare un modello architetturale o una progettazione di alto livello per mostrare i componenti principali e le relative interazioni. Per ulteriori informazioni, vedere Modellazione dell'architettura di un sistema software.

In entrambi i casi, è possibile stabilire una relazione tra gli elementi del modello e i test di sottosistema in modo analogo a quello utilizzato per stabilire una relazione tra il modello requisiti e i test di sistema.

Isolare i componenti con interfacce fornite e richieste

È utile identificare tutte le dipendenze che un componente ha con altre parti del sistema o con servizi esterni e rappresentarle come Interfacce richieste. Questo esercizio comporta in genere una riprogettazione che lascia il componente molto più separato e facilmente separabile dal resto della progettazione.

Un vantaggio offerto da questa separazione è dato dal fatto che è possibile eseguire il test del componente sostituendo i servizi utilizzati generalmente con oggetti fittizi. Si tratta di componenti che vengono configurati a scopo di test. Un componente fittizio fornisce l'interfaccia richiesta dal componente, rispondendo alle query con dati simulati. I componenti fittizi fanno parte di un test harness completo che è possibile connettere a tutte le interfacce del componente.

Un vantaggio del test fittizio è rappresentato dal fatto che è possibile sviluppare un componente mentre gli altri componenti di cui vengono utilizzati i servizi sono ancora in fase di sviluppo.

Gestire le relazioni tra test e modello

In un progetto tipico che esegue un'iterazione a intervalli di poche settimane viene effettuata una verifica dei requisiti quasi all'inizio di ogni iterazione. Nella riunione vengono illustrate le funzionalità che devono essere distribuite nell'iterazione successiva. È possibile utilizzare un modello requisiti per illustrare i concetti, gli scenari e le sequenze di azioni da sviluppare. Le parti interessate dell'azienda impostano le priorità, gli sviluppatori preparano le stime e i tester garantiscono che il comportamento previsto di ogni funzionalità venga acquisito correttamente.

La scrittura di test rappresenta il modo più efficace per definire un requisito ed è anche un modo efficace per consentire a una persona di comprendere chiaramente le necessità. Tuttavia, mentre la scrittura di test è un'operazione che richiede troppo tempo per essere eseguita durante un workshop, la creazione di modelli può essere eseguita molto più rapidamente.

Da un punto di vista del test, un modello requisiti può essere considerato un metodo sintetico per i test. Pertanto, è importante gestire la relazione tra i test e il modello in tutto il progetto.

Associazione di test case agli elementi del modello

Se il progetto utilizza Test Manager, è possibile collegare i test agli elementi del modello. In questo modo è possibile trovare rapidamente i test interessati da una modifica ai requisiti e tenere traccia dell'ambito di utilizzo di un requisito.

È possibile collegare i test a tutti i tipi di elemento. Di seguito sono riportati alcuni esempi:

  • Collegare un caso di utilizzo ai test che ne eseguono la verifica.

  • Scrivere le clausole di una postcondizione del caso di utilizzo, o obiettivo, nei commenti collegati al caso di utilizzo, quindi collegare i test a ogni commento.

  • Scrivere le regole invarianti in commenti nei diagrammi classi o diagrammi di attività e collegarli ai test.

  • Collegare i test a un diagramma di attività o a singole attività.

  • Collegare un gruppo di test al componente o sottosistema sottoposto a test.

Per collegare i test a una relazione o a un elemento del modello

  1. In Test Manager creare un requisito e basare su di esso un gruppo di test. Per informazioni su come eseguire questa operazione, vedere Creazione di un piano di test utilizzando i requisiti o le storie utente.

    Il requisito creato è un elemento di lavoro in Team Foundation Server. Potrebbe essere un elemento di lavoro Storia utente, Requisito o Caso di utilizzo, a seconda del modello di processo utilizzato dal progetto con Team Foundation. Per ulteriori informazioni, vedere Pianificazione e rilevamento di progetti.

  2. Collegare l'elemento di lavoro requisito a uno o più elementi del modello.

    In un diagramma di modellazione fare clic con il pulsante destro del mouse su un elemento, un commento o una relazione, quindi scegliere Collega a elemento di lavoro. Per ulteriori informazioni, vedere Procedura: collegare elementi di modello a elementi di lavoro.

  3. Aggiungere al gruppo di test i test case che verificano il requisito espresso nell'elemento del modello.

Vedere anche

Concetti

Sviluppo di modelli per la progettazione software

Modellazione dei requisiti utente

Modellazione dell'architettura di un sistema software

Modellazione dell'applicazione