当前位置:   article > 正文

Java+playwright+testNG实现UI自动化测试

Java+playwright+testNG实现UI自动化测试

今天来讲讲使用Java结合最新的playwright来做UI自动化测试

目前网上大部分都是关于使用Python做自动化的教程,Java的比较少一些,但是我认为使用Java做自动化还是有优点的,性能就好一点,当然大家根据实际需求来。

一、 普通UI测试

  1. 创建 Maven 项目
    在你选择的 IDE(如 IntelliJ IDEA 或 Eclipse)中创建一个新的 Maven 项目。

  2. **添加依赖到 pom.xml**:(我使用的jdk1.8) 打开 pom.xml 文件并添加以下依赖:

    1. <dependencies>
    2. <!-- Playwright -->
    3. <dependency>
    4. <groupId>com.microsoft.playwright</groupId>
    5. <artifactId>playwright</artifactId>
    6. <version>1.41.0</version>
    7. <scope>test</scope>
    8. </dependency>
    9. <!-- TestNG -->
    10. <dependency>
    11. <groupId>org.testng</groupId>
    12. <artifactId>testng</artifactId>
    13. <version>7.4.0</version>
    14. <scope>test</scope>
    15. </dependency>
    16. </dependencies>

示例测试用例

接下来,编写一个简单的测试用例,使用 Playwright 打开 Google 页面,并验证页面标题。

  1. 创建测试类
    在你的 Maven 项目中,创建一个新的测试类 BaiduTest.java

    1. import com.microsoft.playwright.*;
    2. import org.testng.Assert;
    3. import org.testng.annotations.*;
    4. public class BaiduTest {
    5. Playwright playwright;
    6. Browser browser;
    7. Page page;
    8. @BeforeClass
    9. public void setUp() {
    10. playwright = Playwright.create();
    11. BrowserType.LaunchOptions options = new BrowserType.LaunchOptions();
    12. options.headless = false; // 设置为有头浏览器
    13. browser = playwright.chromium().launch(options);
    14. page = browser.newPage();
    15. }
    16. @Test
    17. public void testBaiduHomePage() {
    18. page.navigate("https://www.baidu.com");
    19. String title = page.title();
    20. Assert.assertEquals(title, "百度一下,你就知道");
    21. }
    22. @AfterClass
    23. public void tearDown() {
    24. browser.close();
    25. playwright.close();
    26. }
    27. }

使用 TestNG 管理测试用例

  • 使用 @Test 注解:这标记了一个方法作为测试方法。

  • 使用 @BeforeClass 和 @AfterClass 注解:分别用于在测试类中所有测试方法之前和之后执行代码。

  • 断言:使用 Assert 类来进行断言,验证测试结果是否符合预期。

生成测试报告

  • 在 pom.xml 中配置 TestNG 生成测试报告的能力。

    1. <build>
    2. <plugins>
    3. <plugin>
    4. <groupId>org.apache.maven.plugins</groupId>
    5. <artifactId>maven-surefire-plugin</artifactId>
    6. <version>3.0.0-M5</version>
    7. <configuration>
    8. <suiteXmlFiles>
    9. <suiteXmlFile>testng.xml</suiteXmlFile>
    10. </suiteXmlFiles>
    11. </configuration>
    12. </plugin>
    13. </plugins>
    14. </build>
  • 创建 testng.xml 文件来管理测试套件:

    1. <!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
    2. <suite name="Sample Suite">
    3. <test name="Baidu Tests">
    4. <classes>
    5. <class name="BaiduTest"/>
    6. </classes>
    7. </test>
    8. </suite>

生成的报告会呈现在target/surefire-reports 目录下生成 XML 格式的测试报告

集成Allure

如果要生成更详细的HTML测试报告,可以集成allure

要集成 Allure,您需要添加相关依赖和插件到您的 POM 文件中:

  1. <dependency>
  2. <groupId>io.qameta.allure</groupId>
  3. <artifactId>allure-testng</artifactId>
  4. <version>2.13.8</version>
  5. <scope>test</scope>
  6. </dependency>

并配置 Allure Maven 插件:

  1. <plugin>
  2. <groupId>io.qameta.allure</groupId>
  3. <artifactId>allure-maven</artifactId>
  4. <version>2.10.0</version>
  5. <configuration>
  6. <reportVersion>2.13.8</reportVersion>
  7. <reportingOutputDirectory>${project.build.directory}/allure-results</reportingOutputDirectory>
  8. </configuration>
  9. <executions>
  10. <execution>
  11. <phase>post-integration-test</phase>
  12. <goals>
  13. <goal>report</goal>
  14. </goals>
  15. </execution>
  16. </executions>
  17. </plugin>

