Preskočiť na obsah

openQA pre vývojárov a správcov

KDE Linux používa openQA na automatické otestovanie každého systémového obrazu pred jeho zverejnením. openQA zavedie každý obraz vo virtuálnom stroji a overí, že sa dá úspešne nainštalovať, aktualizovať a používať.

openQA má vlastnú terminológiu: úloha je jedno spustenie testovacej sady nad obrazom, kým pracovník je stroj alebo kontajner, ktorý úlohu vykonáva. Dokumentácia openQA vysvetľuje tieto aj ďalšie pojmy vrátane testovacích modulov, skupín úloh, prostriedkov a webového rozhrania.

Ako testy fungujú

Testovací pracovník beží popri reťazci CI, takže môže použiť obrazy a virtuálne disky vytvorené pri zostavení bez toho, aby sa tie veľké súbory museli niekam nahrávať. Testy sa do virtuálneho stroja dostávajú cez systémové rozšírenie a komunikujú s ním cez SSH.

Testy pracovného prostredia využívajú prístupnostné API cez selenium-webdriver-at-spi, vďaka čomu dokážu s aplikáciami pracovať a overovať ich stav bez toho, aby sa spoliehali výhradne na porovnávanie snímok obrazovky. Sada tiež kontroluje zlyhané systémové služby, spadnuté procesy prostredia, problémy so sieťou a regresie v príkazoch KDE Linux.

Reťazec CI a postup správcu

V chránenej predvolenej vetve repozitára KDE Linux funguje reťazec takto:

  1. Úloha imaging zostaví, podpíše a pripraví obraz aj jeho kanál sysupdate na storage.kde.org.
  2. Úloha trigger-openqa spustí reťazec v os-autoinst-distri-kdelinux a odovzdá mu URL pripraveného obrazu a URL kanála sysupdate.
  3. Nadväzujúci reťazec spustí bežný postup inštalácie a základných kontrol aj postup aktualizácie.
  4. Úloha publish v pôvodnom reťazci beží až po úspešnom dokončení reťazca openQA. Už pripravený obraz povýši na verejne dostupný.

Zlyhanie openQA je tak podmienkou, ktorá zverejnenie obrazu zastaví. Začnite tým, že z úlohy trigger-openqa otvoríte nadväzujúci reťazec a z jeho záznamu CI potom zlyhanú úlohu openQA. Stránka úlohy zobrazuje testovacie moduly v poradí a umožňuje zistiť, či zlyhanie nastalo pri inštalácii, pri základných kontrolách nainštalovaného systému alebo pri aktualizácii.

Stiahnutie pripraveného obrazu

Odkaz uvedený za hlásením „In case of failure, you can inspect and download the .iso image and sysupdate tree at…“ otvorí prehliadač úložiska pre testované zostavenie. Stiahnite si odtiaľ .iso, aby ste ho zaviedli ručne alebo odovzdali lokálnej inštancii openQA. Strom sysupdate obsahuje pripravené aktualizačné artefakty, ktoré používa test aktualizácie.

Skúmanie zlyhanej úlohy

Otvorte úlohu vo webovom rozhraní openQA a vyberte najprv zlyhaný modul. Odkaz na webové rozhranie sa objaví za hlásením test job is now running.“ Jeho podrobnosti obsahujú výsledok modulu, prípadné snímky obrazovky či video a diagnostický výstup. Na karte Logs & Assets si stiahnite alebo zobrazte autoinst-log.txt so záznamom pracovníka openQA a testovacieho jadra. Je to hlavný záznam samotnej úlohy.

Testy, ktoré spúšťajú príkazy na testovanom systéme, KDE Linux vykonáva v dočasných službách systemd a žurnál služby zaznamenáva ako diagnostický výstup vo výsledku testu. Výstup príkazu a žurnál nájdete v autoinst-log.txt. Stiahnuť si môžete aj súbor *kde-linux-collected-logs.tar.zst so záznamami, ktoré zozbieral nástroj collect-logs.

Spustenie testov lokálne

openQA môžete použiť na otestovanie lokálne zostaveného obrazu ešte pred odoslaním zmeny. Pri práci z forku mimo kde-linux/kde-linux je to nutné – jeho reťazec CI síce testovací obraz zostaví, ale reťazec openQA nespustí. Hodí sa to aj pri vývoji testov k vlastným zmenám.

Repozitár testov openQA pre KDE Linux obsahuje lokálnu zostavu s webovým rozhraním openQA aj pracovníkom. Vyžaduje Podman a podman-compose, ktoré sú v KDE Linux súčasťou systému.

