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
Il testing dell'interfaccia utente è composto 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 in 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
Scrittura dei test
Xisco Faulí's presentation from FOSDEM 2021, LibreOffice QA - how to write your first test, walks through the process of creating tests.
Xisco's presentation from FOSDEM 2022 shows Things you can test in a UITest.
Makefile
A simple makefile for the UI testing looks like the demo makefile. The important part is to use the UITest gbuild class and let the gb_UITest_add_module point to the directories with test files.
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.
Scrittura del 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"}))
Andate 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 |
|
--- |
ComboBox |
|
|
Tabs |
|
|
ListBox(per posizione) |
|
|
Casella elenco (per nome |
|
|
Finestra a schede (per nome) |
|
--- |
Campo di selezione numerica |
|
|
Pulsante di opzione |
|
|
ColorListBox |
|
--- |
MenuButton |
|
--- |
Azione della parola chiave
Esempio/Campione
from libreoffice.uno.propertyvalue import mkPropertyValues
ui_object.executeAction("TYPE", mkPropertyValues({"KEYCODE":"CTRL+A"}))
Codice 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
- Usa 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
- Avvia LibreOffice con
Note: "LO_COLLECT_UIINFO" is a relative path under "instdir/uitest/".LO_COLLECT_UIINFO="test.log" SAL_USE_VCLPLUGIN=gen instdir/program/soffice
- Simula ciò che vuoi fare con il mouse
- Chiudi LibreOffice
- Apri il file risultante in instdir/uitest/test.log
- Accedi alla directory del registratore dell'interfaccia utente con questo comando:
cd uitest/ui_logger_dsl/
- Make sure that your python has textX library installed
- Usa 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 tua scelta dove desideri vedere il codice generato.python dsl_core.py <percorso_del_file_di_log> <percorso_del_nuovo_file_python>
Puoi 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à headless 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)
It is also possible to use a shell script for starting a test.
Nota che devi 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, modificare di conseguenza la variabile TDOC per puntare alla directory in cui si trova il file.
Quando si esegue il test con l'interfaccia utente visibile, si noterà che il test è troppo veloce per vedere cosa sta succedendo. Una soluzione rapida e sporca è quella di aggiungere a python (import time) time.sleep(10), che interrompe l'esecuzione per un po'. L'altra soluzione che si può effettivamente lasciare nel codice (solo pochi utili in un test) in posti interessanti è 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, eseguire 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
- Double-clicking on forms. See tdf#133641 for inspiration
- File - wizard
- Impress - Minimizzatore di presentazioni
- Registrazione ( LO_COLLECT_UIINFO) in Windows
- Doppio click
- registrazione dei grafici
- barra degli strumenti inferiore di Calc
- better support for shortcuts (tdf#124931)
Elenco dei test dell'interfaccia utente nel master
Potete consultare la lista dei UItest già implementati.
Trovare errori
Abbiamo la parola chiave needUITest in Bugzilla per tracciare tutti i bug che necessitano di un UITest per essere testati automaticamente: