複数のテストケースを実行する方法 TestNG スイート

⚡ スマートサマリー

複数のテストケースを実行する TestNG スイート Selenium 単一の testng.xml から複数のクラス、パッケージ、または子スイートをトリガーできます。このチュートリアルでは、並列スレッド、スイート階層、レポート、および最新の AI アシスタンスについて説明します。 TestNG 7.x プロジェクト。

  • 🧵 並列スレッド: ブラウザやパッケージ全体で実行時間を大幅に短縮するには、thread-countとparallel=”tests”を設定してください。
  • 🗂️ スイート階層: 親のtestng.xmlファイルには、子のsuite-fileエントリをリストアップすることで、複数のスイートを1つのトリガーに連結できます。
  • ⚙️ TestNG 7.x 対応済み: 例は以下と一致します TestNG 7.10本、そして Selenium 4つのW3Cドライバが従来のドライバを置き換えます Firefoxドライバー配線。
  • 📊 スマートレポート: 詳細レベル1~10とメール送信可能なHTMLレポートにより、並列スレッドの障害を迅速に診断できます。
  • 🤖 AIオーケストレーション: AIを活用したスケジューラは、過去のフレークデータと期間データに基づいて、スイートの順序変更、再試行、およびシャーディングを行います。

複数のテストケースを実行する TestNG スイート Selenium

TestNG を使用すると、1 つのプロジェクト内でテスト メソッド、クラス、およびテスト スイート全体を並列実行できます。並列実行では、スレッドがテストを 1 つずつではなく同時に開始するため、全体の実行時間が短縮されます。このガイドでは、を使用して複数のクラス (異なるスイート) を実行する方法について説明します。 TestNG 7.x Selenium ウェブドライバー。

ステップ 1) TestNGテストを実行するための.xmlファイル

設定を作成するには、以下の手順に従ってください。

  1. 新しいプロジェクトを作成する Eclipse.
  2. プロジェクト内に 2 つのパッケージを作成します (名前を付けます) com.suite1 (NAIST) と com.suite2).
  3. 各パッケージにクラスを作成します(名前を付けます)。 フリップカート.java (NAIST) と Snapdeal.java)そして、以下のコードをそれぞれのクラスにコピーしてください。
  4. プロジェクトに新しいファイルを作成し、名前を付けます。 テスト。 その TestNG プラグインがインストールされました(手順はこちら) こちらtestng.xml ファイルには、クラス名、テスト名、スイート名などのすべての設定が含まれています。

フリップカート.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();
    }
}

スナップディール.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>

最終的なプロジェクト構造は、以下の例のようになります。

aを作成する TestNGテストを実行するための .xml ファイル

ステップ 2) での並列実行 TestNG

上記のXMLファイルを保存した後、次のステップは並列テストを実行することです。コードは以下のとおりです。

での並列実行 TestNG

1) スレッド数: スレッド数を定義します TestNG 並列実行のために起動できます。値が大きいほど、CPUの上限まで同時に実行されるテストの数が増えます。

2) 冗長コンソールに実行の詳細をログ出力します。指定可能な値は1~10です。値が大きいほど、より詳細で粒度の高いログが出力されます。

3) 名前: スイートの名前。こちらです「Gmail スイート"。

4) 平行: 伝える TestNG 並行して実行するもの。有効な値は、テスト、クラス、メソッド、またはインスタンスです。デフォルト値は なし.

testng.xml ファイルを右クリックして、 実行者 > TestNG スイート処理が完了すると、集計結果が表示されます。

上記のコードを実行すると、次の出力が得られます。

出力:

での並列実行 TestNG

1) testng.xmlで定義されているスイートの名前。

での並列実行 TestNG

2) testng.xmlで定義されているテストの名前。

での並列実行 TestNG

3) testng.xmlで宣言されているクラスの名前。

での並列実行 TestNG

4) .java ファイル内で @Test で注釈が付けられたメソッド名。

での並列実行 TestNG

SnapDealのテストでも同じフローが実行されるため、両方のクラスが並行して実行されます。

ステップ3)1つの親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 runs

  • ピン留め TestNG 7.x:   TestNG 7.10以降 Selenium 4. W3C準拠のドライバがスレッド間で一貫した動作をするようにする。
  • 共有状態を避ける: 移動 webdriver フィールドをThreadLocalに変換することで、各スレッドが独自のセッションを保持できるようにします。
  • スレッド数を調整する: まずはCPUコア数を確認し、次にメール送信可能なHTMLレポートとグリッドの読み込み状況を確認してから、コア数を増やしてください。
  • 試験データを分離する: ログインが競合しないように、スレッドごとに固有のユーザー、カート、PINコードを使用してください。
  • 失敗時にスクリーンショットをキャプチャする: それらを接続します ITestListenerComment 不安定な並列実行をより迅速にデバッグするため。
  • AIアシスタントを活用する: のようなツール TestimmablやCodiumAIは、不安定なテストを検出し、次の実行前に安定したセレクターを提案することができます。

結論

上記の例は、使用方法を示しています。 TestNG 並列テストを実行する。 TestNG 7.x では、複数のテスト クラスを起動し、複数の子スイートをリンクし、並列スレッドを調整するための単一の XML ファイルが提供されるため、大規模な Selenium プロジェクトがはるかに早く完了する。

よくあるご質問

各クラスをそれぞれtestng.xml 内のタグで、parallel=”tests” と、少なくとも 2 のスレッド数を設定します。 TestNG 両方のテストを別々のスレッドで開始するため、クラスは順次ではなく並行して実行されます。

はい。子ファイルを一覧表示する親スイートを作成します。各子スイートファイルパスは独自の構成を実行します。このパターンは Eclipse、Maven Surefire、そして Gradle、そして以下からサポートされています TestNG 6以降、現在の7.xリリースを含む。

parallel属性は、テスト、クラス、メソッド、インスタンス、またはなしを受け入れます。各テストを選択する場合は、タグは自己完結型であり、クラスはクラス全体を分離するためのものであり、メソッドは個々の @Test メソッドがスレッドセーフである場合に使用されます。デフォルト値は none で、すべてが順次実行されます。

ThreadLocal を使用するまたは、静的フィールドとしてではなく、@BeforeMethod ブロック内でドライバーを初期化します。各スレッドは独自のブラウザセッションを所有するため、並列クラッシュの原因となる競合状態が解消されます。 TestNG 走る Selenium グリッド。

AI オーケストレーターは、過去の実行データを分析して障害を予測し、不安定なテストを隔離し、遅いテストを並べ替えます。Launchable などのプラットフォームでは、 Testim、そしてmablプラグイン TestNG そのため、最も失敗する可能性の高いスイートが最初に実行され、継続的インテグレーションサーバー上のフィードバックループが短縮されます。

はい。LaunchableとBuildPulseのAI駆動型スケジューラは、テストごとの過去の実行時間と不安定率を測定し、testng.xmlをバランスの取れたシャードに分割します。各シャードは個別のエージェントで実行されるため、並列処理の利用率を高く維持しながら、総実行時間を短縮できます。