Sviluppo/Test dell'interfaccia utente (UI)
TDF LibreOffice Document Liberation Project Blog comunitari Weblate Nextcloud Redmine Ask LibreOffice Donazione
Questa è la documentazione preliminare per il framework di test dell'interfaccia utente, con un'attenzione particolare alla parte Python
Architettura
La prova dell'interfaccia utente è composta da due parti: una componente in C++ che avvolge l'interfaccia utente di LibreOffice in una libreria di introspezione e un framework Python con il codice di test vero e proprio. La connessione tra le due parti avviene tramite una semplice interfaccia UNO, per lo più non tipizzata.
Libreria di introspezione C++
La libreria di introspezione C++ consiste in un'API UNO che viene utilizzata per la comunicazione con la parte Python del framework e i wrapper per molti oggetti dell'interfaccia utente. L'interfaccia UNO ha solo alcuni metodi e la maggior parte della comunicazione avviene tramite parametri di tipo stringa.
Il wrapper per gli oggetti dell'interfaccia utente fornisce circa gli stessi metodi dell'interfaccia UNO, con l'aggiunta di alcuni metodi di supporto.
Framework Python
Prove di scrittura
La presentazione di Xisco Faulí al FOSDEM 2021, LibreOffice QA - come scrivere il vostro primo test, in inglese, illustra il processo di creazione dei test.
La presentazione di Xisco al FOSDEM 2022 mostra Cose che potete testare in un UITest, in inglese.
Parte di un makefile
Un semplice makefile per il test dell'interfaccia utente è simile a il makefile demo, in inglese. La parte importante è usare la classe gbuild UITest e lasciare che gb_UITest_add_module punti alle directory con i file di test.
Normalmente non è richiesto nient'altro, poiché la maggior parte delle operazioni viene gestita dalla classe gbuild UITest.
$(eval $(call gb_UITest_UITest,range_name))
$(eval $(call gb_UITest_add_modules,range_name,$(SRCDIR)/sc/qa/uitest,\
test_dir1/ \
test_dir2/ \
))
Il parametro range_name è il nome del target del test. La parte $(SRCDIR/sc/qa/uitest) è la directory di base e i parametri in quella parte elencano le directory in cui cercare i test.
In alternativa, è possibile eseguire il test con un file specifico registrymodifications.xcu per supportare l'esecuzione con impostazioni di configurazione personalizzate. Ogni test dispone di un proprio profilo utente nella directory workdir/UITest/test_name/user/. Con il seguente frammento di makefile, è possibile copiare un file all'interno di questa directory.
$(eval $(call gb_UITest_use_configuration,range_name,$(SRCDIR)/sc/qa/uitest/range_name/registrymodifications.xcu))
Questo comando copierebbe il file sc/qa/uitest/range_name/registrymodifications.xcu nel profilo utente e il test verrebbe eseguito con queste impostazioni.
Scrivere il codice Python
Infrastruttura
Comandi disponibili sugli elementi dell'interfaccia utente
Generico
Gestione dello stato degli oggetti UI
Il metodo per ottenere lo stato dell'oggetto UI è fornito da tutti gli elementi UI. Il metodo restituisce lo stato come una sequenza di PropertyValue.
ui_element.getState()
Il framework di test UI fornisce un metodo per convertire la sequenza restituita di PropertyValue in un dizionario Python.
from uitest.uihelper.common import get_state_as_dict
get_state_as_dict(ui_element)
Inviare input da tastiera a un elemento
from uitest.uihelper.common import type_text
xWriterDoc = self.xUITest.getTopFocusWindow()
xWriterEdit = xWriterDoc.getChild("writer_edit")
type_text(xWriterEdit, "Test")
Selezionare il testo
from uitest.uihelper.common import select_text
xEdit = xAddNameDlg.getChild("edit")
select_text(xEdit, from_pos="2", to="12")
Impostare lo zoom
xWriterEdit = xWriterDoc.getChild("writer_edit")
xWriterEdit.executeAction("SET", mkPropertyValues({"ZOOM": "200"}))
Andare alla pagina
xWriterEdit = xWriterDoc.getChild("writer_edit")
xWriterEdit.executeAction("GOTO", mkPropertyValues({"PAGE": "1"}))
Azioni di Controllo
Controllo | Codice | Asserzione |
---|---|---|
Bottone |
|
--- |
Casella di testo |
|
|
Casella di controllo |
|
|
Widget della mappa dei caratteri |
|
--- |
Elenco degli alberi |
|
--- |
Casella combinata |
|
|
Tabulazioni |
|
|
Casella elenco (per posizione) |
|
|
Casella elenco (per nome) |
|
|
Finestra a schede (per nome) |
|
--- |
Campo di selezione numerica |
|
|
Pulsante di opzione |
|
|
ColorListBox |
|
--- |
MenuButton |
|
--- |
Azioni con parola chiave
Esempio:
from libreoffice.uno.propertyvalue import mkPropertyValues
ui_object.executeAction("TYPE", mkPropertyValues({"KEYCODE":"CTRL+A"}))
CODICI CHIAVE:
ESC
TAB
DOWN
UP
LEFT
RIGHT
DELETE
INSERT
BACKSPACE
RETURN
HOME
END
PAGEUP
PAGEDOWN
CTRL
ALT
SHIFT
Come estendere la libreria di introspezione
Estensione degli elementi UI che estendono vcl::Window
Altri elementi UI
Strumenti per scrivere un test
La parte difficile nello scrivere un test è capire quali comandi UNO inviare e quale azione chiamare su un oggetto dell'interfaccia utente. Fortunatamente, è possibile registrare i comandi UNO
- Usate queste righe in .bashrc o .cshrc:
export PYTHONPATH=/"Percorso del repository di LibreOffice"/instdir/program/ export URE_BOOTSTRAP=file:///"Path of LibreOffice repo"/instdir/program/fundamentalrc
- Avviate LibreOffice con
Nota: "LO_COLLECT_UIINFO" è un percorso relativo sotto "instdir/uitest/".LO_COLLECT_UIINFO="test.log" SAL_USE_VCLPLUGIN=gen instdir/program/soffice
- Simula ciò che volete fare con il mouse
- Chiudete LibreOffice
- Aprite il file risultante in instdir/uitest/test.log
- Accedete alla directory del registratore dell'interfaccia utente con questo comando:
cd uitest/ui_logger_dsl/
- Assicuratevi che il vostro python abbia installato textX library
- Usate il seguente comando
<percorso_del_file_di_log> deve essere sostituito con qualcosa come SourceDirectory/core/instdir/uitest/test.log e <percorso_del_nuovo_file_python> può essere una posizione a vostra scelta dove desideriate vedere il codice generato.python dsl_core.py <percorso_del_file_di_log> <percorso_del_nuovo_file_python>
Potete seguire tutti questi passaggi in questo video di YouTube
Siete pregati di accettare questo video. Accettando si accederà ai contenuti di YouTube, un servizio fornito da una terza parte esterna.
Eseguire il test
Prima di spingere il test su master, dobbiamo ovviamente verificare che il test funzioni. Un modo semplice è eseguire tutti i test dell'interfaccia utente nel modulo uitest tramite il comando make uitest.uicheck. Tuttavia, vorremmo vedere l'interfaccia utente mentre il test viene eseguito, e i test vengono eseguiti in modalità senza intestazione per impostazione predefinita. Questo si ottiene eseguendo il seguente comando nella directory core:
(cd sc && make -srj1 UITest_sort UITEST_TEST_NAME="sorting.CalcSorting.test_Sortingbuttons_detect_columnheaders" SAL_USE_VCLPLUGIN=gen)
È anche possibile utilizzare uno script da shell per avviare un test.
Nota che dovete eseguire questo script dalla directory di origine del core di LibreOffice.
Potrebbero essere necessarie anche alcune variabili d'ambiente per farlo funzionare, quindi lo script completo sarebbe del tipo:
export SRCDIR=$PWD
export PYTHONPATH=$SRCDIR/instdir/program:unotest/source/python
export URE_BOOTSTRAP=file://$SRCDIR/instdir/program/fundamentalrc
export TestUserDir=file:///tmp
export TDOC=$SRCDIR/sw/qa/uitest/data
export SAL_USE_VCLPLUGIN=gen
export LC_ALL=C
rm -rf /tmp/libreoffice/4
python3 "$SRCDIR"/uitest/test_main.py --soffice=path:"$SRCDIR"/instdir/program/soffice --userdir=file:///tmp/libreoffice/4 --file="$SRCDIR"/sc/qa/uitest/sort/sorting.py
Nel caso in cui il test chiami get_url_for_data_file
per aprire un file, modificate di conseguenza la variabile TDOC per puntare alla directory in cui si trova il file.
Quando eseguite il test con l'interfaccia utente visibile, noterete che il test è troppo veloce per vedere cosa sta succedendo. Una soluzione rapida e non corretta è quella di aggiungere a python (import time) time.sleep(10), che interrompe l'esecuzione per un po'. L'altra soluzione che potete effettivamente lasciare nel codice in posti di interesse (solo in pochi punti utili in un test) è uitest.debug.sleep. Questo metodo viene ignorato a meno che il test non venga avviato in modalità debug, passando il parametro --debug al test.
Quando è necessario eseguire un solo test nel file di script di test, eseguite il comando seguente:
UITEST_TEST_NAME="FILENAME.CLASS_NAME.TEST_NAME" ./execute.sh
per esempio
UITEST_TEST_NAME="sorting.CalcSorting.test_Sortingbuttons_detect_columnheaders" ./execute.sh
Elementi dell'interfaccia utente non supportati
- Supporto di base
- Selezionatore di diapositive in Impress
- Doppio clic sui formulari. Si veda per ispirazione tdf#133641
- File - creazione guidata
- Impress - Minimizzatore di presentazioni
- Registrazione ( LO_COLLECT_UIINFO) in Windows
- Doppio clic
- registrazione dei grafici
- barra inferiore degli strumenti di Calc
- maggior supporto per le scorciatoie (tdf#124931)
Elenco dei test dell'interfaccia utente nel master
Potete consultare la lista dei UItest già implementati.
Trovare bug
Abbiamo la parola chiave needUITest in Bugzilla per tracciare tutti i bug che necessitano di un UITest per essere testati automaticamente: