Spring naar inhoud

openQA voor ontwikkelaars en onderhouder

KDE Linux gebruikt openQA om elk systeem-image automatisch te testen voordat het wordt gepubliceerd. openQA start elk image op in een virtuele machine en controleert of het succesvol kan worden geïnstalleerd, opgewaardeerd en gebruikt.

openQA hanteert specifieke terminologie: een job is een enkele uitvoering van een testsuite op een image, terwijl een worker de machine of container is die de job uitvoert. De openQA-documentatie licht deze en andere concepten toe, waaronder testmodules, jobgroepen, assets en de web-UI.

Hoe de testen werken

De test-worker draait parallel aan de CI-pipeline, waardoor deze gebruik kan maken van de door de build gegenereerde images en virtuele schijven zonder die grote bestanden elders te hoeven uploaden. Tests worden via een systeemextensie aan de virtuele machine aangeleverd en communiceren ermee via SSH.

Bureaubladtesten maken gebruik van de toegankelijkheids-API via selenium-webdriver-at-spi, waardoor ze met applicaties kunnen interageren en de status ervan kunnen controleren zonder uitsluitend afhankelijk te zijn van screenshot-vergelijking. Daarnaast controleert de testsuite op falende systeemdiensten, gecrashte bureaubladprocessen, netwerkproblemen en regressies in KDE Linux-commando's.

CI-pijplijn en workflow voor onderhouders

Op de beveiligde standaardbranch van de upstream KDE Linux-repository werkt de pijpelijn als volgt:

  1. De imaging-taak bouwt en ondertekent de image en het bijbehorende sysupdate-kanaal, en plaatst deze op storage.kde.org.
  2. De trigger-openqa-job start de pijplijn in os-autoinst-distri-kdelinux en geeft daarbij de URL van de staged image en de URL van het sysupdate-kanaal door.
  3. De downstream-pipeline voert de install- en upgrade-flows uit die in tests/tests.toml zijn gedefinieerd, telkens voor zowel ongecodeerde als versleutelde installaties.
  4. De upstream publish-taak wordt pas uitgevoerd nadat de openQA-pijplijn succesvol is afgerond. Deze bevordert de reeds klaargezette image voor openbaar gebruik.

Hierdoor fungeert een openQA-fout als een blokkade voor de publicatie van de image. Begin met het openen van de downstream-pijplijn vanuit de trigger-openqa-job en open vervolgens de falende openQA-job via het bijbehorende CI-logboek. Op de jobpagina worden de testmodules op volgorde weergegeven; zo kunt u vaststellen of de fout optreedt tijdens de installatie, de sanity-tests van het geïnstalleerde systeem of het opwaardeerproces.

Download een staged image

De koppeling die na het logbericht “In case of failure, inspect and download the .iso image and sysupdate tree at…” wordt weergegeven, opent een opslagbrowser voor de build die wordt getest. Download daar de .iso om deze handmatig op te starten of aan een lokale openQA-stack te voeren. De sysupdate-boomstructuur bevat de voorbereide update-artefacten die door de opwaardeertest worden gebruikt.

Onderzoek een mislukte taak

Open de taak in de openQA-webinterface en selecteer eerst de mislukte module. De koppeling naar de webinterface verschijnt na het logbericht “ test job is now running.” De details omvatten het resultaat van de module, schermafbeeldingen of video (indien van toepassing) en diagnostische uitvoer. Download of bekijk op het tabblad Logs & Assets het bestand autoinst-log.txt voor de logs van de openQA-worker en de test-engine. Dit is het primaire logbestand voor de taak zelf.

Bij testen die commando's uitvoeren op het te testen systeem, voert KDE Linux deze uit in tijdelijke systemd-services en wordt het service-journal als diagnostische uitvoer in het testresultaat vastgelegd. Raadpleeg autoinst-log.txt voor de uitvoer van de commando's en het journal. U kunt ook het bestand *kde-linux-collected-logs.tar.zst downloaden met de logs die door de hulpmiddel collect-logs zijn verzameld.

Voer testen lokaal uit

U kunt openQA gebruiken om een ​​lokaal gebouwde image te testen voordat u een wijziging indient. Dit is vereist wanneer u werkt vanuit een fork buiten kde-linux/kde-linux: de CI-pijplijn daarvan bouwt weliswaar een test-image, maar start de openQA-pijplijn niet. Het is ook nuttig bij het ontwikkelen van tests voor uw eigen wijzigingen.

De KDE Linux openQA-testopslagruimte bevat een lokale stack met zowel een openQA-webinterface als een worker. Hiervoor zijn Python 3.14, Podman en podman-compose vereist, die in KDE Linux zijn opgenomen.

Kloon de testopslagruimte en plaats vervolgens de KDE Linux .iso-image, die u wilt testen in de hoofdmap ervan. Als er geen image aanwezig is, downloadt de testrunner in plaats daarvan de nieuwste publiek beschikbare image.

