openQA para desarrolladores y mantenedores
KDE Linux usa openQA to automatically para probar automáticamente cada imagen del sistema antes de publicarla. openQA arranca cada imagen en una máquina virtual y comprueba que se puede instalar, actualizar y usar de forma correcta.
openQA usa cierta terminología: un trabajo es una ejecución de un paquete de pruebas sobre una imagen, mientras que un trabajador es la máquina o el contenedor que ejecuta el trabajo. La documentación de openQA explica estos y otros conceptos, incluidos los módulos de pruebas, los grupos de trabajo, activos y la interfaz web.
Cómo funcionan las pruebas
El proceso de la prueba se ejecuta junto con la canalización de integración continua (CI), lo que le permite usar las imágenes y los discos virtuales generados durante la compilación sin tener que subir esos archivos grandes a otro lugar. Las pruebas se envían a la máquina virtual mediante una extensión del sistema y se comunican con ella a través de SSH.
Las pruebas de escritorio usan la API de accesibilidad a través de selenium-webdriver-at-spi, lo que les permite interactuar con las aplicaciones y comprobar su estado sin depender únicamente de la comparación de capturas de pantalla. El conjunto de pruebas también verifica si hay servicios del sistema con fallos, procesos de escritorio bloqueados, problemas de red y regresiones en las órdenes de KDE Linux.
Flujo de trabajo del mantenedor y de la canalización de CI
En la rama predeterminada protegida del repositorio principal de KDE Linux, la canalización funciona de la siguiente manera:
- El trabajo imaging compila, firma y prepara la imagen y su canal sysupdate en
storage.kde.org. - El trabajo trigger-openqa inicia la canalización en os-autoinst-distri-kdelinux, pasándole la URL de la imagen preparada y la URL del canal sysupdate.
- La canalización posterior ejecuta el flujo normal de instalación y verificación, así como el flujo de actualización.
- El trabajo publish principal se ejecuta solo después de que la canalización de openQA haya finalizado correctamente. Su función es promocionar la imagen ya preparada para su consumo público.
Esto convierte un fallo de openQA en un obstáculo para la publicación de la imagen. Para empezar, abre la canalización descendente del trabajo trigger-openqa y, a continuación, abre el trabajo de openQA que ha fallado desde su registro de CI. La página del trabajo muestra los módulos de prueba en orden y permite identificar si el fallo se produce durante la instalación, las pruebas de integridad del sistema instalado o la ruta de actualización.
Descargar una imagen preparada
El enlace que se proporciona tras el mensaje de registro «En caso de fallo, puedes inspeccionar y descargar la imagen .iso y el árbol sysupdate en…», abre un explorador de almacenamiento para la compilación bajo prueba. Descarga la .iso ahí para arrancarla manualmente o proporciónasela a una pila openQA local. El árbol sysupdate contiene los artefactos de actualización preparados que usa la prueba de actualización.
Investigar un trabajo que ha fallado
Abre el trabajo en la interfaz web de openQA y selecciona primero el módulo que ha fallado. El enlace a la interfaz web aparecerá tras el mensaje del registro «El trabajo de prueba autoinst-log.txt del trabajador openQA y el registro «test-engine». Este es el registro principal para el propio trabajo.
Para las pruebas que ejecutan órdenes en el sistema bajo prueba, KDE Linux las ejecuta en servicios systemd transitorios y graba el diario del servicio como salida de diagnóstico en el resultado de la prueba. Inspecciona el autoinst-log.txt de la salida de la orden y el diario. También puedes descargar el archivo *kde-linux-collected-logs.tar.zst para los registros capturados por la herramienta collect-logs.
Ejecutar pruebas localmente
Puedes usar openQA para probar una imagen compilada localmente antes de enviar un cambio. Esto es necesario cuando se trabaja con una bifurcación fuera de kde-linux/kde-linux: su canalización de CI crea una imagen de prueba, pero no lanza la canalización openQA. También es útil cuando se desarrollan pruebas para los cambios propios.
El repositorio de pruebas openQA de KDE Linux incluye una pila local que contiene tanto una interfaz web de openQA como un trabajador. Requiere Podman y podman-compose, que se incluyen en KDE Linux.
Clona el repositorio de pruebas y luego sitúa la imagen .iso de KDE Linux que quieras probar en su directorio raíz. Si no hay ninguna imagen presente, el lanzador de la prueba descarga la última imagen disponible públicamente.
Inicia la pila local.
./mock.sh up
Cuando esté preparada, abre http://localhost:1080 para inspeccionar la interfaz web de openQA. Los trabajos no se envían de forma automática, por lo que debes abrir un intérprete en el contenedor y enviar el flujo «normal install and sanity-test».
podman exec -it openqa-single-instance bash ./qa flow
Para ejecutar el flujo «upgrade», añade --upgrade:
./qa flow --upgrade
Para ejecutar el flujo «disk-encryption install-test», añade --encrypt:
./qa flow --encrypt
También se pueden combinar las opciones --upgrade y --encrypt:
./qa flow --upgrade --encrypt
El trabajo sanity-test necesita que el trabajo install-system se ejecute primero porque usa el disco virtual creado por la instalación. Para concentrarse en una determinada prueba, ajusta los trabajos enviados en lib/worker/job_flow.py o ejecuta un trabajo individual con ./qa job sin olvidarte de esta dependencia. Ejecuta ./qa-job --help para ver las opciones que necesita.
Por ejemplo, para ejecutar un trabajo install-system donde has descargado un archivo .iso en el directorio del repositorio:
./qa job \
--live ./kde-linux_<build-id>.iso \
--hdd kde-linux_<build-id>.qcow2 \
--sysext ./openqa-sysext.img \
--build <build-id> \
--name install-system \
--flavor live
Cuando hayas terminado, detén la pila y elimina sus volúmenes locales.
./mock.sh down -v
Escribir una prueba
Las definiciones de la prueba y su código residen en os-autoinst-distri-kdelinux. Añade la prueba al flujo apropiado en main.pm: el flujo «live-install», la prueba de salud «installed-system» o el flujo «upgrade». Las pruebas se componen generalmente de un pequeño adaptador openQA en tests/ y de una prueba Python que se ejecuta en el sistema bajo prueba desde extensions/openqa/usr/lib/kde-linux-openqa/tests/.
Escoge el tipo de prueba según lo que quieras comprobar:
- Usa una
unittestnormal de Python para herramientas de la línea de órdenes, servicios, estado de sistemas de archivos u otro comportamiento no gráfico. - Usa Selenium mediante
selenium-webdriver-at-spicuando el comportamiento requiera interactuar con una aplicación gráfica.
Pruebas normales de Python
Crea una unittest en el directorio de pruebas de la extensión del sistema mencionado anteriormente. Esta prueba debe realizar aserciones sobre el sistema bajo prueba y escribir sus resultados en un archivo XML de JUnit, que se recopilará automáticamente como un activo de openQA y un informe de GitLab CI.
import unittest
from lib.sut import openqa_junit_xml
class ExampleTests(unittest.TestCase):
def test_expected_behaviour(self):
self.assertTrue(True)
if __name__ == "__main__":
openqa_junit_xml.run(ExampleTests, "example")
Crea un adaptador coincidente en tests/ que obtenga openQA para ejecutar la prueba en el anfitrión.
from testapi import *
from lib.test import cli_test
def run(self):
cli_test.CliTest("example").run_python()
Finalmente, registra el adaptador en el flujo relevante de main.pm. El adaptador recopila el resultado de JUnit y la salida de la orden, de modo que los fallos aparezcan en el trabajo openQA y en los artefactos CI.
Pruebas gráficas con Selenium
Las pruebas gráficas también son clases unittest de Python, pero usan el controlador de Appium/Selenium para encontrar elementos accesibles de la interfaz de usuario e interactuar con ellos. El lanzador de Selenium activa la infraestructura de accesibilidad e inicia el controlador automáticamente.
Por ejemplo, una prueba gráfica crea un controlador para su aplicación, interactúa con los elementos accesibles y cierra el controlador después:
import unittest
from appium import webdriver
from appium.options.common.base import AppiumOptions
from appium.webdriver.common.appiumby import AppiumBy
from lib.test import openqa_junit_xml
class ExampleTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
options = AppiumOptions()
options.set_capability("app", "org.kde.example.desktop")
cls.driver = webdriver.Remote("http://127.0.0.1:4723", options=options)
@classmethod
def tearDownClass(cls):
cls.driver.quit()
def test_expected_behaviour(self):
self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "example-control").click()
if __name__ == "__main__":
openqa_junit_xml.run(ExampleTests, "example")
Ejecuta el adaptador con run_selenium() en lugar de con run_python(). Pásale el usuario de pruebas instalado para las aplicaciones de escritorio:
from testapi import *
from lib.test import cli_test
from lib.common import user_manager
def run(self):
cli_test.CliTest("example").run_selenium(user=user_manager.installed())
De forma similar a las pruebas normales de Python, añade su adaptador a main.pm, ejecútalo localmente durante el desarrollo e inclúyelo en el flujo de pruebas que pone a prueba la funcionalidad.
Para más información sobre la escritura de pruebas con Selenium, consulta Pruebas de automatización de Appium y Pruebas de la interfaz gráfica con selenium-webdriver-at-spi.
Saber más
Para una explicación más detallada sobre la prueba y su implementación, consulta Pruebas openQA en KDE Linux. El desarrollo de la infraestructura de pruebas se lleva a cabo en el repositorio os-autoinst-distri-kdelinux.
Artículo escrito por Thomas Duckworth bajo las condiciones de la licencia CC-BY-4.0.