Scrivere il nuovo codice per una storia utente
Sono un nuovo utente di Visual Studio Application Lifecycle Management (ALM) e Team Foundation Server (TFS)? Sono si vi state chiedendo come è possibile ottenere massime beneficiare la versione più recente di questi strumenti per compilare l'applicazione?
Quindi richiedere alcuni minuti per verificare il percorso passo a passo con questa esercitazione capitolo due e seguire una giornata nella vita di Peter e Olga, due sviluppatori a fibra ottica di Fabrikam, un'azienda fittizia che fornisce servizi correlati e televisione via cavo. Si noterà che alcuni esempi di come è possibile utilizzare Visual Studio e TFS per estrarre e aggiornare il codice, sospendere il lavoro quando è interrotto, richiedere una revisione del codice, archiviare le modifiche ed eseguire altre attività.
Finora la storia
Il team ha recentemente iniziato a l'adozione di Visual Studio e Team Foundation Server per Application Lifecycle Management (ALM). Essi impostare i server e computer client, creata un backlog pianificato un'iterazione e completate altre attività di pianificazione necessarie per iniziare a sviluppare la propria applicazione.
Panoramica di questo capitolo
Peter brevemente esamina il backlog e seleziona l'attività che funzioneranno su oggi. Scrive unit test per il codice che egli intende sviluppare. In genere, egli esegue i test più volte in un'ora, passare gradualmente la scrittura di test più dettagliati e quindi scrivere il codice che li rende. Con i colleghi che utilizzano il metodo che sta attualmente scrivendo l'autore discute spesso l'interfaccia del suo codice.
Nota
Le funzionalità di lavoro personale e il Code Coverage vengono trattate in questo argomento sono disponibili solo in Visual Studio Premiume Visual Studio Ultimate.
In questo argomento
Esaminare il backlog personali e preparare l'attività inizi a lavorare
Creare il primo unit test
Creare uno stub per il nuovo codice
Eseguire il primo test
Accettare l'API
Il refactoring di rosso, verde,...
Code Coverage
Quando abbiamo terminati?
Archiviare le modifiche
Esaminare il backlog personali e preparare l'attività inizi a lavorare
In Di Team Explorer, Peter si apre il Lavoro personale pagina. Il team ha deciso che, durante lo sprint corrente, Peter funzionerà su valuta lo stato, un elemento di priorità nel backlog del prodotto. Peter decide di iniziare con funzioni matematiche di implementare, un'attività figlio dell'elemento di backlog delle priorità. Egli trascina questa attività dalla Gli elementi di lavoro disponibili elenco nella elementi di lavoro In corso & Le modifiche elenco.
Per esaminare il backlog personali e preparare attività inizi a lavorare
In di Team Explorer:
Se non si è già connessi al progetto team che si desidera utilizzare, quindi connessione al progetto team.
Scegliere casa, quindi scegliere Lavoro personale.
Nella Lavoro personale di pagina, trascinare l'attività dal Disponibili elementi di lavoro elenco per il Elementi di lavoro In corso sezione.
È inoltre possibile selezionare un'attività nella Gli elementi di lavoro disponibili elenco e quindi scegliere Start.
Proposta di piano di lavoro incrementale
Peter sviluppa in genere codice di una serie di piccoli intervalli. In genere, ogni passaggio richiede non più di un'ora e potrebbe richiedere solo dieci minuti. In ogni passaggio, egli scrive un nuovo unit test e si modifica il codice che si sta sviluppando in modo che passa il nuovo test, oltre alle prove che ha già scritto. A volte scrive il nuovo test prima di modificare il codice e talvolta modifica il codice prima di scrivere il test. A volte si effettua il refactoring. Migliorare, solo il codice senza l'aggiunta di nuovi test. Un test viene superato, egli non cambia mai a meno che non si decide che non è stato non in grado di rappresentare correttamente un requisito.
Alla fine di ogni passaggio, egli esegue tutti gli unit test che sono rilevanti per l'area del codice. Egli non prende in considerazione il passaggio completo fino a quando ogni test ha esito positivo.
Tuttavia, egli non controllerà il codice in Team Foundation Server finché non egli ha terminato l'intera attività.
Peter scrive verso il basso un piano approssimativo per questa sequenza di passaggi di piccole dimensioni. Egli sa che i dettagli esatti e l'ordine di quelle successive verrà probabilmente modificato quando si lavora. Ecco il suo elenco iniziale dei passaggi per questa particolare attività:
Creare stub di metodo di test, ovvero, solo la firma del metodo.
Soddisfare un caso tipico specifico.
Ampia gamma di test. Assicurarsi che il codice risponde correttamente a un ampio intervallo di valori.
Eccezione in negativo. Gestire correttamente i parametri non corretti.
Codice copertura. Assicurarsi che almeno l'80% del codice è esercitato dagli unit test.
Questo tipo di piano di alcuni dei suoi colleghi scrivere commenti nel relativo codice di test. Gli altri è sufficiente memorizzare loro piano. Peter trova utile per scrivere il proprio elenco di passaggi nel campo Descrizione dell'elemento di lavoro attività. Se è necessario passare temporaneamente a un'attività più urgente, saprà dove trovare l'elenco quando è in grado di restituire ad esso.
Creare il primo unit test
Peter inizia con la creazione di uno unit test. Egli inizia con lo unit test perché desidera scrivere un esempio di codice che utilizza la nuova classe.
Questo è il primo unit test per la libreria di classi che si sta testando, in modo che si crea un nuovo progetto di unit test. Apre il Nuovo progetto nella finestra di dialogo e sceglie Visual C#, Teste quindi Progetto di Unit Test.
Il progetto di unit test fornisce un file C# in cui è possibile scrivere questo esempio. In questa fase gli basta illustrare come uno dei suoi nuovi metodi verrà richiamato:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Fabrikam.Math.UnitTest
{
[TestClass]
public class UnitTest1
{
[TestMethod]
// Demonstrates how to call the method.
public void SignatureTest()
{
// Create an instance:
var math = new Fabrikam.Math.LocalMath();
// Get a value to calculate:
double input = 0.0;
// Call the method:
double actualResult = math.SquareRoot(input);
// Use the result:
Assert.AreEqual(0.0, actualResult);
}
}
}
Scrive l'esempio in un metodo di test perché, quando che ha scritto il codice, si desidera eseguire l'esempio.
Per creare un'unità di progetto di test e metodi
In genere si creerà un nuovo progetto di test per ogni progetto che si sta testando. Se esiste già un progetto di test, è sufficiente aggiungere classi e nuovi metodi di test.
Questa procedura viene utilizzato il Framework di Test di Visual Studio unità, ma è anche possibile utilizzare il framework di altri provider. Test works Explorer altrettanto bene con altri Framework, purché si installa la scheda appropriata.
Creare un progetto di Test, se non esiste già.
- Nella Nuovo progetto finestra di dialogo, scegliere una lingua come di Visual Basic, Visual C++ o Visual C#. Scegliere Test e progetto di Unit Test.
Aggiungere i test per la classe di test fornito. Ogni unit test è un metodo.
Ogni unit test devono essere preceduti dal prefisso di TestMethodattributo e il metodo di unit test è necessario senza parametri. È possibile utilizzare qualsiasi nome desiderato per un metodo di unit test:
[TestMethod] public void SignatureTest() {...}
<TestMethod()> Public Sub SignatureTest() ... End Sub
Ogni metodo di test deve chiamare un metodo per la Assert(classe), per indicare se è superato o meno. In genere, si verifica che i risultati previsti ed effettivi di un'operazione sono uguali:
Assert.AreEqual(expectedResult, actualResult);
Assert.AreEqual(expectedResult, actualResult)
I metodi di test possono chiamare altri metodi comuni che non dispongono di TestMethodattributo.
È possibile organizzare i test in più di una classe. Ogni classe deve essere preceduti dal prefisso di TestClassattributo.
[TestClass] public class UnitTest1 { ... }
<TestClass()> Public Class UnitTest1 ... End Class
Per ulteriori informazioni sulla scrittura di unit test in C++, vedere Scrittura di unit test per C/C++ con il framework unit test di Microsoft per C++..
Creare uno stub per il nuovo codice
Successivamente, Peter crea un progetto libreria di classi per il suo nuovo codice. È ora disponibile un progetto per il codice in fase di sviluppo e un progetto per gli unit test. Aggiunge un riferimento di progetto dal progetto di test per il codice in fase di sviluppo.
Nel nuovo progetto, ha aggiunto la nuova classe e una versione minima del metodo che consenta almeno il test venga compilato correttamente. Il modo più rapido per eseguire questa operazione consiste nel generare uno stub di classe e metodo di chiamata nel test.
public double SquareRoot(double p)
{
throw new NotImplementedException();
}
Per generare classi e metodi di test
Innanzitutto, creare il progetto in cui si desidera aggiungere la nuova classe, a meno che non esiste già.
Per generare una classe
Posizionare il cursore su un esempio di classe che si desidera generare, ad esempio, LocalMath. Nel menu di scelta rapida, scegliere Genera codice, Nuovo tipo di.
Nella Nuovo tipo di nella finestra di dialogo, impostare progetto al progetto libreria di classi. In questo esempio, è Fabrikam.Math.
Per generare un metodo
- Posizionare il cursore su una chiamata al metodo, ad esempio, SquareRoot. Nel menu di scelta rapida, scegliere Genera codice, Stub del metodo.
Eseguire il primo test
Peter compila ed esegue il test premendo CTRL + R, T. Il risultato del test viene visualizzato un indicatore di errore rosso e il test viene visualizzato nell'elenco di Impossibile test.
Egli rende una semplice modifica al codice:
public double SquareRoot(double p)
{
return 0.0;
}
Egli esegue nuovamente il test e passa:
Per eseguire unit test
Nella Test menu, scegliere esecuzione, Tutti i test.
- oppure -
Se è aperto Esplora Test, scegliere Esecuzione completa.
- oppure -
Posizionare il cursore in un file di codice di test e premere CTRL + R, T.
Se un test viene visualizzato sotto Impossibile test:
Aprire il test, ad esempio, facendo doppio clic sul nome.
Viene visualizzato il punto in cui il test non riuscito.
Per visualizzare un elenco completo di test, scegliere Mostra tutto. Per tornare al riepilogo, scegliere il casa visualizzazione.
Per visualizzare i dettagli di un risultato, selezionare il test in Test di Explorer.
Per passare al codice di un test fare doppio clic su test nel Test Explorer o scegliere Apri Test dal menu di scelta rapida.
Per eseguire il debug di un test aprire il menu di scelta rapida per uno o più test e quindi scegliere Debug test selezionati.
Per eseguire test in background ogni volta che si genera la soluzione attiva/disattiva Esecuzione dei test dopo la compilazione. Test non riuscita in precedenza verranno eseguiti per primi.
Accetta l'interfaccia
Peter chiama i colleghi Julia su Lync e condivide il suo schermo. Utente utilizzando il componente. Egli Mostra suo esempio iniziale.
Julia considera che l'esempio è OK, ma i commenti, "una grande quantità di funzioni passa tale test."
Peter replies, "è il primo test per assicurarsi che il nome e i parametri della funzione siano corretti. Sarà quindi possibile scrivere un test che acquisisce il requisito principale di questa funzione."
Insieme scrivono i test seguenti:
[TestMethod]
public void QuickNonZero()
{
// Create an instance to test:
LocalMath math = new LocalMath();
// Create a test input and expected value:
var expectedResult = 4.0;
var inputValue = expectedResult * expectedResult;
// Run the method:
var actualResult = math.SquareRoot(inputValue);
// Validate the result:
var allowableError = expectedResult/1e6;
Assert.AreEqual(expectedResult, actualResult, allowableError,
"{0} is not within {1} of {2}", actualResult, allowableError, expectedResult);
}
Suggerimento
Per questa funzione, Peter utilizza Test primo sviluppo, in cui egli scrive innanzitutto lo unit test per una feature e quindi si scrive codice che soddisfa il test.In altri casi, scopre che questa pratica non è realistica, al contrario, che scrive i test dopo scrive il codice.Ma si ritiene molto importante per la scrittura di unit test, se prima o dopo il codice, in quanto essi mantenere stabile il codice.
Il refactoring di rosso, verde,...
Peter segue un ciclo in cui egli ripetutamente scrive un test e conferma che si verifica un errore, che consente di scrivere codice per rendere il test passa, quindi considera il refactoring, miglioramento, ovvero il codice senza modificare i test.
Rosso
Peter preme CTRL + R, T per eseguire il test nuovo che ha creato con Julia. Una volta scrive qualsiasi test, egli viene sempre eseguito per assicurarsi che abbia esito negativo prima che scrive il codice che consente di passare. Questa è una procedura che ha appreso dopo ha dimenticato di inserire le asserzioni in alcuni test che egli fosse scritta. Visualizzare il risultato negativo consente fiducia che quando egli consente di passare, il risultato del test correttamente indica che un requisito è stata soddisfatta.
È consigliabile inoltre impostare Esecuzione dei test dopo la compilazione. Questa opzione esegue i test in background ogni volta che si genera la soluzione in modo che si dispone di un rapporto continuo dello stato del test del codice. Peter è stato inizialmente sospetti che potrebbe essere lento a rispondere di Visual Studio, ma scopre che questo si verifica raramente.
Verde
Peter scrive il suo primo tentativo il codice del metodo che si sta sviluppando:
public class LocalMath
{
public double SquareRoot(double x)
{
double estimate = x;
double previousEstimate = -x;
while (System.Math.Abs(estimate - previousEstimate) > estimate / 1000)
{
previousEstimate = estimate;
estimate = (estimate * estimate - x) / (2 * estimate);
}
return estimate;
}
Peter esegue nuovamente i test e passano tutti i test:
Refactoring
Ora che il codice esegue la funzione main, Peter esamina il codice per trovare i modi di rendere prestazioni migliori o per rendere più facile da modificare in futuro. Egli si rende conto che è possibile ridurre il numero di calcoli eseguiti nel ciclo:
public class LocalMath
{
public double SquareRoot(double x)
{
double estimate = x;
double previousEstimate = -x;
while (System.Math.Abs(estimate - previousEstimate) > estimate / 1000)
{
previousEstimate = estimate;
estimate = (estimate + x / estimate) / 2;
//was: estimate = (estimate * estimate - x) / (2 * estimate);
}
return estimate;
}
Verifica che i test vengano superati:
Suggerimento
Ogni modifica apportata mentre si sviluppa il codice deve essere un'operazione di refactoring o un'estensione:
-
Mezzi di non modificare i test poiché non si sta aggiungendo nuove funzionalità di refactoring.
-
Estensione: aggiunta di test e apportare le modifiche al codice necessarie superare test nuove ed esistenti.
Se si sta aggiornando codice esistente per i requisiti che sono stati modificati, si eliminerà anche test precedente che non rappresentano i requisiti di correnti.
Evitare di modificare i test che hanno già superato.Al contrario, aggiungere nuovi test.Solo scrivere test che rappresentano un requisito reale.
Eseguire i test dopo ogni modifica.
... e ripetere
Peter continua la serie di estensione e refactoring passaggi, utilizzando il proprio elenco di piccole operazioni in linea di principio. Egli non sempre esegue un'operazione di refactoring dopo ogni estensione e ha talvolta esegue più di un passaggio di refactoring in successione. Ma gli unit test ha sempre eseguito dopo ogni modifica al codice.
A volte si aggiunge un test che non sono necessarie modifiche al codice, ma che aggiunge al suo sapendo che il codice funziona correttamente. Ad esempio, desidera assicurarsi che la funzione può essere utilizzata su una vasta gamma di ingressi. Scrive più test, come questo:
[TestMethod]
public void SqRtValueRange()
{
LocalMath math = new LocalMath();
for (double expectedResult = 1e-8;
expectedResult < 1e+8;
expectedResult = expectedResult * 3.2)
{
VerifyOneRootValue(math, expectedResult);
}
}
private void VerifyOneRootValue(LocalMath math, double expectedResult)
{
double input = expectedResult * expectedResult;
double actualResult = math.SquareRoot(input);
Assert.AreEqual(expectedResult, actualResult, expectedResult / 1e6);
}
Il test passa alla prima esecuzione:
Per assicurarsi che questo risultato non è un errore, egli temporaneamente introduce un piccolo errore nel suo rendono l'esito negativo del test. Dopo aver visualizzato l'errore, corretto viene nuovamente.
Suggerimento
Eseguire sempre un test hanno esito negativo prima di renderla passare.
Eccezioni
Peter passa ora alla scrittura di test per gli input eccezionali:
[TestMethod]
public void RootTestNegativeInput()
{
LocalMath math = new LocalMath();
try
{
math.SquareRoot(-10.0);
}
catch (ArgumentOutOfRangeException)
{
return;
}
catch
{
Assert.Fail("Wrong exception on negative input");
return;
}
Assert.Fail("No exception on negative input");
}
Questo test si inserisce il codice in un ciclo. Non deve utilizzare il Annulla pulsante in Explorer del Test. Consente di terminare il codice entro 10 secondi.
Peter desidera assicurarsi che un ciclo infinito accadeva nel server di compilazione. Anche se il server impone un timeout su un completo eseguito, è un timeout molto lungo e causerebbe un sostanziale ritardo. Di conseguenza, ha aggiunto un timeout esplicito per questo test:
[TestMethod, Timeout(1000)]
public void RootTestNegativeInput()
{...
Timeout esplicito rende il test hanno esito negativo.
Peter consente quindi di aggiornare il codice per gestire questo caso eccezionale:
public double SquareRoot(double x)
{
if (x <= 0.0)
{
throw new ArgumentOutOfRangeException();
}
Regressione
Il nuovo test passate, ma non esiste una regressione. Errore in un test che consente di passare a questo punto:
Peter individuare e correggere l'errore:
public double SquareRoot(double x)
{
if (x < 0.0) // not <=
{
throw new ArgumentOutOfRangeException();
}
Dopo aver corretto, passano tutti i test:
Suggerimento
Assicurarsi che ogni passate test dopo ogni modifica apportata al codice.
Codice copertura
A intervalli durante il suo lavoro e infine prima la archivia nel codice, Peter Ottiene un rapporto Code Coverage. Mostra la quantità del codice che è stato esercitato dal suo test.
Team di Peter ha lo scopo per la copertura di almeno 80%. Questo requisito per il codice generato, sono sempre rispettato perché può essere difficile ottenere una copertura elevata per questo tipo di codice.
Buona copertura non garantisce che tutte le funzionalità del componente sono stata testata e non garantisce che il codice funzionerà per ogni intervallo di valori di input. Tuttavia, esiste una correlazione piuttosto stretta tra una descrizione delle righe di codice e copertura dello spazio di un componente comportamentale. Pertanto, buona copertura rafforza la fiducia del team che si sta eseguendo il test la maggior parte del comportamento che dovrebbero.
Per ottenere un rapporto code coverage, via il test menu, scegliere esecuzione, Analisi Code Coverage per tutti i test. Quindi eseguire di nuovo tutti i test.
Peter Ottiene una copertura totale di 86%. Quando si espande il totale nel report, viene illustrato il codice che si sta sviluppando dispone di copertura del 100%. Questo è molto soddisfacente, perché il punteggio importante riguarda il codice sotto test. Le sezioni scoperte sono effettivamente in test stessi. Attivando e disattivando la Mostra colorazione codice copertura pulsante, Peter può vedere quali parti del codice di test non verificate. Tuttavia, decide che queste sezioni sono irrilevanti per copertura perché il codice di test e dovrebbe essere utilizzati solo se viene rilevato un errore.
Per verificare che un test specifico raggiunge in specifici rami del codice, è possibile impostare Mostra colorazione codice copertura e quindi eseguire il test utilizzando il esecuzione comando nel menu di scelta rapida.
Quando abbiamo terminati?
Peter continua ad aggiornare il codice in piccole operazioni fino a quando non si è accertato che:
Tutte le unità disponibili test vengono superati.
In un progetto con un insieme molto ampio di unit test, è poco pratico per uno sviluppatore di attesa per tutti per l'esecuzione. Al contrario, il progetto opera gestito-in servizio, in cui tutti i test automatizzati vengono eseguiti per ogni area di check-in sospensione prima viene unito nella struttura di origine. Il check-in viene rifiutato se l'esecuzione ha esito negativo. Ciò consente agli sviluppatori di eseguire un set minimo di unit test sul proprio computer e quindi procedere con altre operazioni, senza eseguire il rischio di interrompere la compilazione. Per ulteriori informazioni, vedere Utilizzare un processo di compilazione di archiviazione gestita per convalidare le modifiche.
Codice copertura soddisfi standard del team. il 75% è un requisito di progetto tipico.
Unit test del suo simulare ogni aspetto del comportamento che è necessario, compresi gli ingressi tipici ed eccezionali.
Il codice è facile da comprendere ed estendere.
Quando tutti questi criteri vengono soddisfatti, Peter è pronto per controllare il suo codice nel controllo del codice sorgente.
Principi di sviluppo di codice con gli unit test
Peter applica i seguenti principi durante lo sviluppo di codice:
Sviluppare unit test e il codice ed eseguiti frequentemente durante lo sviluppo. Gli unit test rappresentano la specifica del componente.
Non modificare unit test, a meno che non sono stati modificati i requisiti o le prove sono state errate. Come si estendono le funzionalità del codice, aggiungere gradualmente nuovi test.
Obiettivo per almeno il 75% del codice mediante i test. Esaminare i risultati di code coverage a intervalli e prima di archiviare codice sorgente.
Controllare negli unit test e il codice in modo che eseguano per il server continua o regolare le compilazioni.
Laddove possibile, per ogni parte di funzionalità, è necessario scrivere che lo unit test prima. Eseguire questa operazione prima di sviluppare il codice che soddisfa tale.
Archiviare le modifiche
Prima di controllare le relative modifiche, Peter utilizza nuovamente Lync per condividere il suo schermo con i colleghi Julia è possibile in modo informale e in modo interattivo esaminare con lui ciò che ha creato. I test continuano a essere lo stato attivo della loro discussione perché Julia è principalmente interessata alla quale il codice è, il non funzionamento. Julia accetta che cosa ha scritto Peter soddisfi le esigenze.
Peter controlla tutte le modifiche che ha apportato, tra cui entrambi i test e il codice e li associa l'attività ha completato. Il check-in code di sistema di compilazione team automatizzati del team per convalidare le modifiche utilizzando il processo di generazione di elementi di configurazione di compilazione del team. Questo processo di compilazione consente al team di ridurre gli errori nel loro codebase dalla generazione e test, ovvero in un ambiente pulito separato dai computer di sviluppo, ogni modifica del team.
Peter è notificato al termine della compilazione. Nei risultati della compilazione finestra, egli constata che la compilazione è stata completata e tutti i test passati.
Per archiviare le modifiche
Sulla barra dei menu, scegliere visualizzazione, Di Team Explorer.
In Team Explorer, scegliere casa , quindi scegliere Lavoro personale.
Nella Lavoro personale , selezionare Check-In.
Esaminare il contenuto del Le modifiche in sospeso pagina per assicurarsi che:
Tutte le modifiche rilevanti sono elencate Le modifiche incluse
Tutti gli elementi di lavoro rilevanti sono elencati Gli elementi di lavoro correlati.
Specificare un commento per aiutare il team di comprendere lo scopo di queste modifiche quando si esamina la cronologia del controllo della versione di cartelle e i file modificati.
Scegliere Check-In.
Per integrare in modo continuo il codice
Per ulteriori informazioni su come definire un processo di compilazione di integrazione continuata, vedere Configurare una compilazione CI. Dopo aver impostato il processo di compilazione, è possibile scegliere di ricevere una notifica sui risultati delle compilazioni del team.
Per ulteriori informazioni, vedere Eseguire, monitorare e gestire le compilazioni.
Successivo (sospendere il lavoro, correggere un bug e condurre una revisione del codice)