วิธีการรันเคสทดสอบหลายเคสใน TestNG ชุด

⚡ สรุปอย่างชาญฉลาด

รันกรณีทดสอบหลายกรณีด้วย TestNG ห้องชุดใน Selenium ช่วยให้คุณสามารถเรียกใช้งานคลาส แพ็กเกจ หรือชุดทดสอบย่อยหลายรายการจากไฟล์ testng.xml เพียงไฟล์เดียว คู่มือนี้จะครอบคลุมถึงเธรดคู่ขนาน ลำดับชั้นของชุดทดสอบ การรายงาน และความช่วยเหลือจาก AI สำหรับการทดสอบสมัยใหม่ TestNG โปรเจ็กต์เวอร์ชัน 7.x

  • 🧵 เธรดคู่ขนาน: ตั้งค่า thread-count และ parallel=”tests” เพื่อลดเวลาการทำงานโดยรวมในทุกเบราว์เซอร์และแพ็กเกจ
  • 🗂️ ลำดับชั้นของห้องชุด: ไฟล์ testng.xml หลักสามารถระบุรายการไฟล์ suite ย่อยเพื่อเชื่อมโยง suite หลายชุดเข้าด้วยกันในทริกเกอร์เดียวได้
  • ⚙️ TestNG พร้อมใช้งานเวอร์ชัน 7.x: ตัวอย่างสอดคล้องกับ TestNG 7.10 และ Selenium ไดรเวอร์ W3C จำนวน 4 ตัว แทนที่ไดรเวอร์รุ่นเก่า Firefoxการเดินสายไฟของไดร์เวอร์
  • 📊 การรายงานอัจฉริยะ: ระดับความละเอียดในการแสดงผล 1 ถึง 10 และรายงาน HTML ที่สามารถส่งทางอีเมลได้ ช่วยให้วินิจฉัยปัญหาเธรดคู่ขนานที่ล้มเหลวได้อย่างรวดเร็ว
  • 🤖 การจัดการระบบ AI: ระบบจัดตารางเวลาที่ขับเคลื่อนด้วย AI จะจัดลำดับใหม่ ลองใหม่ และแบ่งชุดข้อมูลตามข้อมูลความล้มเหลวและระยะเวลาในอดีต

รันกรณีทดสอบหลายกรณีด้วย TestNG ห้องชุดใน Selenium

TestNG ช่วยให้คุณสามารถรันเมธอดทดสอบ คลาส และชุดทดสอบทั้งหมดพร้อมกันภายในโปรเจกต์เดียว การทำงานแบบขนานช่วยลดเวลาการทำงานโดยรวม เนื่องจากเธรดจะเริ่มการทดสอบพร้อมกันแทนที่จะเริ่มทีละเธรด คู่มือนี้จะอธิบายวิธีการรันหลายคลาส (ชุดทดสอบที่แตกต่างกัน) โดยใช้ TestNG 7.x พร้อม Selenium เว็บไดร์เวอร์

ขั้นตอนที่ 1) การสร้าง TestNGไฟล์ .xml สำหรับเรียกใช้การทดสอบ

ในการสร้างการตั้งค่า ให้ทำตามขั้นตอนด้านล่าง

  1. สร้างโปรเจ็กต์ใหม่ใน Eclipse.
  2. สร้างแพ็กเกจสองแพ็กเกจในโปรเจ็กต์ (ตั้งชื่อแพ็กเกจเหล่านั้น) คอม.สวีท1 และ คอม.สวีท2).
  3. สร้างคลาสในแต่ละแพ็กเกจ (ตั้งชื่อคลาสเหล่านั้น) Flipkart.java และ Snapdeal.java) และคัดลอกโค้ดด้านล่างลงในคลาสที่เกี่ยวข้อง
  4. สร้างไฟล์ใหม่ในโปรเจ็กต์ของคุณและตั้งชื่อไฟล์นั้น การทดสอบ ng.xml. ตรวจดูให้แน่ใจว่า TestNG ติดตั้งปลั๊กอินเรียบร้อยแล้ว (มีคำแนะนำเพิ่มเติม) Good Farm Animal Welfare Awardsไฟล์ testng.xml จะเก็บการตั้งค่าทั้งหมด เช่น ชื่อคลาส ชื่อการทดสอบ และชื่อชุดทดสอบ

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>

โครงสร้างของโปรเจ็กต์สุดท้ายจะมีลักษณะดังตัวอย่างด้านล่าง

การสร้าง TestNGไฟล์ .xml สำหรับดำเนินการทดสอบ

ขั้นตอนที่ 2) การดำเนินการแบบขนานใน TestNG

หลังจากบันทึกไฟล์ XML ข้างต้นแล้ว ขั้นตอนต่อไปคือการรันการทดสอบแบบขนาน โค้ดแสดงอยู่ด้านล่าง

การดำเนินการแบบขนานใน TestNG

1) การนับเส้นด้าย: กำหนดจำนวนเธรด TestNG สามารถเร่งความเร็วในการประมวลผลแบบขนานได้ ค่าที่สูงขึ้นจะทำการทดสอบพร้อมกันมากขึ้น จนถึงขีดจำกัดของ CPU

2) รายละเอียด: บันทึกรายละเอียดการดำเนินการในคอนโซล ค่าที่อนุญาตคือ 1 ถึง 10 ค่าที่สูงขึ้นจะให้บันทึกที่มีรายละเอียดและละเอียดมากขึ้น

3) ชื่อชื่อห้องชุด นี่คือชื่อห้องชุด “Gmail ห้องสวีท”

4) ขนาน: บอก TestNG สิ่งที่จะเรียกใช้พร้อมกัน ค่าที่ถูกต้องคือ การทดสอบ คลาส เมธอด หรืออินสแตนซ์ ค่าเริ่มต้นคือ ไม่มี.

คลิกขวาที่ไฟล์ testng.xml แล้วเลือก เรียกใช้ในฐานะ > TestNG ชุดเมื่อกระบวนการเสร็จสิ้น คุณจะเห็นผลลัพธ์โดยรวม

เมื่อคุณรันโค้ดข้างต้นคุณจะได้รับผลลัพธ์ดังต่อไปนี้

Output:

การดำเนินการแบบขนานใน TestNG

1) ชื่อของชุดทดสอบที่กำหนดไว้ในไฟล์ testng.xml

การดำเนินการแบบขนานใน TestNG

2) ชื่อของการทดสอบที่กำหนดไว้ในไฟล์ testng.xml

การดำเนินการแบบขนานใน TestNG

3) ชื่อของคลาสที่ประกาศไว้ในไฟล์ testng.xml

การดำเนินการแบบขนานใน TestNG

4) ชื่อเมธอดที่มีคำอธิบายประกอบ @Test ในไฟล์ .java

การดำเนินการแบบขนานใน TestNG

กระบวนการทำงานเดียวกันนี้ใช้กับการทดสอบ SnapDeal ด้วย ดังนั้นคลาสทั้งสองจึงทำงานควบคู่กันไป

ขั้นตอนที่ 3) การเรียกใช้ชุดทดสอบหลายชุดจากไฟล์ testng.xml หลักไฟล์เดียว

ข้อกำหนดทั่วไปในโปรเจ็กต์ขนาดใหญ่คือการเชื่อมโยงไฟล์ testng.xml หลายไฟล์เข้าด้วยกันเพื่อสร้างทริกเกอร์เดียว TestNG เวอร์ชัน 7.x รองรับชุดโปรแกรมหลักที่อ้างอิงถึงชุดโปรแกรมย่อย ไฟล์ชุด บันทึกชุดข้อมูลย่อยแต่ละชุดแยกกัน จากนั้นชี้เส้นทางของชุดข้อมูลหลักไปยังชุดข้อมูลหลัก เรียกใช้เฉพาะไฟล์หลักจากไฟล์ต้นฉบับ EclipseMaven หรือผ่านทางบรรทัดคำสั่ง

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

รูปแบบนี้ช่วยแยกชุดทดสอบการถดถอย การทดสอบควัน และการทดสอบความถูกต้องออกจากกัน แต่ยังคงสามารถนำกลับมาใช้ใหม่ได้ นอกจากนี้ คุณยังสามารถเรียกใช้ไฟล์หลักจาก Maven Surefire ได้โดยการตั้งค่า <suiteXmlFile>parent-suite.xml</suiteXmlFile> ภายในการตั้งค่าปลั๊กอิน ซึ่งทำให้โครงสร้างแบบขนานเดียวกันนี้ใช้งานได้ในไปป์ไลน์การรวมระบบอย่างต่อเนื่อง

ขั้นตอนที่ 4) แนวปฏิบัติที่ดีที่สุดสำหรับการทำงานแบบขนาน TestNG ทำงาน

  • หมุด TestNG 7.x: ใช้ TestNG 7.10 หรือเวอร์ชันที่ใหม่กว่า พร้อมด้วย Selenium 4. ดังนั้นไดรเวอร์ที่สอดคล้องกับมาตรฐาน W3C จึงทำงานได้อย่างสม่ำเสมอในทุกเธรด
  • หลีกเลี่ยงการใช้สถานะร่วมกัน: ย้าย ไดรเวอร์เว็บ ส่งข้อมูลฟิลด์ไปยัง ThreadLocal เพื่อให้แต่ละเธรดมีเซสชันของตัวเอง
  • ปรับแต่งจำนวนเส้นด้าย: เริ่มจากจำนวนคอร์ของ CPU ก่อน จากนั้นสังเกตรายงาน HTML ที่ส่งทางอีเมลได้ และการโหลดของ Grid ก่อนที่จะเพิ่มจำนวนคอร์
  • แยกข้อมูลทดสอบ: ใช้ชื่อผู้ใช้ ตะกร้าสินค้า และรหัส PIN ที่ไม่ซ้ำกันสำหรับแต่ละเธรด เพื่อป้องกันการล็อกอินซ้ำซ้อน
  • บันทึกภาพหน้าจอเมื่อเกิดข้อผิดพลาด: เชื่อมต่อเข้าด้วยกันผ่านทาง ITestListener เพื่อแก้ไขข้อผิดพลาดในการทำงานแบบขนานที่ไม่เสถียรได้เร็วขึ้น
  • ใช้ระบบ AI ช่วยเหลือ: เครื่องมือที่ชอบ Testimmabl และ CodiumAI สามารถระบุการทดสอบที่ไม่เสถียรและแนะนำตัวเลือกที่เสถียรก่อนการทำงานครั้งต่อไปได้

สรุป

ตัวอย่างข้างต้นแสดงวิธีการใช้งาน TestNG เพื่อดำเนินการทดสอบแบบขนาน TestNG เวอร์ชัน 7.x ช่วยให้คุณใช้ไฟล์ XML เพียงไฟล์เดียวในการเรียกใช้คลาสทดสอบหลายคลาส เชื่อมโยงชุดทดสอบย่อยหลายชุด และปรับแต่งเธรดแบบขนาน ทำให้ไฟล์ขนาดใหญ่ใช้งานได้สะดวกยิ่งขึ้น Selenium โครงการต่างๆ เสร็จเร็วขึ้นมาก

คำถามที่พบบ่อย

จัดวางแต่ละคลาสไว้ในที่ของตัวเอง ใส่แท็กภายในไฟล์ testng.xml จากนั้นตั้งค่า parallel=”tests” และ thread-count อย่างน้อย 2 TestNG การทดสอบทั้งสองจะเริ่มในเธรดที่แยกจากกัน ดังนั้นคลาสต่างๆ จึงทำงานพร้อมกันแทนที่จะทำงานตามลำดับ

ใช่ สร้างชุดโปรแกรมหลักที่แสดงรายการไฟล์ย่อยภายใน แต่ละเส้นทางไฟล์ชุดย่อยจะเรียกใช้การกำหนดค่าของตัวเอง รูปแบบนี้ใช้ได้ผลใน Eclipseเมเวน ชัวร์ไฟร์ และ Gradleและได้รับการสนับสนุนจาก TestNG ตั้งแต่เวอร์ชัน 6 เป็นต้นไป รวมถึงเวอร์ชัน 7.x ปัจจุบันด้วย

คุณลักษณะ parallel ยอมรับการทดสอบ คลาส เมธอด อินสแตนซ์ หรือไม่มีเลย เลือกการทดสอบเมื่อแต่ละ แท็ก @Test มีความสมบูรณ์ในตัวเอง ใช้สำหรับแยกคลาสทั้งหมด และใช้เมธอดเมื่อเมธอด @Test แต่ละตัวมีความปลอดภัยต่อเธรด ค่าเริ่มต้นคือ none ซึ่งจะรันทุกอย่างตามลำดับ

ใช้ ThreadLocal หรือเริ่มต้นใช้งานไดรเวอร์ภายในบล็อก @BeforeMethod แทนที่จะใช้เป็นฟิลด์แบบ static แต่ละเธรดจะมีเซสชันเบราว์เซอร์เป็นของตัวเอง ซึ่งจะช่วยขจัดปัญหา race condition ที่ทำให้โปรแกรมล่มขณะทำงานแบบขนาน TestNG วิ่งบน Selenium กริด.

ระบบ AI ควบคุมการทำงานจะศึกษาข้อมูลการทำงานครั้งก่อนๆ เพื่อคาดการณ์ความล้มเหลว แยกการทดสอบที่ไม่เสถียร และจัดลำดับการทดสอบที่ช้าใหม่ แพลตฟอร์มต่างๆ เช่น Launchable, Testimและเสียบปลั๊ก mabl เข้าไป TestNG ดังนั้นชุดทดสอบที่มีแนวโน้มที่จะล้มเหลวมากที่สุดจะถูกเรียกใช้ก่อน ซึ่งจะช่วยลดระยะเวลาของวงจรการตอบรับบนเซิร์ฟเวอร์การรวมระบบอย่างต่อเนื่อง

ใช่แล้ว ตัวจัดตารางเวลาที่ขับเคลื่อนด้วย AI ใน Launchable และ BuildPulse จะวัดระยะเวลาและอัตราความผิดพลาดในอดีตของแต่ละการทดสอบ จากนั้นจะแบ่งไฟล์ testng.xml ออกเป็นส่วนย่อยๆ ที่สมดุลกัน แต่ละส่วนย่อยจะทำงานบนเอเจนต์ที่แยกจากกัน ดังนั้นเวลาโดยรวมจึงลดลง ในขณะที่การใช้งานแบบขนานยังคงสูงอยู่

สรุปโพสต์นี้ด้วย: