Sådan kører du flere testcases i TestNG Suite

⚡ Smart opsummering

Kør flere testcases med TestNG Suite i Selenium lader dig udløse flere klasser, pakker eller underordnede suiter fra en enkelt testng.xml. Denne gennemgang dækker parallelle tråde, suitehierarki, rapportering og AI-assistance til moderne TestNG 7.x-projekter.

  • 🧵 Parallelle tråde: Indstil thread-count og parallel=”tests” for at reducere den samlede runtime på tværs af browsere og pakker.
  • 🗂️ Suitehierarki: En overordnet testng.xml-fil kan liste underordnede suite-fil-poster for at kæde flere suiter sammen i én trigger.
  • 🇧🇷 TestNG 7.x Klar: Eksempler stemmer overens med TestNG 7.10 og Selenium 4 W3C-drivere, der erstatter ældre drivere FirefoxDriverledningsføring.
  • 📊 Smart rapportering: Udførlige niveauer 1 til 10 og HTML-rapporter, der kan sendes via e-mail, hjælper med hurtigt at diagnosticere fejlede parallelle tråde.
  • 🤖 AI-orkestrering: AI-drevne planlæggere genbestiller, forsøger igen og sharder suiter baseret på historiske flake- og varighedsdata.

Kør flere testcases med TestNG Suite i Selenium

TestNG lader dig køre testmetoder, klasser og komplette suiter parallelt i ét projekt. Parallel udførelse reducerer den samlede kørselstid, fordi tråde starter testene samtidigt i stedet for én efter én. Denne vejledning forklarer, hvordan man kører flere klasser (forskellige suiter) ved hjælp af TestNG 7.x med Selenium WebDriver.

Trin 1) Oprettelse af en TestNG.xml-fil til udførelse af tests

Følg nedenstående trin for at oprette konfigurationen.

  1. Opret et nyt projekt i Eclipse.
  2. Opret to pakker i projektet (navngiv dem com.suite1 og com.suite2).
  3. Opret en klasse i hver pakke (navngiv dem Flipkart.java og Snapdeal.java) og kopier koden nedenfor ind i de respektive klasser.
  4. Opret en ny fil i dit projekt og navngiv den testng.xml. Sørg for, at TestNG plugin er installeret (instruktioner tilgængelige link.). Filen testng.xml indeholder al konfiguration, såsom klassenavne, testnavne og suite-navne.

Flipkart.java

package com.suite1;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class Flipkart {

    WebDriver driver = new FirefoxDriver();
    String username = ""; // Change to your username and password
    String password = "";

    // This method navigates to the Flipkart URL
    @BeforeClass
    public void init() {
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
        driver.navigate().to("https://www.flipkart.com");
    }

    // Log in to Flipkart
    @Test
    public void login() {
        driver.findElement(By.partialLinkText("Login")).click();
        driver.findElement(By.cssSelector(".fk-input.login-form-input.user-email")).sendKeys(username);
        driver.findElement(By.cssSelector(".fk-input.login-form-input.user-pwd")).sendKeys(password);
        driver.findElement(By.cssSelector(".submit-btn.login-btn.btn")).click();
    }

    // Search for a product
    @Test
    public void searchAndSelectProduct() {
        driver.findElement(By.id("fk-top-search-box")).sendKeys("moto g3");
        driver.findElement(By.cssSelector("search-bar-submit.fk-font-13.fk-font-bold")).click();
        String css = ".gd-row.browse-grid-row:nth-of-type(1) > div:nth-child(1)>div>div:nth-child(2)>div>a";
        driver.findElement(By.cssSelector(css)).click();
    }

    @Test
    public void buyAndRemoveFromCart() {
        driver.findElement(By.cssSelector(".btn-express-checkout.btn-big.current")).click();
        driver.findElement(By.cssSelector(".remove.fk-inline-block")).click();
        Alert a = driver.switchTo().alert();
        a.accept();
    }

    @Test
    public void logout() {
        Actions s = new Actions(driver);
        WebElement user = driver.findElement(By.partialLinkText(username));
        s.moveToElement(user).build().perform();
        driver.findElement(By.linkText("Logout")).click();
    }

    @AfterClass
    public void quit() {
        driver.close();
    }
}

SnapDeal.java

package com.suite2;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class SnapDeal {

    WebDriver driver = new FirefoxDriver();
    String username = ""; // Change to your username and password
    String password = "";
    String pinCode = "";

    // This method navigates to the Snapdeal URL
    @BeforeClass
    public void init() {
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
        driver.navigate().to("https://www.snapdeal.com");
    }

    @Test
    public void login() {
        driver.findElement(By.xpath("//button[text()='Login']")).click();
        driver.switchTo().frame("loginIframe");
        driver.findElement(By.cssSelector("div[onClick='getLoginForm()']")).click();
        driver.findElement(By.id("j_username")).sendKeys(username);
        driver.findElement(By.id("j_password_login")).sendKeys(password);
        driver.findElement(By.id("signin_submit")).click();
        driver.switchTo().defaultContent();
    }

    @Test
    public void searchAndSelectProduct() {
        driver.findElement(By.cssSelector(".col-xs-20.searchformInput.keyword")).sendKeys("iphone 6s");
        driver.findElement(By.cssSelector(".sd-icon.sd-icon-search")).click();
        String css = ".product_grid_row:nth-of-type(1)>div:nth-child(1)";
        driver.findElement(By.cssSelector(css)).click();
    }

    @Test
    public void buyAndRemoveFromCart() {
        driver.findElement(By.xpath("//li[contains(text(),'Silver')]")).click();
        driver.findElement(By.id("pincode-check")).sendKeys(pinCode);
        driver.findElement(By.id("buy-button-id")).click();
        driver.findElement(By.cssSelector("i[title='Delete Item']")).click();
        Alert a = driver.switchTo().alert();
        a.accept();
    }

    @Test
    public void logout() {
        driver.findElement(By.linkText("START SHOPPING NOW")).click();
        Actions s = new Actions(driver);
        WebElement user = driver.findElement(By.cssSelector(".sd-icon.sd-icon-user"));
        s.moveToElement(user).build().perform();
        driver.findElement(By.linkText("Logout")).click();
    }

    @AfterClass
    public void quit() {
        driver.close();
    }
}

TestNG. Xml

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">

<suite thread-count="2" verbose="1" name="Gmail Suite" parallel="tests">

  <test name="flipkart">
    <classes>
      <class name="com.suite1.Flipkart"/>
    </classes>
  </test>

  <test name="Myntra">
    <classes>
      <class name="com.suite2.SnapDeal"/>
    </classes>
  </test>
</suite>

Den endelige projektstruktur ser ud som eksemplet nedenfor.

Oprettelse af en TestNG.xml-fil til udførelse af test

Trin 2) Parallel udførelse i TestNG

Efter at have gemt XML-filen ovenfor, er næste trin at køre de parallelle tests. Koden er vist nedenfor.

Parallel udførelse i TestNG

1) trådtalDefinerer hvor mange tråde TestNG kan starte op for parallel udførelse. En højere værdi kører flere tests på én gang, op til CPU-grænsen.

2) verboseLogfører udførelsesdetaljer i konsollen. Tilladte værdier går fra 1 til 10. Højere værdier producerer mere detaljerede og granulerede logfiler.

3) navnNavnet på suiten. Her er det “Gmail Suiten”.

4) parallelFortæller TestNG hvad der skal køres samtidigt. Gyldige værdier er test, klasser, metoder eller instanser. Standardværdien er ingen.

Højreklik på testng.xml-filen, og vælg Kør som > TestNG SuiteNår det er færdigt, vil du se de samlede resultater.

Når du udfører ovenstående kode, får du følgende output.

Output:

Parallel udførelse i TestNG

1) Navn på den suite, der er defineret i testng.xml.

Parallel udførelse i TestNG

2) Navn på den test, der er defineret i testng.xml.

Parallel udførelse i TestNG

3) Navn på den klasse, der er deklareret i testng.xml.

Parallel udførelse i TestNG

4) Metodenavne kommenteret med @Test i .java-filen.

Parallel udførelse i TestNG

Det samme flow kører for SnapDeal-testen, så begge klasser udføres side om side.

Trin 3) Kørsel af flere suiter fra én overordnet testng.xml

Et almindeligt krav på større projekter er at kæde flere testng.xml-filer sammen til en enkelt trigger. TestNG 7.x understøtter en forældresuite, der refererer til underordnede suite-fil poster, så hvert barn kan beholde sit eget trådantal, lyttere og parametre. Gem hver barnesuite separat, og peg derefter den overordnede fil til dens sti. Kør kun den overordnede fil fra Eclipse, Maven eller kommandolinjen.

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Parent Suite" parallel="tests" thread-count="4">
  <suite-files>
    <suite-file path="./flipkart-suite.xml"/>
    <suite-file path="./snapdeal-suite.xml"/>
  </suite-files>
</suite>

Dette mønster holder regressions-, røg- og sanity-pakkerne adskilte, men genanvendelige. Du kan også udløse den overordnede fil fra Maven Surefire ved at indstille <suiteXmlFile>parent-suite.xml</suiteXmlFile> inde i plugin-konfigurationen, hvilket får det samme parallelle layout til at fungere i kontinuerlige integrationspipelines.

Trin 4) Bedste praksis for parallel TestNG løber

  • Pin (Binding) TestNG 7.x: Brug TestNG 7.10 eller nyere med Selenium 4 så W3C-kompatible drivere opfører sig ensartet på tværs af tråde.
  • Undgå delt tilstand: Flyt webdriver feltet ind i en ThreadLocal, så hver tråd har sin egen session.
  • Justér trådantal: Start med antallet af CPU-kerner, og se derefter den e-mailbare HTML-rapport og Grid-indlæsningen, før du hæver den.
  • Isoler testdata: Brug unikke brugere, indkøbskurve og pinkoder pr. tråd, så logins aldrig kolliderer.
  • Tag skærmbilleder ved fejl: Fastgør dem gennem en ITestListener til at fejlfinde ustabile parallelle kørsel hurtigere.
  • Brug AI-hjælp: Værktøjer som Testim, mabl og CodiumAI kan markere ustabile tests og foreslå stabile selektorer før næste kørsel.

Konklusion

Eksemplet ovenfor viser, hvordan man bruger TestNG at udføre parallelle tests. TestNG 7.x giver dig en enkelt XML-fil til at starte flere testklasser, linke flere underordnede suiter og finjustere parallelle tråde, så store Selenium projekter bliver færdige meget hurtigere.

Ofte Stillede Spørgsmål

Placer hver klasse i sin egen tagget i testng.xml, og indstil derefter parallel="tests" og et trådantal på mindst 2. TestNG starter begge tests på separate tråde, så klasserne udføres samtidigt i stedet for sekventielt.

Ja. Byg en overordnet suite, der viser underfiler indeni Hver sti til en underordnet suite-fil kører sin egen konfiguration. Mønsteret fungerer i Eclipse, Maven Surefire, og Gradle, og er støttet fra TestNG 6 og fremefter, inklusive den nuværende 7.x-udgivelse.

Attributten parallel accepterer tests, klasser, metoder, instanser eller ingen. Vælg tests, når hver `tag` er selvstændig, klasser til isolering af hele klasser, og metoder, når individuelle @Test-metoder er trådsikre. Standardværdien er `none`, hvilket kører alt sekventielt.

Brug en ThreadLocal eller initialiser driveren i en @BeforeMethod-blok i stedet for som et statisk felt. Hver tråd ejer derefter sin egen browsersession, hvilket eliminerer de kapløbsbetingelser, der går ned parallelt. TestNG kører på Selenium Gitter.

AI-orkestratorer studerer data fra tidligere kørsel for at forudsige fejl, sætte ustabile tests i karantæne og omarrangere langsomme tests. Platforme som Launchable, Testim, og mabl-stikket ind TestNG så de mest sandsynligt fejlende suiter kører først, hvilket forkorter feedback-loops på kontinuerlige integrationsservere.

Ja. AI-drevne planlæggere i Launchable og BuildPulse måler historisk varighed og flake-rate pr. test og opdeler derefter testng.xml i balancerede shards. Hver shard kører på en separat agent, så den samlede wall-clock-tid falder, mens den parallelle udnyttelse forbliver høj.

Opsummer dette indlæg med: