ABONAMENTE VIDEO REDACȚIA
RO
EN
NOU
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 22
Abonament PDF

Cum câştigi jocul automatizării?

Mihai Cristian
Test Automation Engineer
@Hewlett Packard



TESTARE


În ziua de azi una dintre primele întrebări care îţi sunt adresate ca inginer în testare este dacă foloseşti testarea automată. Cu siguranţă, în ultimii ani, testarea automată a fost şi rămâne un subiect la modă. Toată lumea vorbeşte despre ea, încearcă sa o folosească sau se plânge de ea. Cu toate acestea, ea rămâne eminamente un subiect intern, fiecare companie dezvoltând soluţii proprietare, croite pentru produsele și nevoile proprii. Acesta este un lucru firesc având în vedere ca produsele diferă mult, în special când vorbim de enterprise software, aşa că e greu de crezut că vom putea folosi o singură soluţie de automatizare indiferent de produsul dezvoltat. Acestea fiind spuse, după câţiva ani petrecuţi în domeniul testării automate, observând atât părţile rele cât şi cele bune, ajungi la un momentdat să te întrebi: Cum câştigi jocul automatizării?

Articolul acesta încearcă să prezinte aspectele cheie ale dezvoltării şî implementării cu success a unei soluţii de automatizare . Vom prezenta un ghid pas-cu-pas bazat pe soluţia utilizată în momentul de faţă de produsul HP Server Automation numită AXIS. Deşi articolul se concentrează în mare parte pe testarea automată a planului funcţional (backend), ideile prezentate pot fi aplicate pentru orice soluţie de testare automată indiferent de tehnologia utiltizată în dezvoltarea ei.

Soluţia de automatizare

Să începem. Ca şi în orice alt joc în care vrem să fim cei mai buni este important să cunoaştem în primul rând cum se joacă jocul. Consideraţi partea aceasta ca fiind manualul de instrucţiuni pentru jocul nostru. Atunci ce este o soluţie de automatizare?

În viziunea noastră o soluţie de automatizare este alcătuite din trei elemente de bază:

  • Framework-ul,
  • Conţinutul,
  • Interfaţa cu utilizatorul.

Framework-ul

Un framework de testare automată este de obicei definit ca fiind un set de presupuneri, concepte și practici utilizate pentru a oferi un suport pentru testarea automată a unui produs software[4]. Framework-ul este baza unei soluţii de automatizare. Acesta se ocupă de alocarea resurselor, execuţia testelor, validarea opţiunilor selectate și gestionarea mediului de testare utilizat. Este foarte important să utilizăm un framework care se potriveşte atât cu tipul automatizării propuse cât şi cu produsul testat.

Produsul nostru facilitează gestionarea de data center-e mari alcătuite din servere ce au diferite sisteme de operare, oferind toate uneltele necesare unui administrator de sistem, cum ar fi provizionarea sistemelor de operare, gestiunea pachetelor și a fişierelor de configurare precum și impunerea unor standarde de conformitate (compliance).

Pentru a executa teste automate pe un asemenea produs avem nevoie de un framework ce poate gestiona un mediu de testare cu multi-platformă. Soluţia AXIS se bazează pe un framework de automatizare existent numit STAF (Software Testing Automation Framework). STAF este un framework open source dezvoltat în jurul ideii de componente reutilizabile numite servicii (cum ar fi invocarea proceselor, gestiunea resurselor, logging şi monitorizare)[5]. Folosind STAF putem să implementăm premisele necesare testelor și să verificăm validitatea operaţiilor efectuate pe toate platformele importante utilizate în ziua de azi. Acest exemplu face dovada faptului că nu trebuie mereu să începem de la zero atunci când implementăm o soluţie de testare automată. Există numeroase produse de automatizare pe piaţă pentru toate gusturile şi, chiar în cazul în care implementam soluţii proprii, acestea pot fi de ajutor.

Un alt aspect cheie care trebuie luat în considerare când dezvoltăm un framework este procesul de "descoperire". Pe scurt acest proces va traduce informaţia despre mediul de testare din limbajul produsului testat in limbajul framework-ului de automatizare. Folosind acest proces putem defini un mediu de testare, specificând ţintele testelor şi orice altă informaţie considerată necesară, într-un format convenabil aplicaţiei proprii înainte de a rula efectiv testele.

Conţinutul

Conţinutul este reprezentat de testele automate în sine. Este bine să avem o separare clară între framework şi conţinut astfel încât soluţia de automatizare să poată fi folosită pentru mai multe produse. Testele în sine pot fi dezvoltate în orice limbaj de programare ales, atât timp cât acesta este suportat de framework și de produs.

Crearea conţinutului necesită o bună înţelegere a produsului ce va fi testat, astfel că echipele de testare ar trebui să joace un rol important în dezvoltarea testelor automate.

Interfaţa cu utilizatorul

Framework-ul şi testele automate sunt inutile dacă nimeni nu le poate folosi. Una din cele mai întâltnite probleme în soluţiile proprietare de testare automată este că doar specialiştii în automatizare ştiu cum să ruleze testele şi cum să interpreteze rezultatele. La fel ca în cazul oricărui alt produs testat exclusiv de persoanele ce l-au dezvoltat şi îi cunosc din start punctele forte și cele slabe, această abordare va duce inevitabil la probleme de calitate.

Uşurinţa de a utiliza un produs este unul din aspectele cheie ale unei soluţii automatizare. Cu cât mai mulţi oameni utilizează soluţia cu atât mai bună va fi aceasta. De aceea este foarte important să avem o interfaţă ce permite utilizatorilor să ruleze teste şi să interpreteze rezultatele acestora cu uşurinţă.

AXIS foloseşte o interfaţă grafică, bazată pe un server web, ce permite utilizatorilor să selecteze testele dorite şi mediul de testare pe care să le ruleze, precum şi să vizualizeze rezultate testelor într-un format de tabel, în care pot observa rezultatul testului şi pot accesa log-urile la nivel de suită sau test pentru a indentifica posibile erori. Aceasta interfaţă este dublată de o interfaţă line de comandă cu aceeaşi funcţionalitate.

Jocul testării automate

Acum că ştim ce este jocul automatizării putem să începem să îl jucăm. Acest ghid vă va da toate informaţiile necesare pentru a construi propria soluţie de automatizare. Este foarte important să nu săriţi peste nivele pentru că, cel mai probabil, veţi fi nevoiţi să vă întoarceţi la ele pentru a le parcurge la un moment dat. Să înceapă jocul!!!

Nivelul 1: Caracterul vostru

Să începem cu începutul. În primul rând trebuie să alegeţi ce fel de jucător veţi fi. Doriţi să mergeţi spre automatizarea interfeţei grafice sau veţi alege automatizarea backend? Poate amândouă. Orice alegere faceţi este important să definiţi abordarea de la bun început.

Cel mai important aspect la acest nivel este cunoaşterea produsului. Unele produse nu sunt compatibile cu automatizarea backend, pe când altele s-ar putea să nu aibă o interfaţă grafică (GUI) pe care să o automatizaţi. Automatizarea GUI se bazează deseori pe produse de înregistrare și redare în timp ce automatizarea backend se bazează pe faptul că produsul testat are un API expus ce permite apelarea metodelor sale din testele automate. Trebuie să vă asiguraţi că abordarea aleasă se pliază pe produsul testat. Puteţi să lucraţi împreuna cu echipa de development pentru a face produsul compatibil cu tipul de automatizare ales, însă acest lucru trebuie făcut cât mai devreme în ciclul de dezvoltare al produsului.

Un alt aspect de luat in considerare la nivelul 1 este care parte a procesul de testare doriţi să o automatizaţi. Doriţi să automatizaţi execuţia testelor sau validarea rezultatelor? Unele soluţii de automatizare se concentrează exclusiv pe partea de execuţie, lăsând validarea rezultatelor în sarcina testerilor, în timp ce altele acoperă ambele procese.

Revenind la exemplul nostru putem vedea că AXIS este o soluţie bună pentru nivelul 1. AXIS realizează doar automatizare backend. Testele sunt scrise în Python și implementează diferite scenarii apelând metodele produsului expuse prin API, replicând astfel comportamentul unui utilizator prin diferite script-uri. Validarea rezultatelor este de asemenea automatizată, testele verificând valorile returnate de diferite metode prin compararea cu un set de valori predefinite şi prezentând rezultatul utilizatorului într-un format simplu: Passed/Failed/Skipped. Apoi utilizatorii pot să navigheze prin log-urile testelor pentru a investiga eventualele probleme.

Odată ce aţi ales abordarea pentru soluţia voastră de automatizare şi aţi verificat faptul că aceasta funcţionează pentru produsul testat puteţi să treceţi la umătorul nivel.

Nivelul 2: Povestea din spatele jocului

Să intrăm în lumea jocului! Orice joc care merită jucat are şi o poveste în spate. Dacă vrem să înţelegem contextul în care au loc aventurile eroului nostru, merită să cunoaştem povestea înainte de a începe să atacăm tot ce mişcă.

Cum realizăm acest lucru? Simplu, trebuie doar să revizuim procesul de testare existent. Treceţi în revistă testele manuale existente pentru a vă asigura că acestea sunt scrise într-o manieră ce permite automatizarea lor. Colaboraţi cu echipa de testare pentru a alcătui o listă cu testele ce trebuie automatizate. Cele mai la îndemână exemple sunt suitele de regresie, suitele de teste smoke sau testele instalare a produsului. Identificaţi testele cheie care, în cazul în care nu trec, vor produce defecte cu prioritate mare. De asemenea, definiţi din start noţiunea de Pass și Fail pentru teste cu scopul de a evita orice confuzii ulterioare.

O altă operațiune ce trebuie aplicată la acest nivel este stabilirea unei legături clare între testele manuale şi cele automate. Această legătură vă va ajuta să determinaţi gradul de acoperire al testelor. Poate că acest nivel nu pare foarte distractiv dar, dacă faceţi acest efort acum, înainte de a începe efectiv să automatizaţi, veţi vedea că rezultatele muncii voastre vor fi vizibile mult mai devreme. AXIS foloseşte anumite fișiere text ataşate fiecărui test ce conţin informaţia ce leagă testul automat de cel manual, sub forma unui număr de identificare. Acestea sunt folosite în procesul de raportare a rezultatelor testelor automate către sistemul de monitorizare utilizat de management. Consideraţi această parte ca o tabelă de scor a jocului. Cu siguranţă veţi dori ca lumea să ştie la ce nivel se află eroul vostru şi ce misiuni a îndeplint.

Odată ce aveţi lista de teste ce trebuie automatizate, condiţiile de Pass/Fail şi testele scrise într-un format agreat de echipa de automatizare puteţi să avansaţi la următorul nivel.

Nivelul 3: Alegerea clasei eroului

În momentul de faţă ştim deja cum se joacă jocul şi care este povestea din spatele lui. E momentul să alegeţi clasa caracterului vostru. Alegerea clasei potrivite pentru abordarea decisă va face eroul vostru mult mai eficient. Vreţi să alegeţi calea luptătorului, a magului sau cea a arcaşului? Fiecare alternativă are punctele ei forte dar şi slăbiciunile ei şi va influenţa fundamental modul în care veţi juca jocul.

În acest nivel trebuie să definiţi ce doriţi să facă soluţia de automatizare propusă şi cum vreţi să realizaţi acest lucru. Va trebui să definiţi cerinţe care vor reprezenta scopurile soluţiei. În acest fel veţi avea un standard clar pentru contorizarea progresului şi veţi şti momentul în care soluţia propusă este gata de a fi folosită.

Să presupunem că vreţi să automatizaţi testele de regresie pentru un produs. Datorită faptului că aţi parcurs deja nivelele 1 şi 2, ar trebui să aveţi definită o listă de teste ce acoperă toate aspectele produsului ce trebuie verificate. Veţi şti de asemenea care sunt condiţiile de Pass/Fail pentru teste şi sunteţi sigur că testele sunt scrise într-un format ce facilitează automatizarea lor. E momentul să creaţi User Stories pentru efortul de automatizare. Fiecare user story trebuie estimat şi trebuie să conţină condiţii clare ce determină momentul când este considerat încheiat. Este important să faceţi progresul efortului de automatizare cât mai vizibil astfel încât celealte echipe vor şti când testele automate devin disponibile şi ce funcţionalitate acoperă.

Una dintre greşelile des întâlnite la acest nivel este să încercaţi să faceţi prea multe. Există de obicei o presiune de a automatiza cât mai multe teste. Acest tip de automatizare nu este util pentru nimeni. Prin definirea clară a cerinţelor veţi şti exact cât trebuie să automatizaţi şi când puteţi considera că o anumită componentă este acoperită de testele automate.

Utilizaţi acest proces pentru toate obiectivele de automatizare propuse: regression, validare de build-uri, teste de instalare. Odată ce aveţi definite cerinţele pentru toate sarcinile de automatizare, puteţi trece la nivelul 4.

Nivelul 4: "Măcinarea"

Am petrecut destul timp studiind povestea din spatele jocului şi creând caracterul nostru. E momentul să începem jocul. Orice gamer știe că înainte să ajungi să ai un erou cu adevărat puternic e necesar sa "macini" întâi. Acest lucru presupune îndeplinirea unor misiuni mai uşoare la început pentru a creşte abilităţile eroului, a-i îmbunătăţi echipamentul şi a creşte în experienţă. În orice joc, într-o primă etapă eroul este implicat înr-o serie de misiuni facile până să ajungă la adversarii cu adevărat puternici.

Din păcate nu există nici o scurtătură la nivelul 4. Însă, trecând de nivelul 3 veţi avea la dispoziţie un set clar de cerinţe sau misiuni, pe care trebuie să le îndepliniţi. O idee bună este să începeţi cu testele de "smoke". Acestea sunt teste de bază care, teoretic, ar trebui să fie mai uşor de automatizat, şi care pot fi apoi folosite pentru a determina dacă un build este valid sau nu înainte de a intra pe mâna echipei de testare. O altă opţiune bună este automatizarea testelor de instalare a produsului. Odată ce aveţi un set de teste smoke automatizate precum şi posibilitate de a instala produsul folosind teste automate puteţi implementa un proces de Continous Integration. Principalul obiectiv la acest nivel este să vă faceţi utili celorlate echipe cât mai repede.

Un sfat pentru acest nivel este să încercaţi jocul multiplayer, deoarece câștigi mai multă experiență, când te afli într-un grup. Colaboraţi cu echipele de testare pentru a vă asigura că testele sunt rulate şi acoperă toate aspectele definite în cerinţe. Ei sunt singurii care pot decide când misiunile voastre sunt îndeplinite. Reţineţi că în calitate de inginer de automatizare, scopul vostru este să implementaţi şi să oferiţi suport pentru soluţia de automatizare, nu să rulaţi teste pentru alte echipe şi să investigaţi rezultatele lor.

Odată ce aţi îndeplinit misiunile definite şi coechipierii confirmă acest lucru, puteţi avansa la următorul nivel.

Nivelul 5: Echipamentul este tot!

Trecând prin nivelul 4 aveţi deja experienţă în jocul automatizării. Aţi îndeplinit o serie de misiuni şi începeţi să realizaţi cât de important e să ai un echipament bun. Pentru ca eroul vostru să fie cu adevărat puternic el trebuie să aibă echipamentul potrivit şi să îl menţină în stare bună. În acest nivel vom învăţa de asemenea că este bine să avem diferite rânduri de echipament pentru diferite misiuni.

Dar care este echipamentul eroului în acest joc? Singurele arme pe care le aveţi la dispoziţie sunt testele în sine. În continuare vom prezenta câteva atribute care ar trebui luate în seamă pentru testele automate:

  • Capacitatea de a fi reviziuite: Testele trebuie să fie uşor de înţeles şi revizuit. E important ca ele să fie bine documentate, iar log-urile trebuie să conţină toată informaţia necesară pentru a ca utilizatorul să determine motivul pentru care testul a căzut. Doar pentru că un test trece de fiecare dată, nu înseamnă că este un test bun. Există o posibilitate ca el să nu funcţioneze corect. Utilizatorul trebuie să poată identifica astfel de probleme. Dacă funcţionalitatea testată se schimbă, testele automate trebuie să fie uşor de revizuit şi modificat.
  • Acurateţe: Atunci când un test trece, sau pică, trebuie ca utilizatorul să fie sigur că rezultatul obţinut este unul corect. Orice test trebuie să aibă interfeţe pentru implementarea premiselor scenariului şi pentru a readuce sistemul la starea iniţială după rularea testului. Atunci când automatizaţi scenarii complexe, adăugaţi condiţii speciale pentru a vă asigura că o eroare apărută în metodele ce implementează premisele testului nu va face ca testul să fie picat, ci mai degrabă sărit. Obiectivul testării automate este de a oferi o imagine asupra stării curente a produsului nu de a avea suite de teste ce trec tot timpul.
  • Consistenţă: De fiecare dată când sunt executate, testele trebuie să aibă acelaşi comportament. Interfeţele pre şi post execuţie implementate trebuie să asigure această consistenţă la fiecare rulare a testelor.
  • Independenţă: Utilizatorii vor dori să aibă opţiunea de a executa fie un singur test (pentru a verifica un defect anume), o suită întreagă (pentru a determina starea unei anumite componente) sau un grup de suite (pentru a determina starea produsului). Oferiţi utilizatorilor cât mai multe opţiuni pentru a vă asigura că testele sunt folosite la potenţial maxim.
  • Reutilizare: Pentru a evita duplicarea codului şi pentru a face mai ușor procesul de dezvoltare al testelor noi, puteţi crea anumite utilitare. Extragerea funcţionalităţii comune şi gruparea în clase de utilitare ce pot fi apoi importate în teste, va facilita dezvoltarea testelor noi precum şi investigarea unor posibile erori. Clasele de utilitare trebuie să fie bine documentate (parametri primiţi, valori returnate) pentru a putea fi folosite cu uşurinţă.

O idee bună este să folosiţi un sistem de versionare a codului pentru testele automate, la fel ca şi pentru produsul testat. Dacă produsul testat are mai multe versiuni lansate e bine să aveţi câte o versiune a testelor pentru fiecare versiune a produsului. Anumite funcţionalităţi ale produsului pot fi modificate în diferite versiuni astfel că un singur test s-ar putea să nu fie suficient.

Acum că avem un echipament competitiv e momentul să ne construim o reputaţie in nivelul 6.

Nivelul 6: Făurirea

Sigur, e distractiv să vă folosiţi armele în care aţi investit timp şi efort în nivelul 5 pentru a îndeplini misiuni, dar pentru a avansa în jocul automatizării e necesar să împărţiţi echipamentul cu alţi jucători. Făurirea de echipament vă va ajuta să vă construiţî o reputaţie, iar dacă vă faceţi prieteni puternici veţi progresa mult mai rapid în joc.

Ideea de bază la nivelul 6 este să fiţi darnici. Testele automate trebuie să fie disponibile tuturor utilizatorilor. Grupaţi testele în pachete ce pot fi utilizate de pe orice platormă. După cum am spus şi la nivelul 5 versionarea codului este o idee bună. Utilizaţi sistemul de versionare implementat pentru produs şi pentru testele automate. Astfel veţi avea un pachet nou de teste la fiecare build nou al produsului. Acest lucru vă va permite să vă modificaţi testele rapid, în concordanţă cu schimbările din produs. Nu uitaţi că automatizarea este utilă doar dacă este folosită. La acest nivel cheia este să oferiţi un acces cât mai facil la testele automate indiferent de versiunea testată.

Acum că ne-am îndeplinit misiunile propuse, avem cel mai bun echipament, am făurit arme şi pentru coechipieri ce mai rămâne de facut?

Nivelul 7: Conducătorul de breaslă

Acesta este ultimul nivel al jocului nostru. Acum sunteţi cu adevărat un conducător de breaslă. Jucătorii de nivel mai mic vă caută pentru a cere asistenţă, echipament şi sfaturi. Dar se termină jocul automatizării aici? Doar pentru că acum sunteţi numărului unu,nu înseamnă că veţi rămâne la acest nivel mereu.

Natura jocului automatizării este mereu schimbătoare. Trebuie să fiţi tot timpul în gardă dacă nu vreţi să regresaţi la nivelele anterioare. Căutaţi mereu să îmbunătăţiţi soluţia de automatizare implementată. Menţineţi suitele de teste într-o stare bună. Adăugaţi teste noi, revizuiţi testele vechi pentru a vă asigura ca sunt la curent cu schimbările din produs şi eliminaţi testele care nu mai sunt utile. Lucraţi la framework-ul de automatizare pentru a-i imbunătăţi perferomanţele şi fiabilitatea.

Împărtăşiţi cunoştinţele acumulate. Organizaţi şedinţe pentru a ţine la curent echipele de testare referitor la starea soluţiei de automatizare. Comunicaţi clar modificările ce ar putea avea impact în procesul de testare. O soluţie bine gândită şi bine implementată va permite echipelor de testare să îşi dezvolte singure testele eliberând din timpul vostru, timp ce poate fi folosit pentru îmbunătăţiri. Oferiţi suport pentru echipele ce utilizează testele automate.

Modificările din produs vor produce mereu noi sarcini pentru echipa de automatizare. Comunicaţi cu managerii de produs pentru a afla din timp de modificările ce vă vor afecta şi pentru a vă asigura că automatizarea este luată în calcul in procesul de dezvoltare a noilor funcţionalităţi.

Urmând paşii din acest ghid veţi putea să implementaţi o soluţie de automatizare ce poate fi utilizată eficient şi produce rezultate utile şi vizibile. În cele din urmă, ca în orice alt joc, dacă studiaţi regulile, vă pregătiţi din timp, depuneţi efortul necesar la toate nivelele şi nu trişaţi, la final veţi ieşi învingători. Aşadar, haideţi să câştigăm jocul automatizării.

Bibliografie

  1. Test Automation Architecture: Planning for Test Automation - Douglas Hoffman, 1999
  2. Test Automation Frameworks - Carl J. Neagle, 2000
  3. Common Mistakes in Test Automation - Mark Fewster, 2001
  4. Wikipedia, The Free Encyclopedia
  5. Software Testing Automation Framework (STAF) - http://staf.sourceforge.net/

Conferință TSM

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