Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

CodedUI test per Windows Store Apps

Link copiato negli appunti

Tra le tante novità introdotte da Visual Studio 2013, troviamo la possibilità di eseguire CodedUI test per le applicazioni Windows Store App. Prima di entrare nel merito di come creare ed eseguire tali test e di quali siano le attuali limitazioni, cerchiamo di capire cosa sono i Coded UI Test.

Breve introduzione ai CodedUI Test

I Coded UI test sono una particolare tipologia di test che consente di testare e, quindi, validare il comportamento di una interfaccia grafica in maniera automatica senza la presenza di un operatore umano.

Di fatto un Coded UI test è a tutti gli effetti un test (sfrutta, cioè un framework di test supportato da Visual Studio) con la capacità di eseguire operazioni sull'interfaccia grafica (ad esempio la pressione di un tasto o la verifica della presenza di un testo all'interno di un textbox).

Grazie all'assenza di operatori che effettuano manualmente i test, si può aggiungere un numero maggiore di test da affiancare alle tecniche di testing automatico già esistenti (ad esempio gli Unit Test).

Visual Studio dispone di strumenti e supporto per la creazione e l'esecuzione di CodedUI test fin dalla versione 2010, ma solo nella versione 2013 abbiamo questa feature anche per le Windows Store App.

Progetto CodedUI Test e la UIMap

I coded UI test per le Windows Store App hanno un loro progetto specifico all'interno di Visual Studio:

Durante la creazione del progetto di test, Visual Studio richiede se creare la UI Map o se il test deve essere scritto manualmente.

La UI Map contiene la definizione degli oggetti grafici che andremo a "sollecitare" nei nostri test e può essere modificata in seguito utilizzando lo strumento "Code UI Test Tool" (CUIT) presente nel menu test di Visual Studio.

Selezionando l'opzione di editing della UI Map viene aperto il CUIT come mostrato nella figura seguente:

Il tool consente di creare una mappa dei controlli grafici presenti nell'applicazione da testare in modo da poterli referenziare nel codice del test stesso. Per poter aggiungere un controllo grafico nella mappa dei controlli che utilizzeremo per il test, è sufficiente cliccare sullo strumento di selezione presente nella piccola toolbar del CUIT e trascinare il cursore (mantenendo premuto il tasto sinistro) al di sopra del controllo desiderato (evidenziato da un bordo colorato).

Selezionando un controllo della UI si apre una finestra che mostra il nome del controllo e le sue proprietà.

Selezioniamo, dunque, i singoli controlli che intendiamo utilizzare nei nostri test, confermiamo per ognuno l'aggiunta alla mappa con l'apposito comando e, infine, salviamo la mappa stessa con il comando di "generazione del codice".

Nei progetti CodedUI test per altre tecnologie (ad esempio WPF), il CUIT può essere utilizzato per registrare il test stesso. Nelle Windows Store App non è possibile, al momento, registrare i test con il CUIT.

Nel momento in cui eseguiamo il comando di generazione della UI Map, Visual Studio crea un file UIMap.uitest che contiene la mappa stessa e un file di codice (UIMap.Designer.cs) che contiene la classe UIMap che espone le finestre e i controlli per poterli utilizzare nel codice.

La seguente figura mostra il diagramma delle classi generato dallo strumento:

Come possiamo vedere la classe UIMap espone un'istanza della finestra che stiamo testando (UIW8CidedUITestWindow nell'esempio) la quale, a sua volta, espone i vari controlli.

Scriviamo il test

Una volta generata la classe UIMap e non potendo utilizzare il registratore dei test, dobbiamo armarci di pazienza e scrivere il nostro test.

Una classe che implementa dei CodedUI test è una normale classe decorata con un attributo che comunica all'ambiente di sviluppo che tale classe potrebbe contenere dei metodi di test (di tipo CodedUI).

Un esempio è la seguente classe:

Come accennato in precedenza, la classe CodedUITest è decorata con l'attributo CodedUITest per segnalare all'ambiente di sviluppo che tale classe è un contenitore di test di tipo CodedUI e, in più per WindowsStore.

Ogni metodo di test, come accade anche per i canonici unit test, è decorato con l'attributo TestMethod.

Osserviamo che la classe mette a disposizione una istanza della UIMap attraverso la quale possiamo sollecitare l'applicazione.

L'applicazione che andiamo a testare è una sorta di gioco per imparare le addizioni. L'applicazione propone il primo addendo e il risultato e l'utente deve indovinare il secondo addendo.

Proviamo a realizzare il primo test: vogliamo verificare che se digitiamo la risposta corretta l'applicazione mostra la scritta "Bravo!!".

Prima cosa che dobbiamo fare è dire al test di aprire la nostra applicazione e per fare ciò possiamo utilizzare la classe XamlWindow (contenuta nel namespace Microsoft.VisualStudio.TestTools.UITesting.WindowsRuntimeControls in cui troviamo tutte le classi per il testing della parte XAML).

XamlWindow appWindow = XamlWindow.Launch("W8CodedUITest_zajsc8zqgb60r!App");

Il metodo statico Launch accetta l'app package family name (seguito dalla stringa "!App") che possiamo trovare nel manifest della nostra applicazione.

Una volta lanciata l'applicazione, recuperiamo il testo contenuto nel controllo del primo addendo e quello contenuto nel controllo del risultato:

var resultText = UIMap.UIW8CodedUITestWindow.UIResultText.DisplayText;
var firstNumberText = UIMap.UIW8CodedUITestWindow.UIFirstNumberText.DisplayText;

