Hur man kör flera testfall i TestNG Suite

⚡ Smart sammanfattning

Kör flera testfall med TestNG Svit in Selenium låter dig utlösa flera klasser, paket eller underordnade sviter från en enda testng.xml. Den här genomgången täcker parallella trådar, svithierarki, rapportering och AI-hjälp för moderna TestNG 7.x-projekt.

  • 🧵 Parallella trådar: Ställ in thread-count och parallel=”tests” för att minska den totala körtiden över webbläsare och paket.
  • 🗂️ Svithierarki: En förälder testng.xml kan lista poster i underordnade suite-filer för att länka flera sviter i en utlösare.
  • ⚙️ TestNG 7.x Klar: Exempel överensstämmer med TestNG 7.10 och Selenium 4 W3C-drivrutiner, som ersätter äldre FirefoxDrivrutinskabel.
  • 📊 Smart rapportering: Utförliga nivåer 1 till 10 och e-postbara HTML-rapporter hjälper till att snabbt diagnostisera misslyckade parallella trådar.
  • 🤖 AI-orkestrering: AI-drivna schemaläggare omordnar, försöker igen och shardar sviter baserat på historiska flake- och varaktighetsdata.

Kör flera testfall med TestNG Svit in Selenium

TestNG låter dig köra testmetoder, klasser och fullständiga sviter parallellt i ett projekt. Parallell körning minskar den totala körtiden eftersom trådar startar testerna samtidigt istället för ett efter ett. Den här guiden förklarar hur man kör flera klasser (olika sviter) med hjälp av TestNG 7.x med Selenium WebDriver.

Steg 1) Skapa en TestNG.xml-fil för att köra tester

Följ stegen nedan för att skapa konfigurationen.

  1. Skapa ett nytt projekt i Eclipse.
  2. Skapa två paket i projektet (namnge dem com.suite1 och com.suite2).
  3. Skapa en klass i varje paket (namnge dem Flipkart.java och Snapdeal.java) och kopiera koden nedan till respektive klasser.
  4. Skapa en ny fil i ditt projekt och namnge den testng.xml. Se till att TestNG plugin är installerat (instruktioner finns tillgängliga) här.). Filen testng.xml innehåller all konfiguration, såsom klassnamn, testnamn och svitnamn.

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 slutliga projektstrukturen ser ut som i exemplet nedan.

Skapa ett TestNG.xml-fil för att köra test

Steg 2) Parallellt utförande i TestNG

Efter att ha sparat XML-filen ovan är nästa steg att köra de parallella testerna. Koden visas nedan.

Parallell utförande i TestNG

1) trådräkningDefinierar hur många trådar TestNG kan starta för parallell körning. Ett högre värde kör fler tester samtidigt, upp till CPU-gränsen.

2) talrikLoggar körningsdetaljer i konsolen. Tillåtna värden sträcker sig från 1 till 10. Högre värden ger mer detaljerade och detaljerade loggar.

3) namnSvitens namn. Här är det “Gmail Svit".

4) parallellBerättar TestNG vad som ska köras samtidigt. Giltiga värden är tester, klasser, metoder eller instanser. Standardvärdet är ingen.

Högerklicka på testng.xml-filen och välj Kör som > TestNG SuiteNär det är klart kommer du att se de sammanslagna resultaten.

När du kör ovanstående kod får du följande utdata.

Produktion:

Parallell utförande i TestNG

1) Namn på sviten som definieras i testng.xml.

Parallell utförande i TestNG

2) Namn på testet som definieras i testng.xml.

Parallell utförande i TestNG

3) Namn på klassen som deklarerats i testng.xml.

Parallell utförande i TestNG

4) Metodnamn kommenterade med @Test i .java-filen.

Parallell utförande i TestNG

Samma flöde körs för SnapDeal-testet, så båda klasserna körs sida vid sida.

Steg 3) Köra flera programsviter från en överordnad testng.xml

