ABONAMENTE VIDEO REDACȚIA
RO
EN
Numărul 148 Numărul 147 Numărul 146 Numărul 145 Numărul 144 Numărul 143 Numărul 142 Numărul 141 Numărul 140 Numărul 139 Numărul 138 Numărul 137 Numărul 136 Numărul 135 Numărul 134 Numărul 133 Numărul 132 Numărul 131 Numărul 130 Numărul 129 Numărul 128 Numărul 127 Numărul 126 Numărul 125 Numărul 124 Numărul 123 Numărul 122 Numărul 121 Numărul 120 Numărul 119 Numărul 118 Numărul 117 Numărul 116 Numărul 115 Numărul 114 Numărul 113 Numărul 112 Numărul 111 Numărul 110 Numărul 109 Numărul 108 Numărul 107 Numărul 106 Numărul 105 Numărul 104 Numărul 103 Numărul 102 Numărul 101 Numărul 100 Numărul 99 Numărul 98 Numărul 97 Numărul 96 Numărul 95 Numărul 94 Numărul 93 Numărul 92 Numărul 91 Numărul 90 Numărul 89 Numărul 88 Numărul 87 Numărul 86 Numărul 85 Numărul 84 Numărul 83 Numărul 82 Numărul 81 Numărul 80 Numărul 79 Numărul 78 Numărul 77 Numărul 76 Numărul 75 Numărul 74 Numărul 73 Numărul 72 Numărul 71 Numărul 70 Numărul 69 Numărul 68 Numărul 67 Numărul 66 Numărul 65 Numărul 64 Numărul 63 Numărul 62 Numărul 61 Numărul 60 Numărul 59 Numărul 58 Numărul 57 Numărul 56 Numărul 55 Numărul 54 Numărul 53 Numărul 52 Numărul 51 Numărul 50 Numărul 49 Numărul 48 Numărul 47 Numărul 46 Numărul 45 Numărul 44 Numărul 43 Numărul 42 Numărul 41 Numărul 40 Numărul 39 Numărul 38 Numărul 37 Numărul 36 Numărul 35 Numărul 34 Numărul 33 Numărul 32 Numărul 31 Numărul 30 Numărul 29 Numărul 28 Numărul 27 Numărul 26 Numărul 25 Numărul 24 Numărul 23 Numărul 22 Numărul 21 Numărul 20 Numărul 19 Numărul 18 Numărul 17 Numărul 16 Numărul 15 Numărul 14 Numărul 13 Numărul 12 Numărul 11 Numărul 10 Numărul 9 Numărul 8 Numărul 7 Numărul 6 Numărul 5 Numărul 4 Numărul 3 Numărul 2 Numărul 1
×
▼ LISTĂ EDIȚII ▼
Numărul 64
Abonament PDF

Eleganța unei arhitecturi avansate de testare automată, bazată pe componente open source

Adrian Vaidos
IT Operations Manager–Applications @ Siemens



PROGRAMARE


Atunci când un proiect software trebuie să fie supus în premieră unui testări automate, probabil că primul lucru la care ne gândim este folosirea unui software comercial destinat tipului de software care urmează a fi testat. De foarte puține ori avem în vedere sau avem curajul să abordam, o soluție de testare automată bazată exclusiv pe componente gratuite și open source, deși în final putem obține rezultate mult mai elegante și mai eficiente comparativ cu soluția comercială.

 În funcție de experiența profesională a celor implicați și ținând cont de tipul proiectului software care urmează a fi testat (aplicație desktop, web, mobile, etc.), sau de tipul de testare automată (UI, API, Performance, DB, etc.), putem avea în vedere soluțiile HP UFT, LeanFT, Microsoft Coded UI, clasicul Selenium cu Visual Studio sau Java. Desigur că există o mulțime de alte soluții comerciale mai mult sau mai puțin cunoscute care pot fi avute în vedere, cum ar fi TestComplete, Tricentis, Ranorex, eggPlant, etc. . Criteriile principale pentru alegerea unei soluții ar fi în ordinea importanței: gratuitatea, costul licențelor, al resurselor necesare și al eventualelor traininguri, deținerea unei soluții (ducând la așa numitul sunk-cost bias sau capcana costurilor îngropate), experiența profesională în general și în particular cu soluția respectivă a celor implicați în decizie, recomandări, demo-uri și cercetare personală. Alte criterii de alegere pot fi cele ce țin de politica companiei, de colaborare, de existența suportului comercial, dar și de soluțiile impuse de către client. Deși de cele mai multe ori, marketingul și evaluările externe de tip marketing pot avea o influență hotărâtoare. 

Dacă nu avem nici un fel de experiență cu soluția de testare automată respectivă, putem începe cu facilitatea "record and playback" pentru a înregistra câteva teste și a le rula, demonstrând astfel viabilitatea soluției respective. Cu toate că de cele mai multe ori această facilitate eșuează în proiectele reale, fiind mai degrabă o facilitate existentă în scop de marketing, de multe ori aceasta este utilă pentru un start rapid în faza inițială de evaluare a diferitelor soluții de testare automată.

Pentru a iniția cu succes un proiect de testare automată, sunt recomandate următoarele condiții prealabile:

 Deși sunt destul de cunoscute, merită să reamintim aici avantajele testării automate, care pot fi aduse ca argumente atunci când încercăm să influențăm decizia de a iniția un proiect de testare automată, și anume:

Mergând mai departe, soluția de testare automată poate fi uneori una simplă, prin simpla utilizare a uneltei de testare alese, conform recomandărilor furnizorului soluției, respectiv fără implementarea unui Framework. Dacă soluția de testare automată este mai complexă, și aceasta presupune crearea unei arhitecturi software, împreună cu unul sau mai multe Frameworkuri, pornind de la una sau mai multe soluții comerciale sau open source cunoscute, procesul în linii mari ar fi același ca în cazul dezvoltării oricărui proiect software, respectiv cerințe, arhitectură, design, implementare, integrare, testare, instalare, întreținere. Desigur că este important să se țină cont și de metodologia de dezvoltare a proiectului software supus testării. Din păcate, în proiectele reale, de multe ori se începe direct cu implementarea Frameworkului pentru testarea automată a unui software departe de a fi finalizat și astfel instabil, ignorând lipsa condițiilor prealabile exemplificate mai sus precum și trecerea peste etapele premergătoare de definire a cerințelor, arhitectură și design, insuccesul fiind astfel garantat.   Ținând cont de aceste principii de mai sus, în continuare vom exemplifica o arhitectură avansată de testare automată, elegantă și modernă, bazată exclusiv pe componente open source sau gratuite pentru uzul comercial. După cum se poate vedea mai jos, această arhitectură integrează toate aceste componente, bazate pe multiple și diverse tehnologii, într-o soluție inovatoare, unică și completă, care poate satisface cerințele oricărui proiect de testare automată, în cazul de față al unui software web complex.

 Următoarele componente fac parte din această arhitectură:

Deși există biblioteci open source disponibile în Robot Framework pentru fiecare dintre componentele SikuliX, Selenium și AutoIT, doar biblioteca Selenium este destul de avansată și folosită pe larg, astfel încât ne putem baza pe ea. Scriptul AutoIT este apelat ca proces separat din Robot Framework, deși poate fi implementată și o bibliotecă Robot Framework dacă se consideră necesar. Pentru SikuliX este recomandată implementarea unei biblioteci noi, mai degrabă decât rularea ca proces separat ale unor scripturi exclusive SikuliX. Implementarea acestor biblioteci în Robot Framework permite executarea combinată, în funcție de nevoi, a oricărei acțiuni prin intermediul celor 3 componente. De exemplu, verificarea și clickul pe un element identificat cu Selenium, apoi verificarea și clickul pe un element identificat cu SikuliX și eventual extragerea informațiilor din baza de date, de exemplu pentru login, cu ajutorul AutoIT.

Avantajele acestei soluții ar fi:

Dezavantajele acestei soluții ar fi:

Deși utilizarea diferitelor componente open source sau gratuite pentru uzul comercial este exemplificată în detaliu în diferite articole, bloguri sau pe site-urile oficiale de distribuție ale componentelor, integrarea completă și funcțională ale tuturor componentelor în arhitectura prezentată mai sus poate fi considerată dificilă. Deși nu este o descriere completă, pentru a înțelege în mare cum a fost construită și integrată aceasta arhitectură, pașii ar fi următorii:

  1. Se instalează Python27, robotframework, robotframework-selenium2library, PyCharm, plugin-ul Robot Framework Support pentru PyCharm, SixuliX, jython2.7.0, autoit-v3, KeePass-2.35, și driverele Selenium (chromedriver, geckodriver, IEDriverServer).

  2. Dacă se dorește o configurație "portabilă", toate aceste componente se instalează în același path de bază sau pe un Virtual Hard Disk, asigurând configurările necesare astfel încât toate componentele să ruleze în modul "portabil", folosind pathuri relative, respectiv orice legătură cu sistemul de operare cu privire la path-uri sau variabile de sistem trebuind înlăturată.

  3. Implementarea unei biblioteci noi folosind facilitatea Remote Library din Robot Framework, cu Jython, ceea ce presupune în principiu crearea unei clase în Python, de exemplu