Per recuperare a runtime il testo contenuto nei controlli utilizziamo la classe UIMap come già detto in precedenza. Recuperati i valori testuali, li convertiamo in numeri interi, deduciamo il numero corretto da digitare e recuperiamo il bottone che dovremmo premere:

var result = int.Parse(resultText);
var firstNumber = int.Parse(firstNumberText);
var secondNumber = result - firstNumber;
XamlControl controlToTap = GetXamlControlFromNumber(secondNumber);

Il metodo GetXamlControlFromNumber restituisce il corrispondente bottone da premere (recuperato dalla UIMap):

private void GetXamlControlFromNumber(int secondNumber)
{
    XamlControl controlToTap = null;
    switch (secondNumber)
    {
        case 0:
            controlToTap = UIMap.UIW8CodedUITestWindow.UIItem0Button;
            break;
        case 1:
            controlToTap = UIMap.UIW8CodedUITestWindow.UIItem1Button;
            break;
        case 2:
            controlToTap = UIMap.UIW8CodedUITestWindow.UIItem2Button;
            break;
        case 3:
            controlToTap = UIMap.UIW8CodedUITestWindow.UIItem3Button;
            break;
        case 4:
            controlToTap = UIMap.UIW8CodedUITestWindow.UIItem4Button;
            break;
        case 5:
            controlToTap = UIMap.UIW8CodedUITestWindow.UIItem5Button;
            break;
        case 6:
            controlToTap = UIMap.UIW8CodedUITestWindow.UIItem6Button;
            break;
        case 7:
            controlToTap = UIMap.UIW8CodedUITestWindow.UIItem7Button;
            break;
        case 8:
            controlToTap = UIMap.UIW8CodedUITestWindow.UIItem8Button;
            break;
        case 9:
            controlToTap = UIMap.UIW8CodedUITestWindow.UIItem9Button;
            break;
        default:
            Assert.Inconclusive();
            break;
    }
    return controlToTap;
}

Recuperato il bottone da premere dobbiamo comunicare al metodo di test di eseguire tale azione. In questo caso ci vengono in aiuto alcune classi helper presenti nel namespace Microsoft.VisualStudio.TestTools.UITesting che ci consentono di simulare l'input utente.

In questo caso simuliamo la gesture di tipo tap:

Gesture.Tap(controlToTap);

Per completare il test non ci rimane che verificare che l'interfaccia si comporti come ci si aspetta. Nella fattispecie, in caso di risposta esatta deve apparire il pannello con la scritta "Bravo!!", quindi potremo scrivere:

var isReady = UIMap.UIW8CodedUITestWindow.UIResultMessageText.WaitForControlReady(2000);
Assert.IsTrue(isReady);
var resultMessage = UIMap.UIW8CodedUITestWindow.UIResultMessageText.DisplayText;
Assert.IsTrue(resultMessage.StartsWith("Bravo"));

Nel codice precedente sfruttiamo un metodo della classe XamlControl (classe base di tutti I controlli della UIMap) per attendere (al massimo 2 secondi) che un controllo sia pronto (in questo caso il TextBlock con la scritta "Bravo!!") e, quindi, che all'interno del TextBlock ci sia effettivamente la scritta.

Per la fase di assert si utilizza la canonica classe Assert nota anche a chi sviluppa unit test.

Gesture, keyboard e mouse

Nel precedente test abbiamo visto l'utilizzo della classe statica Gesture per simulare il tap sull'interfaccia. Il framework di test per le Store App ci mette a disposizione altre classi di questo tipo, in particolare abbiamo:

  • Gesture: classe statica che permette di simulare le gesture principali come tap, doubletap, swipe, pinch e via dicendo;
  • Keyboard: permette di simulare la pressione di uno o più tasti della tastiera. Possiamo anche decidere il delay tra un tasto e l'altro.
  • Mouse: permette di simulare il mouse (click, doubleclick, drag & drop). Possiamo impostare la posizione del puntatore del mouse o la velocità di movimento dello stesso.

Utilizzando keyboard e mouse, il test precedente potrebbe essere scritto in questo modo:

[TestMethod]
public void CodedUITestMethod3()
{
    XamlWindow appWindow = XamlWindow.Launch("W8CodedUITest_zajsc8zqgb60r!App");
    var resultText = UIMap.UIW8CodedUITestWindow.UIResultText.DisplayText;
    var firstNumberText = UIMap.UIW8CodedUITestWindow.UIFirstNumberText.DisplayText;
    var result = int.Parse(resultText);
    var firstNumber = int.Parse(firstNumberText);
    var secondNumber = result - firstNumber ;
    XamlControl controlToClick = GetXamlControlFromNumber(secondNumber);
    Mouse.Click(controlToClick);
    var isReady = UIMap.UIW8CodedUITestWindow.UIResultMessageText.WaitForControlReady(2000);
    Assert.IsTrue(isReady);
    var resultMessage = UIMap.UIW8CodedUITestWindow.UIResultMessageText.DisplayText;
    Assert.IsTrue(resultMessage.StartsWith("Peccato"));
}

Il vantaggio di utilizzare l'istanza di XamlWindows sta nel fatto che quando viene rilasciata l'istanza stessa, l'applicazione viene chiusa.

Conclusioni

I CodedUI test per le Windows Store App pur con alcune limitazioni, rappresentano un ottimo modo per testare la nostra interfaccia grafica.

Ti consigliamo anche