然后我们需要在src/test/resources目录下添加allure.properties

allure.results.directory=target/allure-results

添加这个文件主要让生成的Allure结果放到target目录里面,不然就直接放在根目录,当然你不介意的话

运行和生成报告

可以直接运行测试文件,也可以通过mvn test执行测试,然后就能在target目录下看到Allure_results的测试结果数据,全部为json格式文件,接下来使用allure generate <results dir> -o <report dir> 在report dir 目录下生成Allure测试报告,打开index.html文件就能查看测试结果

我直接使用allure generate .target/allure-results 这样就会根据里面的结果生成报告了,同样在Jenkins上面配置Allure的时候要注意results和report的区别,配置正确

二、数据驱动测试

1. 组织测试数据

为了处理多个参数和多组数据,testNG的数据提供者(@DataProvider)的二维数组会是你的核心工具。数据数组的每个元素都可以包含多种数据,包括不同的定位方式、输入值和其他参数。

  1. import org.testng.annotations.DataProvider;
  2. public class TestDataProvider {
  3. @DataProvider(name = "complexData")
  4. public Object[][] createComplexData() {
  5. return new Object[][] {
  6. { "Case 1", "https://example.com/login", "username1", "password1", "login-button-id-1" },
  7. { "Case 2", "https://example.com/login", "username2", "password2", "login-button-id-2" },
  8. { "Case 3", "https://example.com/signup", "newuser1", "newpass1", "signup-button-id" }
  9. };
  10. }
  11. }

在这个示例中,我们有一个数据提供者 complexData,包含了多个参数,包括测试用例名称、网址、用户名、密码和按钮 ID。

2. 链接数据提供者到测试方法

现在,我们需要一个测试类,它使用上面定义的数据提供者来获取不同的数据集,并应用于测试方法。

  1. import com.microsoft.playwright.*;
  2. import org.testng.Assert;
  3. import org.testng.annotations.*;
  4. public class ComplexTest {
  5. Playwright playwright;
  6. Browser browser;
  7. Page page;
  8. @BeforeClass
  9. public void setUp() {
  10. playwright = Playwright.create();
  11. BrowserType.LaunchOptions options = new BrowserType.LaunchOptions();
  12. options.headless = false; // 设置为 true 运行无头浏览器
  13. browser = playwright.chromium().launch(options);
  14. page = browser.newPage();
  15. }
  16. @Test(dataProvider = "complexData", dataProviderClass = TestDataProvider.class)
  17. public void testComplexScenarios(String testCaseName, String url, String username, String password, String buttonId) {
  18. page.navigate(url);
  19. // 输入用户名和密码
  20. page.fill("input[name='username']", username);
  21. page.fill("input[name='password']", password);
  22. // 点击按钮
  23. page.click("#" + buttonId);
  24. // 检查页面是否成功登录/注册
  25. boolean isLoginSuccess = page.locator("#success-message").isVisible();
  26. Assert.assertTrue(isLoginSuccess, testCaseName + " - 登录/注册失败");
  27. }
  28. @AfterClass
  29. public void tearDown() {
  30. browser.close();
  31. playwright.close();
  32. }
  33. }

在这个示例中,测试方法 testComplexScenarios 接收多个参数。这使得我们可以根据不同的数据集运行相同的测试逻辑。

3. 在报告中显示测试用例名称和具体步骤

为了在报告中显示测试用例名称和步骤结果,可以通过以下方式实现:

  • 使用 TestNG Reporter:TestNG 提供了报告功能,测试用例可以通过 Reporter.log() 输出特定信息,这样在最终报告中会显示这些信息。

  • 使用 TestNG 监听器:监听器可以帮助你更好地跟踪测试结果,并自定义报告输出。

示例代码展示了如何记录测试步骤以及在报告中显示测试用例名称:

  1. import com.microsoft.playwright.*;
  2. import org.testng.Assert;
  3. import org.testng.Reporter;
  4. import org.testng.annotations.*;
  5. public class DetailedReportTest {
  6. Playwright playwright;
  7. Browser browser;
  8. Page page;
  9. @BeforeClass
  10. public void setUp() {
  11. playwright = Playwright.create();
  12. BrowserType.LaunchOptions options = new BrowserType.LaunchOptions();
  13. options.headless = false; // 设置为 true 运行无头浏览器
  14. browser = playwright.chromium().launch(options);
  15. page = browser.newPage();
  16. }
  17. @Test(dataProvider = "complexData", dataProviderClass = TestDataProvider.class)
  18. public void testWithReport(String testCaseName, String url, String username, String password, String buttonId) {
  19. Reporter.log("开始执行用例:" + testCaseName, true);
  20. page.navigate(url);
  21. Reporter.log("导航至:" + url, true);
  22. // 输入用户名和密码
  23. page.fill("input[name='username']", username);
  24. Reporter.log("填入用户名:" + username, true);
  25. page.fill("input[name='password']", password);
  26. Reporter.log("填入密码", true);
  27. // 点击按钮
  28. page.click("#" + buttonId);
  29. Reporter.log("点击按钮:" + buttonId, true);
  30. // 检查页面是否成功
  31. boolean isSuccess = page.locator("#success-message").isVisible();
  32. Assert.assertTrue(isSuccess, testCaseName + " - 操作失败");
  33. Reporter.log("用例:" + testCaseName + " 执行成功", true);
  34. }
  35. @AfterClass
  36. public void tearDown() {
  37. browser.close();
  38. playwright.close();
  39. }
  40. }

这个例子通过 Reporter.log() 来记录测试用例的步骤和结果,在生成的 TestNG 报告中,你可以看到这些日志信息以及测试用例名称。

当然如果你想要在Allure里面展示详细步骤,比如某个按钮,或者某个节点是否成功,你可以添加Allure.step(<string>)

  1. import com.microsoft.playwright.*;
  2. import com.microsoft.playwright.options.AriaRole;
  3. import org.testng.Assert;
  4. import org.testng.annotations.*;
  5. import io.qameta.allure.*;
  6. public class LoginTest {
  7. Playwright playwright;
  8. Browser browser;
  9. Page page;
  10. @BeforeClass
  11. public void setUp() {
  12. playwright = Playwright.create();
  13. BrowserType.LaunchOptions options = new BrowserType.LaunchOptions();
  14. options.headless = false; // 设置为运行有头浏览器
  15. browser = playwright.chromium().launch(options);
  16. page = browser.newPage();
  17. }
  18. @Feature("登录功能模块")
  19. @Test(dataProvider = "loginData",dataProviderClass = TestDataProvider.class)
  20. public void testLogin(String testCaseName,String username, String password, boolean isExpectedAlert ,String expectedMessage, String expectedUrl) {
  21. boolean[] alertPresent = {false};
  22. String [] alertMessage = {""};
  23. // page.onDialog(dialog -> {
  24. // alertPresent[0] = true;
  25. // alertMessage[0] =dialog.message();
  26. // });
  27. page.navigate("https://yourexample.com/mangement/#/login");
  28. Allure.step("进入登录页成功");
  29. page.locator("input[type=\"text\"]").fill(username);
  30. Allure.step(testCaseName+"输入用户名成功");
  31. page.fill("#inputPwd", password);
  32. Allure.step(testCaseName+"输入密码成功!");
  33. page.getByText("登录", new Page.GetByTextOptions().setExact(true)).click();
  34. Allure.step(testCaseName+"点击登录按钮成功!");
  35. String newUrl = page.url();
  36. if(!testCaseName.equals("Case 1")) {
  37. Locator toast = page.getByRole(AriaRole.ALERT);
  38. toast.waitFor(new Locator.WaitForOptions().setTimeout(1000));//最多等待五秒
  39. if (toast.isVisible()) {
  40. alertPresent[0] = true;
  41. alertMessage[0] = toast.textContent();
  42. }
  43. }else {
  44. page.waitForTimeout(2000);
  45. newUrl = page.url();
  46. Allure.step(testCaseName+"登录成功!");
  47. }
  48. Assert.assertEquals(alertPresent[0],isExpectedAlert, testCaseName + "failed");
  49. Assert.assertEquals(alertMessage[0],expectedMessage,testCaseName + "failed");
  50. Assert.assertEquals(newUrl,expectedUrl,testCaseName + "failed");
  51. }
  52. @AfterClass
  53. public void tearDown() {
  54. browser.close();
  55. playwright.close();
  56. }
  57. }

如果熟悉使用Python进行UI测试用过Allure的应该都清楚

这里简单回顾一下Allure常用的接口,装饰器(更多的大家可以去官网查看)

  1. @Feature

  • 意义:用于标注主要的功能模块。

  • 用途:帮助组织和分类测试用例,使其按照功能模块进行归类。通过查看报告中的Feature,可以快速地了解哪些功能模块被测试了。

@Story

  • 意义:用于标注功能模块下的分支功能或具体场景。

  • 用途:进一步细分功能模块,描述更具体的功能点或业务场景。通过Story,可以更详细地了解每个功能模块下的具体测试内容。

@Title

  • 意义:用于为测试用例或测试步骤提供标题。

  • 用途:使得每个测试用例或步骤在报告中都有一个明确的、描述性的标题,方便用户快速识别和理解。

三、测试数据与代码分离进行数据驱动

当然,让我们继续讨论如何使用 CSV 文件来进行数据驱动的测试。

添加 Maven 依赖

首先,在你的 Maven pom.xml 文件中添加 Apache Commons CSV 或任何其他 CSV 解析库的依赖。这里我们使用 Apache Commons CSV。

  1. <dependency>
  2. <groupId>org.apache.commons</groupId>
  3. <artifactId>commons-csv</artifactId>
  4. <version>1.8</version>
  5. </dependency>

读取 CSV 文件

创建一个 @DataProvider 方法来读取 CSV 文件,并返回测试用例所需的数据。以下是一个例子,演示如何解析 CSV 文件并构造对象数组。

  1. import org.apache.commons.csv.*;
  2. import org.testng.annotations.DataProvider;
  3. import java.io.FileReader;
  4. import java.io.IOException;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. public class CSVDataProviders {
  8. @DataProvider(name = "csvTestData")
  9. public static Object[][] readCsvData() throws IOException {
  10. List<Object[]> testCases = new ArrayList<>();
  11. try (CSVParser parser = new CSVParser(new FileReader("path/to/testdata.csv"), CSVFormat.DEFAULT.withHeader())) {
  12. for (CSVRecord record : parser) {
  13. String testCaseName = record.get("TestCaseName");
  14. String inputData = record.get("InputData");
  15. String locatorId = record.get("LocatorId");
  16. String expectedOutcome = record.get("ExpectedOutcome");
  17. testCases.add(new Object[]{testCaseName, inputData, locatorId, expectedOutcome});
  18. }
  19. }
  20. return testCases.toArray(new Object[0][]);
  21. }
  22. }

在这个例子中,我们假设 CSV 文件有列标题 TestCaseName, InputData, LocatorId, 和 ExpectedOutcomeCSVParser 用于读取 CSV 文件,然后每条记录被转换成一个对象数组并添加到列表中。

使用数据提供者

接下来,在你的测试类中使用这个 @DataProvider

  1. import com.microsoft.playwright.*;
  2. import org.testng.Assert;
  3. import org.testng.annotations.*;
  4. public class DataDrivenTests {
  5. Playwright playwright;
  6. Browser browser;
  7. Page page;
  8. @BeforeClass
  9. public void setUp() {
  10. playwright = Playwright.create();
  11. browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setHeadless(false));
  12. page = browser.newPage();
  13. }
  14. @Test(dataProvider = "csvTestData", dataProviderClass = CSVDataProviders.class)
  15. public void testWithCsvData(String testCaseName, String inputData, String locatorId, String expectedOutcome) {
  16. page.navigate(inputData); // Assuming inputData is a URL for simplicity
  17. page.click("#" + locatorId);
  18. Assert.assertTrue(page.isVisible(expectedOutcome), "Test failed for: " + testCaseName);
  19. }
  20. @AfterClass
  21. public void tearDown() {
  22. browser.close();
  23. playwright.close();
  24. }
  25. }

在这个测试方法中,通过 @DataProvider 注解指定数据来源为 csvTestData,它会自动接收 CSV 文件中的每行数据作为参数。

好了本次分享就到此结束了,欢迎大家一起讨论学习

附官网参考地址:

1、playwright的Java版本相关接口:https://playwright.dev/java/docs/api/class-playwrighthttps://playwright.dev/java/docs/api/class-playwright

2、Allure与testNG相关的接口:

https://allurereport.org/docs/testng/

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/512909
推荐阅读
相关标签
  

闽ICP备14008679号