class SikuliRemoteLib(BaseLogger):
    def __init__(self):
        self.appRegion=Region()
    ..
    def click_object(self,img,offsetX=0,offsetY=0):
        self._find_object(img,offsetX,offsetY)
        self.appRegion.click(self.appPattern)
    ... 

care va conține toate keywordurile necesare a fi apelate din Robot Framework, sub forma unor funcții care să apeleze funcțiile din SikuliX prin intermediul jython, și apoi instanțierea acestei clase în main:

if __name__ == '__main__':
    import sys
    from robotremoteserver import RobotRemoteServer

    RobotRemoteServer(SikuliRemoteLib(), 
    *sys.argv[1:])

Moștenirea din BaseLogger permite în plus personalizarea logurilor, pentru ca acestea să conțină atât imaginea de referință cât și imaginea reală cu care se compară, pentru mai multă siguranță la verificarea rezultatelor execuției testelor, cât și pentru corectarea ulterioară a unor imagini de referință.

4.Serverele SikuliX și Selenium se pot porni în mod automat din Robot Framework, folosind fișierul special init.robot, care poate conține următoarele linii de cod:

Resource        ${CURDIR}/Common/sikuliremote.robot
Suite Setup     Start And Import Remote Library  SikuliRemoteLib/sikuliremotelib.py
Suite Teardown  Stop Remote Library  ${True}

Iar Start And Import Remote Library conține codul prin care se pornește SikuliX prin procesul java jython.jar, precum și Selenium, de exemplu pentru chromedriver.

Mai multe detalii pentru această procedură se pot explora în documentația Robot Framework precum și direct în codul sursă de pe Git.

Având toată această arhitectură integrată, nu ne rămâne decât să creăm proiectul final, structurat pe module în funcție de specificul aplicației, să decidem locația imaginilor de referință și să realizăm primul fișier de tipul robot cu primele teste.

Presupunând că dorim să implementam un test de regresie pentru profilul de utilizator Facebook, instrucțiunile de testare, folosind Visual Studio cu Selenium, ar fi următoarele:

[Test]
public void FbTest()
{
    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));

    driver.Navigate().GoToUrl(
      "https://www.facebook.com");
    // 1. Assume new browser profile, 
    // thus logon required all the time

    wait.Until(ExpectedConditions.
       ElementIsVisible(By.Id("email")));
    // hardcoded here for demo only, otherwise would 
    // call a keyword that will use KeePass instead

    driver.FindElement(By.Id("email")) 
      .SendKeys("username");

    driver.FindElement(By.Id("pass"))
      .SendKeys("password");
    driver.FindElement(By.Id("loginbutton")).Click();

    // 2. Close notification dialog if appearing
    IWebElement element = IsElementPresent(
       By.XPath(
    "//*[@aria-labelledby='notification-permission-title']//a"));
    if (element != null)
        element.Click();

    // 3. Check if FB logo and search field are displayed correctly
    driver.FindElement(By.XPath(
       "//*[@data-testid='blue_bar_fb_logo']"));
    driver.FindElement(By.XPath(
       "//*[@data-testid='search_input']"));

    // 4. Click on user name to display user profile
    driver.FindElement(By.XPath(
       "//*[@id='u_0_4']/div[1]/div[1]/div/a/span"))
        .Click();
    // Check the Profile Picture element exists
    driver.FindElement(By.XPath(
       "//*[@class='profilePicThumb']"));

    // 5. Check the tabs Timeline, 
    // Friends and Photos exist
    driver.FindElement(By.XPath(
       "//*[@data-tab-key='timeline']"));
    driver.FindElement(By.XPath(
       "//*[@data-tab-key='friends']"));
    driver.FindElement(By.XPath(
       "//*[@data-tab-key='photos']"));

    // 6. Check the tab More exists, 
    // click it in order to activate popup items
    driver.FindElement(By.XPath(
       "//*[@id='fbProfileCover']/div[2]/div[2]/ul/
        li[5]/div/a")).Click();

    // Check if the popup items exist
    driver.FindElement(By.XPath(
       "//*[@data-tab-key='map']"));
    driver.FindElement(By.XPath(
       "//*[@data-tab-key='sports']"));
    driver.FindElement(By.XPath(
       "//*[@data-tab-key='books']"));
    driver.FindElement(By.XPath(
       "//*[@data-tab-key='likes']"));
    driver.FindElement(By.XPath(
       "//*[@data-tab-key='events']"));
    driver.FindElement(By.XPath(
       "//*[@data-tab-key='fitness']"));
    driver.FindElement(By.XPath(
       "//*[@data-tab-key='reviews']"));
    driver.FindElement(By.XPath(
       "//*[@data-tab-key='groups']"));
    driver.FindElement(By.XPath(
       "//*[@data-tab-key='notes']"));

    // 7. Check and click on About tab
    driver.FindElement(By.XPath(
       "//*[@data-tab-key='about']")).Click();
    // Check if the About menu is displayed correctly
    driver.FindElement(By.XPath(
       "//*[@id='medley_header_about']/a"));

    // Several checks still missing, e.g. is the 
    // About tab selected and with black color while 
    // the other tabs are blue?
    // Or, are the menu items displayed correctly in 
    // English language?
    // ...

Instrucțiunile în limbaj Robot Framework, ar fi următoarele:

Basic FB check
  [Documentation]   Test Fb login, profile picture, main tabs and click on About tab
  [Tags]  Warmup  Fb
  go to   https://www.facebook.com

  # 1. Assume new browser profile, thus logon required 
  # all the time
  wait until element is visible   id=email

  # hardcoded here for demo only, otherwise would 
  # call a keyword that will use KeePass instead
  press key           id=email  username
  press key           id=pass   password
  click button        //*[@id='loginbutton']/input

  # 2. Close notification dialog if appearing
  Run Keyword And Ignore Error click element    
  //*[@aria-labelledby=
  // 'notification-permission-title']//a

  # "T01-1 fb logo and search" and upcoming are .PNG 
  # files, taken as reference images on a very specific 
  # region
  # The next used keywords are Python functions 
  # implemented in SikuliRemoteLib, that in turn are 
  # calling SikuliX methods for finding and executing   
  # actions on images, then logging the results.
  # The numbers are x, y click coordinates, exactly 
  # as seen e.g. on Paint application.

  # 3. Check if FB logo and search field are displayed 
  # correctly
  wait for object     T01-1 fb logo and search

  # 4. Click on user name to display user profile
  verify and click object  T01-2 main controls   
    ${-20}  ${18}

  # Check the Profile Picture element exists
  wait until element is visible   //*[@class='profilePicThumb']

  # 6. Check the tab More exists, hover mouse over it 
  # in order to activate popup items
  hover over object        T01-3 timeline tab   
    ${382}  ${18}

  # Check if the popup items exist
  verify object            T01-4 more popup menu
  hover mouse right        ${100}

  # 5. Check the tabs Timeline, Friends and Photos 
  # elements exist
  # 7. Check and click on About tab
  verify and click object  T01-3 timeline tab   
    ${116}  ${18}

  # check the About tab is displayed correctly
  verify object            T01-5 about tab
  # Check if the About menu is displayed correctly
  verify object            T01-6 about menu displayed

  # No more checks are missing for this basic test. 
  # About tab is selected correctly and with the 
  # correct colors displayed
  # All menu items are displayed correctly in 
  # English language, as in the reference image

După cum se poate vedea mai sus, instrucțiunile în Robot Framework sunt mult mai elegante și mai naturale, implementarea unui caz de testare fiind mult mai accesibilă chiar și pentru un inginer de testare fără experiență în programare pentru că logica acestor teste urmărește destul de aproape pașii din testul manual, spre deosebire de implementarea în C# și Selenium, unde cunoștințele de programare sunt obligatorii. Mai mult decât atât, timpul de scriere al unui caz de testare automat, relativ complex, este mult mai mic atunci când se folosește testarea automată bazată pe recunoașterea imaginilor, de exemplu, cu SikuliX, decât atunci când se folosește recunoașterea elementelor ascunse în pagina web ca în cazul Selenium. Concret, dacă un caz de testare în Selenium cu Visual Studio ar necesita 10 "man days", același caz de testare cu arhitectura prezentată mai sus poate fi finalizat cel mult în 1 "man day", deci de 10 ori mai repede sau cu 10% din resurse.

În concluzie, indiferent dacă criteriile de alegere a unei soluții de testare automată pun costul soluției pe un loc principal sau secundar, atunci când suntem dispuși să renunțam la varianta evidentă, populară, comercială și care beneficiază de marketing din plin și decidem să acordăm o șansă soluțiilor alternative, putem avea surpriza să obținem o soluție de testare automată nu doar gratuită, ci una cu mult mai puternică, mai elegantă și mai flexibilă pentru proiectul software care urmează a fi testat automat, atât în beneficiul membrilor echipei care vor lucra în acel proiect, cât mai ales în beneficiul clientului final al cărui produs software urmează a fi testat.

LANSAREA NUMĂRULUI 149

Marți, 26 Octombrie, ora 18:00

sediul Cognizant

Facebook Meetup StreamEvent YouTube

NUMĂRUL 147 - Automotive

Sponsori

  • Accenture
  • BT Code Crafters
  • Accesa
  • Bosch
  • Betfair
  • MHP
  • BoatyardX
  • .msg systems
  • P3 group
  • Ing Hubs
  • Cognizant Softvision
  • Colors in projects