Start de lokale stack uit de hoofdmap van de opslagruimte.

./qa-mock up

Zodra het gereed is, opent u http://localhost:1080 om de openQA-webinterface te bekijken. Taken worden niet automatisch ingediend; open daarom een ​​shell in de container en start de installatieprocedure. Voer de volgende commando's uit: flow, job en build-sysext in deze container.

./qa-mock enter
./qa flow install

Voer de flow upgrade in plaats daarvan uit:

./qa flow upgrade

Geef voor een versleutelde installatie FDE_INSTALL=1 op als openQA-instelling.Het variant-achtervoegsel onderscheidt versleutelde taken in het webinterface:

./qa flow install --var FDE_INSTALL=1 --flavor-suffix=-encrypted
./qa flow upgrade --var FDE_INSTALL=1 --flavor-suffix=-encrypted

--var NAAM=WAARRDE kan worden herhaald, maar elke variabele moet worden gedeclareerd in de lijst variables van de geselecteerde flow in tests/tests.toml.

De suite sanity-test maakt gebruik van de virtuele schijf die door install-system is aangemaakt. Om u op specifieke tests te richten, kunt u de lijst tests van de suite in tests/tests.toml aanpassen of daar een andere suite en flow definiëren. U kunt ook een afzonderlijke suite uitvoeren met ./qa job --name <suite>, waarbij u rekening houdt met de bijbehorende schijfafhankelijkheden. De commando's flow, job en build-sysext ondersteunen de optie --manifest-path <path> om een ​​ander manifest te gebruiken dan tests/tests.toml. Testpaden in het manifest zijn relatief ten opzichte van de map waarin het manifest zich bevindt. Voer ./qa job --help uit voor informatie over de vereiste opties.

Bouw bijvoorbeeld de systeemextensie en voer een tak install-system uit met een .iso in de opslagruimtemap. Vervang de build-ID en variant door die van uw image:

./qa build-sysext
./qa job \
    --live ./kde-linux_<build-id>.iso \
    --hdd kde-linux_<build-id>.qcow2 \
    --sysext ./openqa-sysext.img \
    --build <build-id> \
    --variant <variant> \
    --name install-system \
    --flavor live

Wanneer u klaar bent, verlaat de shell van de container, stop de stack en verwijder de lokale volumes van de host.

./qa-mock down -v

./qa-mock geeft argumenten door aan podman-compose. Gebruik bijvoorbeeld ./qa-mock up -d om de stack op de achtergrond te starten.

Test opwaarderingen tussen lokale builds

Plaats de basis-ISO in de hoofdmap van de test-opslagruimte. Stel bij het starten van de stack vanaf de host KDE_LINUX_OUTPUT in op de map mkosi.output die de build bevat waarnaar u wilt opwaarderen:

KDE_LINUX_OUTPUT=~/Repositories/kde-linux/mkosi.output ./qa-mock up

Ga de container binnen en voer de opwaardeerprocedure uit, waarbij u <build-id> vervangt door de build-ID van uw basis-ISO:

./qa-mock enter
./qa flow upgrade \
    --upgrade-from /casedir/kde-linux_<build-id>.iso \
    --upgrade-to /kde-linux-output

Beide opties moeten samen worden opgegeven. De opslagruimte wordt aangekoppeld op /casedir en de geselecteerde map mkosi.output wordt alleen-lezen aangekoppeld op /kde-linux-output. De nieuwste build in die map wordt aan de virtuele machine aangeboden als tijdelijke sysupdate-bron en moet nieuwer zijn dan de basis-ISO. Voeg --var FDE_INSTALL=1 --flavor-suffix=-encrypted toe om een ​​versleutelde installatie te testen.

Declareer suites en flows

tests/tests.toml definieert de distributie (name en distri), suites en flows. Een suite is een geordende lijst van tests die in één openQA-taak worden uitgevoerd. De action ervan bepaalt hoe de taak de virtuele schijf gebruikt:

  • install start de live-image op en maakt de geïnstalleerde schijf aan.
  • upgrade start op vanaf de geïnstalleerde schijf en stelt DO_UPGRADE in voor tests die de opwaardering uitvoeren.
  • test start op vanaf de geïnstalleerde schijf ter validatie.

Een flow voert suites uit in de opgegeven volgorde en geeft de geïnstalleerde schijf door tussen de jobs. KDE Linux definieert deze flows:

[flows.install]
suites = ["install-system", "sanity-test"]
variables = ["FDE_INSTALL"]

[flows.upgrade]
suites = ["install-system", "upgrade-system", "sanity-test"]
variables = ["FDE_INSTALL"]

De flow install installeert en controleert de te testen build. De flow upgrade installeert eerst een oudere image, voert een opwaardering uit naar de te testen build en voert vervolgens sanity-tests uit. Bij een staged CI-build vormt de laatst gepubliceerde image de basis. Zonder de opties --upgrade-from en --upgrade-to gebruikt een lokale upgrade standaard de nieuwste publieke build als doel; hierbij wordt een oudere lokale ISO gebruikt (indien beschikbaar) of de vorige image gedownload.