Naklonujte repozitár testov a do jeho koreňového adresára umiestnite obraz .iso KDE Linux, ktorý chcete otestovať. Ak tam žiadny obraz nie je, spúšťač testov stiahne najnovší verejne dostupný.

Spustite lokálnu zostavu.

./mock.sh up

Keď je pripravená, otvorte http://localhost:1080 a pozrite si webové rozhranie openQA. Úlohy sa neodosielajú automaticky, preto otvorte shell v kontajneri a odošlite bežný postup inštalácie a základných kontrol.

podman exec -it openqa-single-instance bash
./qa flow

Ak chcete namiesto toho spustiť postup aktualizácie, pridajte --upgrade:

./qa flow --upgrade

Na spustenie postupu inštalácie so šifrovaním disku pridajte --encrypt:

./qa flow --encrypt

Voľby --upgrade a --encrypt sa dajú aj kombinovať:

./qa flow --upgrade --encrypt

Úloha sanity-test potrebuje, aby najprv prebehla úloha install-system, pretože používa virtuálny disk vytvorený pri inštalácii. Ak sa chcete sústrediť na konkrétny test, upravte odosielané úlohy v lib/worker/job_flow.py alebo spustite jednotlivú úlohu cez ./qa job s ohľadom na túto závislosť. Voľby, ktoré vyžaduje, zobrazíte príkazom ./qa job --help.

Napríklad na spustenie úlohy install-system, keď máte .iso stiahnuté v adresári repozitára:

./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

Keď skončíte, zostavu zastavte a odstráňte jej lokálne zväzky.

./mock.sh down -v

Napísanie testu

Definície testov aj samotný kód sú v os-autoinst-distri-kdelinux. Test pridajte do príslušného postupu v main.pm – postupu inštalácie zo živého obrazu, základných kontrol nainštalovaného systému alebo aktualizácie. Testy sa spravidla skladajú z malého obalu pre openQA v tests/ a testu v Pythone, ktorý beží na testovanom systéme z extensions/openqa/usr/lib/kde-linux-openqa/tests/.

Typ testu si zvoľte podľa toho, čo overujete:

  • Pri nástrojoch príkazového riadka, službách, stave súborového systému alebo inom negrafickom správaní použite bežný unittest v Pythone.
  • Keď si správanie vyžaduje prácu s grafickou aplikáciou, použite Selenium cez selenium-webdriver-at-spi.

Bežné testy v Pythone

Vytvorte unittest v spomínanom adresári testov systémového rozšírenia. Mal by robiť tvrdenia o testovanom systéme a zapisovať výsledky do súboru JUnit XML, ktorý sa automaticky zozbiera ako prostriedok openQA a ako správa pre 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")

Vytvorte k nemu zodpovedajúci obal v tests/, ktorý zabezpečí, že openQA test spustí na hostiteľovi.

from testapi import *
from lib.test import cli_test

def run(self):
    cli_test.CliTest("example").run_python()

Nakoniec obal zaregistrujte v príslušnom postupe v main.pm. Obal zozbiera výsledok JUnit a výstup príkazu, takže sa zlyhania objavia vo výsledkoch.

Grafické testy so Seleniom

Aj grafické testy sú triedy unittest v Pythone, na hľadanie prístupných prvkov rozhrania a prácu s nimi však používajú ovládač Appium/Selenium. Spúšťač Selenia zapne prístupnostnú infraštruktúru a ovládač naštartuje za vás.

Grafický test napríklad vytvorí ovládač pre svoju aplikáciu, pracuje s prístupnými prvkami a potom ovládač zavrie:

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

Zodpovedajúci obal spustite s run_selenium() namiesto run_python(). Pri aplikáciách pracovného prostredia odovzdajte nainštalovaného testovacieho používateľa:

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

Podobne ako pri bežných testoch v Pythone pridajte jeho obal do main.pm, počas vývoja ho spúšťajte lokálne a zaraďte ho do testovacieho postupu, ktorý danú funkciu preveruje.

Viac o písaní testov v Seleniu nájdete v Automatizovanom testovaní s Appium a Testovaní rozhrania pomocou selenium-webdriver-at-spi.

Zistiť viac

Podrobnejší výklad testovacieho postupu a jeho implementácie nájdete v článku openQA Testing in KDE Linux. Testovacia infraštruktúra sa vyvíja v repozitári os-autoinst-distri-kdelinux.


Článok napísal pod licenciou CC-BY-4.0.