如何在并行执行中退出移动驱动程序会话 - Browserstack 中的 testng

问题描述 投票:0回答:1

我正在开发 TestNG 框架,该框架与 Browserstack 集成以实现移动自动化。 该框架表现得非常好,直到我们在浏览器堆栈中运行单个线程来执行测试。 当我们集成并行执行时,问题实际上就开始了。我们的框架有一个 json 文件,我们在其中定义所有设备功能并调用它们来执行。示例如下:

  "about": {
    "project": "Demo-DexAutomation",
    "team": "QE",
    "environment": "QA",
    "releaseVersion": "1.0"
  },
  "gui": {
    "ss:remoteExecutor": {
      "browserstack": {
        "ss:remoteAddress": "http://hub-cloud.browserstack.com/wd/hub",
        "browserstack.user": “<Username>”,
        "browserstack.key": “<access key>“
      }
    },
    "defaultProfile": "browserstack-oneplus-7T",
    "multiProfile": [
      "browserstack-samsung-galaxy-s21-plus",
      "browserstack-oneplus-7T",
      "browserstack-google-pixel-4"
    ],
    "randomProfile": [
      "browserstack-samsung-galaxy-s21-plus",
      "browserstack-google-pixel-4",
      "browserstack-oneplus-7T"
    ],
   "browserstack-samsung-galaxy-s21-plus": {
        "ss:remoteExecutor": "browserstack",
        "platformName": "Android",
        "app": "bs://fbac93a34795331e12e3949ac65d120e73422217",
        "automationName": "UiAutomator2",
        "device": "Samsung Galaxy S21 Plus",
        "os_version": "11.0",
        "project": "Android Automation",
        "build": "DEX Android Smoke Execution",
        "name": "Samsung Galaxy S21 Plus Tests",
        "browserstack.networkLogs": true,
        "autoGrantPermissions": "true",
        "autoAcceptAlerts": "true",
        "acceptInsecureCerts": true,
        "acceptSslCert" : true
      },
      "browserstack-google-pixel-4": {
        "ss:remoteExecutor": "browserstack",
        "platformName": "Android",
        "app": "bs://fbac93a34795331e12e3949ac65d120e73422217",
        "automationName": "UiAutomator2",
        "device": "Google Pixel 4",
        "os_version": "10.0",
        "project": "Android Automation",
        "build": "DEX Android Smoke Execution",
        "name": "Google Pixel 4 Tests",
        "browserstack.networkLogs": true,
        "autoGrantPermissions": "true",
        "autoAcceptAlerts": "true",
        "acceptInsecureCerts": true,
        "acceptSslCert" : true
      },
      "browserstack-oneplus-7T": {
        "ss:remoteExecutor": "browserstack",
        "platformName": "Android",
        "app": "bs://fbac93a34795331e12e3949ac65d120e73422217",
        "automationName": "UiAutomator2",
        "device": "OnePlus 7T",
        "os_version": "10.0",
        "project": "Android Automation",
        "build": "DEX Android Smoke Execution",
        "name": "One plus 7T Tests",
        "browserstack.networkLogs": true,
        "autoGrantPermissions": "true",
        "autoAcceptAlerts": "true",
        "acceptInsecureCerts": true,
        "acceptSslCert" : true
      },
    }
  },
  "dashboard": {
    "url": "http://localhost:4000",
    "disabled": true
  }
}

现在,我们使用上面 json 中的 RandomProfile 来运行测试用例。代码实际上会根据浏览器堆栈中设备的可用性选择随机配置文件。我们还可以使用默认配置文件和多配置文件。

随机配置文件 -> 为选择执行的每个测试用例选择不同的设备

默认配置文件 -> 调用添加到所有测试用例配置文件中的单个设备

多配置文件 -> 在配置文件下提到的每个设备中运行每个测试用例。

并行运行 TestNG 时,驱动程序退出无法正常工作。完成 @Test 注释中的每个测试用例后调用 quit 方法,会终止并行执行期间所有正在运行的会话。在 @AfterMethod 中调用 quit 时观察到相同的行为。还尝试在 @AfterTest 和 @AfterClass 中调用 driver.quit 都不起作用,最终导致在 browserstack 中给出超时会话。