Ett vanligt krav på större projekt är att kedja samman flera testng.xml-filer till en enda trigger. TestNG 7.x stöder en föräldrasvit som refererar till underordnade svitfil poster, så att varje underordnad fil kan behålla sitt eget trådantal, lyssnare och parametrar. Spara varje underordnad filsvit separat och peka sedan föräldern till dess sökväg. Kör endast förälderfilen från Eclipse, Maven eller kommandoraden.

<!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>

Det här mönstret håller regressions-, rök- och sanity-sviterna separerade men ändå återanvändbara. Du kan också utlösa föräldrafilen från Maven Surefire genom att ställa in <suiteXmlFile>parent-suite.xml</suiteXmlFile> inuti plugin-konfigurationen, vilket gör att samma parallella layout fungerar i kontinuerliga integrationspipelines.

Steg 4) Bästa praxis för parallell TestNG kör

  • nål TestNG 7.x: Använda TestNG 7.10 eller senare med Selenium 4 så att W3C-kompatibla drivrutiner beter sig konsekvent över trådar.
  • Undvik delat tillstånd: Flytta webbdrivrutin fältet i en ThreadLocal så att varje tråd har sin egen session.
  • Justera trådantalet: Börja med antalet CPU-kärnor och titta sedan på den e-postbara HTML-rapporten och nätladdningen innan du laddar upp den.
  • Isolera testdata: Använd unika användare, varukorgar och pinkoder per tråd så att inloggningar aldrig kolliderar.
  • Ta skärmdumpar vid fel: Fäst dem genom en ITestListener för att felsöka ojämna parallella körningar snabbare.
  • Använd AI-hjälp: Verktyg som Testim, mabl och CodiumAI kan flagga ostabila tester och föreslå stabila selektorer före nästa körning.

Slutsats

Exemplet ovan visar hur man använder TestNG att genomföra parallella tester. TestNG 7.x ger dig en enda XML-fil för att starta flera testklasser, länka flera underordnade sviter och finjustera parallella trådar, så stora Selenium projekten slutförs mycket snabbare.

Vanliga frågor

Placera varje klass i sin egen taggen inuti testng.xml, ange sedan parallel="tests" och ett trådantal på minst 2. TestNG startar båda testerna på separata trådar, så klasserna körs samtidigt snarare än sekventiellt.

Ja. Bygg en föräldrasvit som listar underfiler inuti Varje sökväg till underordnad svitfil kör sin egen konfiguration. Mönstret fungerar i Eclipse, Maven Surefire och Gradle, och stöds av TestNG 6 och framåt, inklusive den nuvarande 7.x-utgåvan.

Attributet parallell accepterar tester, klasser, metoder, instanser eller inga. Välj tester när varje taggen är självständig, klasser för helklassisolering och metoder när individuella @Test-metoder är trådsäkra. Standardvärdet är none, vilket kör allt sekventiellt.

Använd en trådlokal eller initiera drivrutinen inuti ett @BeforeMethod-block istället för som ett statiskt fält. Varje tråd äger sedan sin egen webbläsarsession, vilket eliminerar de kapplöpningsförhållanden som kraschar parallellt. TestNG går på Selenium Rutnät.

AI-orkestratorer studerar data från tidigare körningar för att förutsäga fel, sätta instabila tester i karantän och ordna om långsamma tester. Plattformar som Launchable, Testim, och mabl-anslutningen TestNG så de mest sannolikt misslyckade sviterna körs först, vilket förkortar feedback-loopar på kontinuerliga integrationsservrar.

Ja. AI-drivna schemaläggare i Launchable och BuildPulse mäter historisk varaktighet och flakefrekvens per test och delar sedan upp testng.xml i balanserade shards. Varje shard körs på en separat agent, så den totala väggklockan minskar medan parallellanvändningen förblir hög.

Sammanfatta detta inlägg med: