ABONAMENTE VIDEO REDACȚIA
RO
EN
NOU
Numărul 150
Numărul 149 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 129
Abonament PDF

În căutarea perfecțiunii: proiecte mai bune cu Clean Code, BDD și Testare Automată

Denisa Lupu
Java Software Developer @ msg systems Romania



PROGRAMARE


Știm cu toții că în lumea programării nu există proiecte perfecte sau fără buguri. În ciuda eforturilor noastre de a scrie cod de înaltă calitate și de a testa meticulos aplicațiile noastre, greșelile și neglijențele sunt, până la urmă, inevitabile. Dar asta nu înseamnă că ar trebui să renunțăm la dorința de perfecțiune. Există mai multe tehnici de care ne putem folosi pentru a ne dezvolta proiectele mai bine și mai fiabil.

O abordare ar fi să ne concentrăm pe scrierea de cod "curat", ușor de înțeles și de întreținut. Folosind principiile de Clean Code, putem minimiza probabilitatea de a introduce erori, făcând astfel procesul de înțelegere și modificare a codului mai ușor atât pentru noi cât și pentru alții.

O altă tehnică pe care o putem folosi pentru a îmbunătăți experiența noastră, indiferent de proiectul la care lucrăm, este aceea de a aplica Behavior Driven Development (Dezvoltarea Bazată pe Comportament) sau, pe scurt, BDD. Această tehnică pune accent pe colaborarea și comunicarea dintre dezvoltatori, testeri și membrii non-tehnici ai echipei. BDD ne ajută să ne asigurăm că toți cei implicați în proiect au înțelegere deplină a ceea ce software-ul trebuie să facă, iar codul și testele sunt aliniate cu aceste cerințe.

Observăm că undeva la intersecția acestor două concepte putem găsi loc pentru ideea de testare automată. Prin scrierea de teste automate care pot fi rulate rapid și ușor, putem identifica erorile în stadiile incipiente și, totodată, să ne asigurăm că funcționalitatea codului nostru se încadrează în parametrii necesari chiar și atunci când facem schimbări.

În acest articol, vom explora fiecare dintre aceste tehnici în detaliu și vom discuta cum pot fi utilizate împreună pentru a dezvolta proiecte robuste și bug-free (pe cât de multe se poate).

O scurtătură marca Clean Code pentru a obține cod human-friendly

Înainte de a merge mai departe trebuie să stabilim un concept de bază legat de Clean Code și cum ne-ar afecta în această situație. Desigur, fiecare developer știe că aplicarea principiilor de Clean Code reduce costurile de dezvoltare și îmbunătățește calitatea produsului final. Din păcate, există foarte multe reguli pe care ar trebui să le aplicăm în timp ce analizăm sau proiectăm flow-uri complexe în cod. Uneori, putem fi prea copleșiți de taskul respectiv pentru a ne concentra cu adevărat pe regulile și directivele învățate acum mult timp, "in a galaxy far far away …". Prin urmare, în scopul acestui articol, trebuie să avem în minte o singură regulă, respectiv unul din principiile de bază ale Clean Code: "Pot să-l citesc?". Atunci când codul conține orice lucru care necesită o explicație suplimentară sau muncă de detectiv, înseamnă că nu-l putem citi cu adevărat, prin urmare nu este human-friendly. În final, exact asta dorim să obținem: un cod cu care este ușor de lucrat.

Baza automatizării de succes a testelor: BDD

O altă parte esențială pentru îmbunătățirea codului este testarea. Cu toții putem fi de acord că testarea este un pas esențial în asigurarea faptului că diferitele componente ale aplicației funcționează împreună așa cum trebuie. Adesea, testele pe care le scriem pentru diferite flow-uri se bazează exclusiv pe înțelegerea noastră asupra business logicului. Iar asta se dovedește a fi o logică ușor eronată, în unele cazuri. Ca și scrierea codului, scrierea testelor poate duce la același proces confuz descris mai devreme. Pornim de undeva, doar că, uneori, complexitatea componentei testate ne face să ne abatem de la scopul nostru principal. În acest punct, posibilele rezultate și scenarii sunt trecute cu vederea, iar bugurile pot rămâne nedescoperite. Aici intervine utilizarea metodologiei de Behavior Driven Development (BDD).

BDD este o abordare de tip Agile în care o aplicație este proiectată în jurul comportamentului pe care utilizatorul se așteaptă să-l aibă în timpul interacțiunii cu ea. În BDD, cerințele de software sunt exprimate ca user stories (diverse scenarii ipotetice din punct de vedere al utilizatorului care folosește aplicația), scrise într-un limbaj simplu și concis, care este ușor de înțeles atât de membrii tehnici, cât și de cei non-tehnici.

A avea scenarii bine exprimate, folosind logica "Given - When - Then" este un punct de plecare excelent pentru crearea scenariilor de testare automată. Acest lucru încurajează o strânsă colaborare între dezvoltatori, testeri și membrii non-tehnici ai echipei, ceea ce produce o înțelegere mai clară a comportamentului aplicației, precum și a criteriilor de acceptare necesare. În plus, acest lucru adaugă valoare integrării continue (continuous integration) și a verificării calității. De ce? De exemplu, cu integrarea continuă, testăm automat proiectul cu fiecare nouă modificare care este făcută sau feature adăugat. Acest lucru previne regresia și oferă feedback cu privire la posibilele modificări care pot afecta alte părți ale aplicației.

În continuare, vom observa cum putem descrie cerințele și logica software-ului în termeni de scenarii exprimate într-un limbaj simplu și ușor de înțeles.

Aici putem vedea cum se desfășoară structura "Given - When - Then". De asemenea, observăm că acesta este punctul de plecare în aplicarea principiului metaforic de Clean Code: "Can I read it?". Folosind o explicare simplă și lizibilă a funcționalității, evităm confuzia și posibilitatea de a introduce cod duplicat sau de a crea faimosul "spaghetti code".

Aplicarea BDD și Clean Code în testarea automată cu Cucumber

Testele scrise folosind Cucumber sunt implementate într-o sintaxă simplă și declarativă care utilizează limbajul natural pentru a descrie comportamentul software-ului în termeni de scenarii și pași. Aceste scenarii sunt definite folosind limbajul Gherkin care constă într-un set de cuvinte cheie folosite pentru a oferi structură și semnificație specificațiilor executabile. Fiecare pas în Gherkin este asociat cu o metodă care execută pasul respectiv, realizat prin utilizarea de adnotări și regex care le leagă împreună.

Cucumber suportă o mulțime de limbaje de programare și este destul de ușor de instalat. Pentru pași specifici referitor la modul de a începe testarea pe un proiect cu aceasta, vă rugăm să accesați https://cucumber.io/docs/installation/, selectați limbajul de programare dorit și urmați instrucțiunile.

Cu toate acestea, simpla definire a unui scenariu și instalarea Cucumber nu va face magia transformării unui text simplu în teste automate. Trebuie să mergem un pas mai departe în procesul de definire a pașilor. În esență, acest lucru înseamnă luarea fiecărui fragment de text din descrierea scenariului și interpretarea acestuia în metode sau funcții independente.

În timp ce scenariile descriu cerințele, definițiile pasului reprezintă o formă de divide et impera ( dezbină și cucerește). Beneficiul împărțirii cerinței în sarcini mici și independente este că acestea vor deveni reutilizabile în alte scenarii. Acest layer de definiție a pasului apelează layerul de automatizare a testului și rulează efectiv metodele necesare.

Cucumber și JUnit 5 în proiectele Java

Urmează câțiva pași de bază necesari rulării unui exemplu folosind Cucumber și JUnit 5 într-un proiect Java:

Pasul 1: Adăugarea dependințelor necesare.

<dependencies>
   <dependency>
     <groupId>org.junit.jupiter</groupId>
     <artifactId>junit-jupiter</artifactId>
     <version>${junit-jupiter.version}</version>
     <scope>test</scope>
   </dependency>
   <dependency>
     <groupId>org.junit.platform</groupId>
     <artifactId>junit-platform-suite</artifactId>
     <version>${junit-platform-suite.version}
     </version>
     <scope>test</scope>
   </dependency>
   <dependency>
     <groupId>io.cucumber</groupId>
     <artifactId>cucumber-java</artifactId>
     <version>${cucumber.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-junit-platform-engine
      </artifactId>
      <version>${cucumber.version}</version>
      <scope>test</scope>
    </dependency>
    </dependencies>

    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin
            </artifactId>
            <version>
                ${maven-surefire-plugin.version}
            </version>
         </plugin>
      </plugins>
    </build>

Pe lângă dependința cucumber-java, ar fi necesară și dependința cucumber-junit-platform-engine pentru a rula folosind JUnit 5.

Pasul 2: Definirea unui punct de acces.

În JUnit 4, punctul de acces pentru folosire Cucumber ar fi fost definit prin utilizarea @RunWith(Cucumber.class). Pentru integrarea cu JUnit 5, a fost folosită adnotare @Cucumber. Cu toate acestea, deoarece integrarea completă cu JUnit5 este posibilă, adnotarea este acum depreciată și trebuie să utilizăm @Suite împreună cu alte adnotări.

package com.dlupu.cucumber.demo;

import org.junit.platform.suite.api
       .ConfigurationParameter;

import org.junit.platform.suite.api.IncludeEngines;
import org.junit.platform.suite.api
       .SelectClasspathResource;

import org.junit.platform.suite.api.Suite;

import static io.cucumber.junit.platform.engine
       .Constants.GLUE_PROPERTY_NAME;

@Suite
@IncludeEngines("cucumber") 
//tells JUnit 5 to use Cucumber test engine to run 
//features

@SelectClasspathResource("features")
//where the feature files are located

@ConfigurationParameter(key = GLUE_PROPERTY_NAME, 
  value = "com.dlupu.cucumber.demo")
//^this annotation specifies the path to steps 
// definitions

public class CucumberTest {
}

Pasul 3: Crearea fișierelor de caracteristici (features).

Un fișier de caracteristici, care are extensia feature, cuprinde unul sau mai multe scenarii destinate testării unei anumite funcționalități, fiecare scenariu reprezentând un singur caz de testare. Acesta este locul în care este utilizat limbajul Gherkin. Așadar, trebuie să ne asigurăm că avem instalat pluginul pentru limbajul Gherkin.

Feature: Shopping functionalities
  Scenario: Earning a 10% online voucher when 
  shopping of 100 dollars
    Given user selects products in value of 
    100 dollars
    When user completes the purchase
    Then user should receive a 10% online voucher

În funcție de IDE-ul utilizat, pașii care nu au fost implementați încă în fișierul de Steps vor fi highlighted.

Pasul 4: Adăugați o clasă de definire a pașilor.

Clasa Steps creează conexiunea între fiecare pas al scenariului descris în fișierul feature și o metodă corespunzătoare care trebuie executată. Când Cucumber execută un pas din scenariul pe care l-am descris în fișierul feature, el scanează, de fapt, clasa Steps și determină ce funcție ar trebui invocată.

package com.dlupu.cucumber.demo;

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;

public class ShoppingSteps {

 @Given("user selects products in value of {int}"+
  " dollars")

 public void userSelectsProductsInValueOfDollars(
  int amount) {

   System.out.println("user selects products in " 
   +"value of " + amount + " dollars");
   }

 @When("user completes the purchase")
 public void userCompletesThePurchase() {
   System.out.println("user completes the purchase");
 }

 @Then("user should receive a {int}% online voucher")
 public void userShouldReceiveAOnlineVoucher(
  int voucherAmount) {

  System.out.println("user should receive a " + 
  voucherAmount + "% online voucher");
  }
}

Pasul 5: Rularea testelor.

Testele pot fi rulate folosind comanda mvn clean test sau mvn clean install.

Concluzie

Observăm că, prin utilizarea BDD și Cucumber, echipele pot identifica buguri sau inconsistențe logice în stadiile incipiente ale procesului de dezvoltare, ceea ce ajută la reducerea costurilor asociate cu remedierea defectelor de mai târziu în proiect. De asemenea, se asigură că proiectul îndeplinește cerințele și așteptările clientului, rezultând într-un proiect dezvoltat cu succes. Chiar dacă partea mai spectaculoasă este realizată de frameworkul de testare, trebuie să observăm că, fără baza principiilor de Clean Code și fără utilizarea unui business logic clar definit, explicat într-un mod "human-friendly" (indiferent dacă este cod sau doar documentație), acest proces de automatizare a testelor nu ar fi posibil.

Referințe

  1. Garcia, Boni. Mastering Software Testing with Junit 5. Packt Publishing, 2017.

  2. Martin, Robert C., et al. Clean Code A Handbook of Agile Software Craftsmanship. Pearson Education, Inc, 2016.

  3. Rose, Seb, et al. The Cucumber for Java Book: Behaviour-Driven Development for Testers and Developers. The Pragmatic Bookshelf, 2015.

  4. Smart, John Ferguson, and Dan North. BDD in Action: Behavior-Driven Development for the Whole Software Lifecycle. Manning, 2015.

  5. "Tools and Techniques That Elevate Teams to Greatness." Cucumber, https://cucumber.io/.

NUMĂRUL 149 - Development with AI

Sponsori

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