几个测试用例的示例: - 我已删除下面代码片段中的 driver.quit 语句,但已按照上述方式进行了尝试。

    public void likeOrUnlikeAContent() {
        Profile deviceProfile = null;
        try {
            deviceProfile = singletonUtils.getUnusedRandomProfile(profile);
            SlingshotReporter.log("********************Test Case: Like or Unlike a Content Navigating from Home Page********************");
            DriverFactory.get().build(CommonUtils.setRunTimeCapability(deviceProfile, runTimeCapabilityUtils.getRuntimeCapabilities()));
            mobileDriver = DriverFactory.getDriver();
            CommonUtils.setSessionName(mobileDriver, "Like or Unlike a Content Navigating from Home Page");
            commonUtils.loginToAppWithSSO(mobileDriver, "username1", EMPLOYEE);
            HomePageFunctions homePageFunctions = new HomePageFunctions(mobileDriver);
            homePageFunctions.navigateToAltimetrikTab(CommonUtils.ScrollDirection.HORIZONTAL,CommonUtils.Direction.RIGHT);
            homePageFunctions.clickOnAltiverseCard();
            CommonUtils.scrollIntoViewIDWithDirection(mobileDriver,CommonUtils.ScrollDirection.VERTICAL,UP,"likeContent");
            Assert.assertTrue(homePageFunctions.verifyLikeButtonDisplayed());
            homePageFunctions.verifyLikeCount();
            CommonUtils.closeApp(mobileDriver);
            CommonUtils.setStatusForTestCase(mobileDriver, "Passed", "Test Execution Completed");
            singletonUtils.reAssignUsedDevices(deviceProfile.getProfileName());
        } catch (Exception e) {
            SlingshotReporter.log("-----------------Test case failed due to below error-----------------");
            CommonUtils.setStatusForTestCase(mobileDriver, "Failed", e.getMessage());
            singletonUtils.reAssignUsedDevices(Objects.requireNonNull(deviceProfile).getProfileName());
            Assert.fail(e.getMessage());
        }
    }



    @Test(groups = {"Smoke1"}, priority = 2)
    public void commentAndReplyToCommentOnAContent() {
        Profile deviceProfile = null;
        try {
            deviceProfile = singletonUtils.getUnusedRandomProfile(profile);
            SlingshotReporter.log("********************Test Case: Comment and Reply to a comment on a Content Navigating from Home "
                + "Page********************");
            DriverFactory.get().build(CommonUtils.setRunTimeCapability(deviceProfile, runTimeCapabilityUtils.getRuntimeCapabilities()));
            mobileDriver = DriverFactory.getDriver();
            CommonUtils.setSessionName(mobileDriver, "Comment and Reply to a comment on a Content Navigating from Home Page");
            commonUtils.loginToAppWithSSO(mobileDriver, "username1", EMPLOYEE);
            HomePageFunctions homePageFunctions = new HomePageFunctions(mobileDriver);
            homePageFunctions.navigateToAltimetrikTab(CommonUtils.ScrollDirection.HORIZONTAL,CommonUtils.Direction.RIGHT);
            homePageFunctions.clickOnAltiverseCard();
            CommonUtils.scrollIntoViewIDWithDirection(mobileDriver,CommonUtils.ScrollDirection.VERTICAL,UP,"commentCnt");
            homePageFunctions.commentOnAContent();
            Assert.assertTrue(homePageFunctions.verifyCommentOrReplyPosted());
            homePageFunctions.replyToAComment();
            Assert.assertTrue(homePageFunctions.verifyCommentOrReplyPosted());
            homePageFunctions.exitFromCommentDetailPage();
            CommonUtils.closeApp(mobileDriver);
            CommonUtils.setStatusForTestCase(mobileDriver, "Passed", "Test Execution Completed");
            singletonUtils.reAssignUsedDevices(deviceProfile.getProfileName());
        } catch (Exception e) {
            SlingshotReporter.log("-----------------Test case failed due to below error-----------------");
            CommonUtils.setStatusForTestCase(mobileDriver, "Failed", e.getMessage());
            singletonUtils.reAssignUsedDevices(Objects.requireNonNull(deviceProfile).getProfileName());
            Assert.fail(e.getMessage());
        }
    }

Testng Xml 看起来像这样:

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

<suite name="Mobile Automation" verbose="1" thread-count="3" parallel="methods">
    <listeners>
        <listener class-name="com.altimetrik.qe.slingshot.reporter.SlingshotTestNGReporter"/>
        <listener class-name="com.altimetrik.qe.slingshot.testng.listeners.NeedsDriverListener"/>
    </listeners>

    <test name="DEX UI Tests">
        <classes>
            <class name="com.altimetrik.pp.dexapp.mobileAutomation.SmokeTests"/>
            <class name="com.altimetrik.pp.dexapp.mobileAutomation.SuccessStoryTests"/>
            <class name="com.altimetrik.pp.dexapp.mobileAutomation.EmployeeLandingTest"/>
            <class name="com.altimetrik.pp.dexapp.mobileAutomation.InnovateAndInspireTest"/>
            <class name="com.altimetrik.pp.dexapp.mobileAutomation.TweetTests"/>
            <class name="com.altimetrik.pp.dexapp.mobileAutomation.ContributorTests"/>
            <class name="com.altimetrik.pp.dexapp.mobileAutomation.ReviewerTests"/>
            <class name="com.altimetrik.pp.dexapp.mobileAutomation.CandidateLandingTest"/>
            <class name="com.altimetrik.pp.dexapp.mobileAutomation.JobOpportunitiesTests"/>
            <class name="com.altimetrik.pp.dexapp.mobileAutomation.JobDetailsPageTests"/>
            <class name="com.altimetrik.pp.dexapp.mobileAutomation.MySpaceTests"/>
            <class name="com.altimetrik.pp.dexapp.mobileAutomation.DiscoverDexTest"/>

        </classes>
    </test>
</suite>

请帮助我解决这个问题,尝试了互联网上提供的所有解决方案,但没有任何效果。

java testng appium browserstack browserstack-app-automate
1个回答
0
投票

使用 BeforeTest 和 AfterTest 注释与 getdriver() 方法从并行的驱动程序池中获取当前驱动程序。

AfterTest 仅包含 getdriver().quit();

© www.soinside.com 2019 - 2024. All rights reserved.