Voor elke taak maakt de werker een tijdelijke testmap (CASEDIR) aan met een schema main.pm voor de geselecteerde testsuite. De tests worden uitgevoerd in de volgorde van het manifest, inclusief herhaalde vermeldingen. Pas het manifest aan om het schema te wijzigen.

Schrijf een test

De testdefinities en de code bevinden zich in os-autoinst-distri-kdelinux. Voeg testscripts toe in de map tests/, naast gerelateerde tests, en registreer ze in de array tests van de betreffende suite in tests/tests.toml. Bijvoorbeeld:

[suites.voorbeeld]
action = "test"
tests = [
    { path = "common/bootup.py", type = "openqa" },
    { path = "common/basic_test.py", type = "python" },
    { path = "kdelinux/app/firefox.py", type = "selenium", user = "installed", timeout = 180 },
]

Testen openqa worden uitgevoerd op de werker en maken rechtstreeks gebruik van openQA-API's. python- en selenium-tests worden uitgevoerd op het te testen systeem; de systeemextensie verpakt de scripts automatisch en de werker genereert de openQA-testwrappers die deze aanroepen.

Kies het type test op basis van wat u controleert:

  • Gebruik een standaard Python-unittest voor opdrachtregelhulpmiddelen, services, de status van het bestandssysteem of ander niet-grafisch gedrag.
  • Gebruik Selenium via selenium-webdriver-at-spi wanneer voor het gedrag interactie met een grafische toepassing vereist is.

Normale Python testen

Maak een unittest aan in de map tests/, bijvoorbeeld tests/kdelinux/system/example.py. Deze moet toekenningen bevatten over het te testen systeem en de resultaten wegschrijven naar een JUnit XML-bestand; dit bestand wordt automatisch verzameld als openQA-asset en GitLab CI-rapport.

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")

Voeg een vermelding toe aan de array tests van de betreffende suite:

{ path = "kdelinux/system/example.py", type = "python" },

De gegenereerde wrapper verzamelt het JUnit-resultaat en de uitvoer van het commando, zodat fouten zichtbaar zijn in de openQA-job en de CI-artefacten.

Grafische tests met Selenium

Grafische tests zijn ook Python-unittest-klassen, maar ze maken gebruik van de Appium/Selenium-driver om toegankelijke UI-elementen te vinden en ermee te interageren. De Selenium-runner activeert de toegankelijkheidsinfrastructuur en start het stuurprogramma voor u op.

Een grafische test maakt bijvoorbeeld een stuurprogramma aan voor de toepassing, communiceert met toegankelijke elementen en sluit het stuurprogramma vervolgens weer af:

import unittest
from appium import webdriver
from appium.options.common.base import AppiumOptions
from appium.webdriver.common.appiumby import AppiumBy
from lib.sut 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")

Sla het script op als bijvoorbeeld tests/kdelinux/app/example.py en voeg het toe aan de relevante testsuite met type = "selenium". Selecteer de geïnstalleerde testgebruiker voor bureaubladtoepassingen:

{ path = "kdelinux/app/example.py", type = "selenium", user = "installed", timeout = 180 },

Voer de flow die uw suite bevat lokaal uit terwijl u deze ontwikkelt.

Test opties en aangepaste wrappers

Voor gegenereerde SUT-wrappers kunnen manifest-items de volgende instellingen bevatten: user (root, live, installed of plasma_setup), timeout in seconden (standaard 90), artifacts (een lijst met te verzamelen paden) en de openQA-vlaggen fatal = true of always_run = true. Stel enabled = false in om een ​​test wel te declareren, maar uit de planning uit te sluiten.

Wanneer een test een vorm van aangepaste orkestratie vereist om te kunnen draaien, plaats dan een wrapper naast het SUT-script en verwijs ernaar met override:

{ path = "kdelinux/system/collect_logs.py", type = "selenium", override = "kdelinux/system/collect_logs.openqa.py" },

Deze aangepaste wrapper is verantwoordelijk voor de bijbehorende vlaggen, gebruiker, time-out en het verzamelen van artefacten, en moet het relatieve pad naar het SUT-script doorgeven aan CliTest.run_python() of CliTest.run_selenium(). Zie het bestaande bestand collect_logs.openqa.py voor een voorbeeld.

Voor meer informatie over het schrijven van Selenium-tests, zie Appium automation testing en GUI Testing with selenium-webdriver-at-spi.

Kom meer te weten

Voor een uitgebreidere uitleg over het testverloop en de implementatie ervan, zie openQA Testing in KDE Linux. De testinfrastructuur wordt ontwikkeld in de os-autoinst-distri-kdelinux-repository.


Artikel bijgedragen door onder de licentie CC-BY-4.0.