质量与效率:如何使用AI工具进行自动化REST API测试

2024-12-13   出处: stackspot.com  作/译者:Álefe Cardozo Silva/Ares

人工智能(AI)已经改变了自动化Rest API测试的设计和执行方式。通过应用机器学习(ML)和自然语言处理技术,AI可以分析庞大的数据集和API规范,自动生成全面且相关的测试用例。这加快了测试过程,并通过识别未被探索的质量领域来提高测试的有效性。

在本文中,您将学习如何使用StackSpot AI的情境化代码助手来创建自动化Rest API测试,从而简化自动化项目的开发和编码。

了解StackSpot AI

StackSpot是一个开发平台,它通过集中和重用技术标准、通过AI生成高度情境化的代码,使工程团队能够快速实现系统并更快地交付价值。它分为三个产品:StackSpot EDP、StackSpot云服务和StackSpot AI(后者是本文的重点)。

StackSpot AI可以根据您的上下文、知识来源和技术决策来生成更果断、高质量的建议。此外,AI助手还能够创建快速命令来自动化重复性任务。告别通用建议,采用超情境化的代码生成!

最好的部分是:StackSpot AI提供了一项免费+增值服务的计划。您可以使用网页版或下载IDE扩展(IntelliJ或Visual Code)来开始使用!

自动化Rest API测试:使用StackSpot AI的第一步

在本文中,我们将使用Java、Rest Assured、Cucumber和Maven创建一个Rest API自动化测试项目。

我们将使用个人账号(GitHub)登录StackSpot AI门户,下载AI情境化代码助手插件,并添加开发工具(IntelliJ)。

AI情境化代码向导将根据问题和上下文帮助生成初始项目代码,并建议添加到项目中的代码。

最后,我们将添加新的测试场景并重构代码,使我们的项目对软件社区来说更加全面且可重用。

那么,让我们开始吧:

登录StackSpot AI登录页面。这一步需要先在GitHub上创建一个账号。

在StackSpot AI环境中,您将会看到这个初始屏幕:

安装步骤

为了进行安装,请遵循以下推荐的自动化测试构建指南:

集成开发环境(IDE)

  • IntelliJ(版本2024.1 / 241.14494.240)

IDE插件

  • StackSpot AI(版本1.5.4)
  • Cucumber-Java(版本241.14494.158)
  • Gherkin(版本241.14494.150)

编程语言

  • Java(版本11.0.20 / 2023年7月18日发布的长期支持版本)

依赖项

  • Maven(版本3.9.5)

Maven库

  • Rest Assured(版本4.3.3)
  • Cucumber-Java(版本6.10.4)
  • Cucumber-JUnit(版本6.10.4)
  • JUnit(版本4.13.2)
  • JavaFaker(版本1.02)

请按照上述工具和版本号进行安装,以确保自动化测试项目的顺利构建和运行。

创建自动化Rest API测试项目

要创建并运行Rest API自动化测试项目,请遵循以下指南。

1 – 为自动化Rest API测试创建一个新项目

在完成安装(上一步)后,只需:

  • 打开IntelliJ IDE。
  • 转到“File”菜单并选择“New -> Project”。
  • 点击“New Project”并选择“Java”选项。
  • 在“Name”字段中输入项目的名称。
  • 点击“Build System”并选择“Maven”。

就这样!Rest API自动化测试项目已经创建完成。

2 – 使用StackSpot AI进行身份验证

在IntelliJ IDE已经打开且项目已经创建(上一步)的情况下,只需:

  • 进入StackSpot AI插件。
  • 在GitHub账号的电子邮件字段中填写信息。
  • 点击“Continue with GitHub(使用GitHub继续)”按钮。
  • 在弹出的屏幕中点击“Yes”按钮。收到确认后,返回IntelliJ。

就这样!身份验证完成后,您就可以使用StackSpot AI了。

3 – 生成代码

在IntelliJ IDE中已经创建了项目并且已经登录到StackSpot AI(上一步)之后,只需:

  • 进入StackSpot AI插件。
  • 向AI提问:使用Java 11、Maven、Rest Assured和Cucumber生成一个Rest API POST测试的示例。在本文中,您学习如何在StackSpot AI中创建一个好的提示。
  • 复制生成的代码,并为项目创建建议的文件夹/文件。

就这样!代码已经生成,我们可以将其添加到创建的项目中以供使用。

将StackSpot AI生成的代码添加到项目中

让我们按照以下步骤将生成的代码添加到自动化Rest API测试项目中:

  1. 使用Maven配置项目

在项目的pom.xml文件中,为Cucumber、JUnit和RestAssured添加以下依赖项。

pom.xml

<dependencies>

       <!-- RestAssured -->

       <dependency>

           <groupId>io.rest-assured</groupId>

           <artifactId>rest-assured</artifactId>

           <version>4.3.3</version>

           <scope>test</scope>

       </dependency>

       <!-- Cucumber -->

       <dependency>

           <groupId>io.cucumber</groupId>

           <artifactId>cucumber-java</artifactId>

           <version>6.10.4</version>

           <scope>test</scope>

       </dependency>

       <dependency>

           <groupId>io.cucumber</groupId>

           <artifactId>cucumber-junit</artifactId>

           <version>6.10.4</version>

           <scope>test</scope>

       </dependency>

       <!-- JUnit -->

       <dependency>

           <groupId>junit</groupId>

           <artifactId>junit</artifactId>

           <version>4.13.2</version>

           <scope>test</scope>

       </dependency>

   </dependencies>
  1. 使用Cucumber创建测试场景

为Cucumber创建一个功能文件。

src/test/resources/features/postFeature.feature

Feature: Test POST API endpoint

 Scenario: Post new data to the API

   Given I set POST API endpoint

   When I send POST HTTP request

   Then I receive valid HTTP response code 201
  1. 使用RestAssured实现测试

现在,使用RestAssured实现测试步骤。为您的Cucumber场景创建一个对应的测试类。

src/test/java/stepDefinitions/PostApiSteps.java

package com.example.steps;

import io.cucumber.java.en.Given;

import io.cucumber.java.en.When;

import io.cucumber.java.en.Then;

import io.restassured.RestAssured;

import io.restassured.response.Response;

import static org.junit.Assert.*;

public class PostApiSteps {

   private Response response;

   @Given("I set POST API endpoint")

   public void i_set_post_api_endpoint() {

       RestAssured.baseURI = "http://yourapi.com/api";

   }

   @When("I send POST HTTP request")

   public void i_send_post_http_request() {

       response = RestAssured.given().contentType("application/json")

               .body("{\"key\": \"value\"}")

               .when().post("/endpoint");

   }

   @Then("I receive valid HTTP response code 201")

   public void i_receive_valid_http_response_code_201() {

       assertEquals(201, response.getStatusCode());

   }

}
  1. 使用Cucumber设置运行器

创建一个类来运行Cucumber测试。

src/test/java/cucumberOptions/TestRunner.java

package com.example;

import io.cucumber.junit.Cucumber;

import io.cucumber.junit.CucumberOptions;

import org.junit.runner.RunWith;

@RunWith(Cucumber.class)

@CucumberOptions(

       features = "src/test/resources/features",

       glue = "com.example.steps",

       plugin = {"pretty", "html:target/cucumber-reports.html"},

       monochrome = true

)

public class TestRunner {

}

运行自动化Rest API测试

要运行自动化Rest API测试,您可以使用Maven命令。

mvn test

此时,您已经拥有了一个集成Rest API自动化测试项目的代码和结构的示例,该项目会发出POST请求,接收响应,并验证状态码。现在,您可以根据需要调整已生成的内容。

接下来,我们需要改进代码并整理项目,添加GET请求,接收响应,并验证数据。

为此,请使用ServeRest API来:

  • 注册新用户(POST User)
  • 查询已注册用户(GET User)
  • 查询未注册用户(尝试GET不存在的User)

以下将基于要验证的场景展示所做的调整。

重构项目以使实现更加简洁和组织有序

为了进行重构,请进行以下更改:

1 – 使用Maven调整项目

调整pom.xml文件以包含实现所需的依赖项。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"

        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

   <modelVersion>4.0.0</modelVersion>

   <groupId>org.example</groupId>

   <artifactId>StackSpot-api-integration-tests</artifactId>

   <version>1.0-SNAPSHOT</version>

   <properties>

       <maven.compiler.source>11</maven.compiler.source>

       <maven.compiler.target>11</maven.compiler.target>

       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

   </properties>

   <dependencies>

       <!-- RestAssured -->

       <dependency>

           <groupId>io.rest-assured</groupId>

           <artifactId>rest-assured</artifactId>

           <version>4.3.3</version>

           <scope>test</scope>

       </dependency>

       <!-- Cucumber -->

       <dependency>

           <groupId>io.cucumber</groupId>

           <artifactId>cucumber-java</artifactId>

           <version>6.10.4</version>

           <scope>test</scope>

       </dependency>

       <dependency>

           <groupId>io.cucumber</groupId>

           <artifactId>cucumber-junit</artifactId>

           <version>6.10.4</version>

           <scope>test</scope>

       </dependency>

       <!-- JUnit -->

       <dependency>

           <groupId>junit</groupId>

           <artifactId>junit</artifactId>

           <version>4.13.2</version>

           <scope>test</scope>

       </dependency>

       <!-- Java Faker -->

       <dependency>

           <groupId>com.GitHub.javafaker</groupId>

           <artifactId>javafaker</artifactId>

           <version>1.0.2</version>

       </dependency>

   </dependencies>

</project>

2 – 使用Cucumber调整测试场景

调整resources/features/user.feature文件,以包含实现所需的测试场景。

src/test/resources/features/user.feature

Feature: User API

  @all @user-register

  Scenario: Should register a new user

    Given I have the data to register a new user

    When I make a POST request to the URL "https://serverest.dev/usuarios"

    Then The response status code should be 201 to a new user

  @all @user-not-registered

  Scenario: Should query registered user

    Given I do not have a registered user but wish to register

    When I make a GET request to the URL "https://serverest.dev/usuarios"

    Then The response status code should be 200 to registered user

  @all @user-non-existent

  Scenario: Should query non-registered user

    Given I do not have a registered user "XPTO"

    When I make a GET request to the URL "https://serverest.dev/usuarios"

    Then The response status code should be 400 to non-registered user

3 – 使用RestAssured调整测试步骤

调整stepDefinitions/UserSteps.java文件,以包含用于注册新用户、查询已注册用户和查询未注册用户的特性测试的实现。

src/test/java/stepDefinitions/UserSteps.java

package stepDefinitions;

import io.cucumber.java.en.Given;

import io.cucumber.java.en.Then;

import io.cucumber.java.en.When;

import io.restassured.response.Response;

import services.UserService;

public class UserSteps {

    private Response response;

    private String body;

    private String idUser;

    private final UserService userService = new UserService();

    @Given("I have the data to register a new user")

    public void i_have_the_data_to_register_a_new_user() {

        body = userService.generateUserData();

    }

    @When("I make a POST request to the URL {string}")

    public void i_make_a_post_request_to_the_url(String url) {

        response = userService.createNewUser(url, body);

    }

    @Then("The response status code should be {int} to a new user")

    public void the_response_status_code_should_be_to_a_new_user(int statusCode) {

        idUser = userService.validateRegisteredUserData(response, statusCode);

    }

    @Given("I do not have a registered user but wish to register")

    public void i_do_not_have_a_registered_user_but_wish_to_register() {

        idUser = userService.checkExistingUser(null);

    }

    @When("I make a GET request to the URL {string}")

    public void i_make_a_get_request_to_the_url(String url) {

        response = userService.queryUser(url, idUser);

    }

    @Then("The response status code should be {int} to registered user")

    public void the_response_status_code_should_be_to_registered_user(int statusCode) {

        userService.validateQueriedUserData(response, idUser, statusCode);

    }

    @Given("I do not have a registered user {string}")

    public void i_do_not_have_a_registered_user(String newUserId) {

        idUser = newUserId;

    }

    @When("I make an attempt to GET request to the URL {string}")

    public void i_make_an_attempt_to_get_request_to_the_url(String url) {

        response = userService.queryUser(url, idUser);

    }

    @Then("The response status code should be {int} to non-registered user")

    public void the_response_status_code_should_be_to_non_registered_user(int statusCode) {

        userService.validateNonRegisteredUserData(response, statusCode);

    }

}

4 – 创建DTO结构以操作请求数据

创建dto/UserDto文件,用于创建get/set方法以及访问对象/类的属性。

src/test/java/dto/UserDto.java

package dto;

public class UserDto {

    private String name;

    private String email;

    private String password;

    private String admin;

    // Getter and Setter for name

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    // Getter and Setter for email

    public String getEmail() {

        return email;

    }

    public void setEmail(String email) {

        this.email = email;

    }

    // Getter and Setter for password

    public String getPassword() {

        return password;

    }

    public void setPassword(String password) {

        this.password = password;

    }

    // Getter and Setter for admin

    public String getAdmin() {

        return admin;

    }

    public void setAdmin(String admin) {

        this.admin = admin;

    }

}

5 – 创建Service结构以设置请求

创建service/UserService.java文件,用于设置要发出的请求。

src/test/java/service/UserService.java

package services;

import com.github.javafaker.Faker;

import dto.UserDto;

import io.restassured.path.json.JsonPath;

import io.restassured.response.Response;

import static io.restassured.RestAssured.given;

import static org.junit.Assert.assertEquals;

public class UserService {

    private Response response;

    private String requestBody;

    private String userId;

    private UserDto userDto;

    private Faker faker;

    private String newUserId;

    public String generateUserData(){

        faker = new Faker();

        userDto = new UserDto();

        userDto.setName(faker.name().name());

        userDto.setEmail(faker.internet().emailAddress());

        userDto.setPassword("123456");

        userDto.setAdmin("true");

        requestBody = "{\n" +

                "  \"nome\": \""+userDto.getName()+"\",\n" +

                "  \"email\": \""+userDto.getEmail()+"\",\n" +

                "  \"password\": \""+ userDto.getPassword()+"\",\n" +

                "  \"administrador\": \""+ userDto.getAdmin()+"\"\n" +

                "}";

        return requestBody;

    }

    public Response createNewUser(String url, String requestBody){

        response = given()

                .header("Content-type", "application/json")

                .and()

                .log().all()

                .body(requestBody)

                .when()

                .post(url)

                .then()

                .log().all()

                .extract().response();

        return response;

    }

    public String validateRegisteredUserData(Response response, int statusCode){

        JsonPath jsonPathEvaluator = response.jsonPath();

        assertEquals(statusCode, response.getStatusCode());

        userId = jsonPathEvaluator.get("_id");

        return userId;

    }

    public String checkExistingUser(String userId){

        String newBody;

        Response newResponse;

        if (userId == null){

            newBody = generateUserData();

            newResponse = createNewUser("https://serverest.dev/usuarios",newBody);

            newUserId = validateRegisteredUserData(newResponse, 201);

        }

        else{

            newUserId = userId;

        }

        return newUserId;

    }

    public Response queryUser(String url, String newUserId){

        response = given()

                .header("Content-type", "application/json")

                .and()

                .log().all()

                .when()

                .get(url + "/" + newUserId)

                .then()

                .log().all()

                .extract().response();

        return response;

    }

    public void validateQueriedUserData(Response response, String newId, int statusCode){

        JsonPath jsonPathEvaluator = response.jsonPath();

        if (newUserId.equals(newId)) {

            assertEquals(statusCode, response.getStatusCode());

            assertEquals(newUserId, jsonPathEvaluator.get("_id"));

        }

        else {

            assertEquals(userDto.getName(), jsonPathEvaluator.get("name"));

            assertEquals(userDto.getEmail(), jsonPathEvaluator.get("email"));

            assertEquals(userDto.getPassword(), jsonPathEvaluator.get("password"));

            assertEquals(userDto.getAdmin(), jsonPathEvaluator.get("admin"));

            assertEquals(statusCode, response.getStatusCode());

            assertEquals(userId, jsonPathEvaluator.get("_id"));

        }

    }

    public void validateNonRegisteredUserData(Response response, int statusCode){

        assertEquals(statusCode, response.getStatusCode());

    }

}

重构后运行测试

要运行测试,您可以使用Maven命令。

mvn test

就这样!调整后的项目已成功执行。在StackSpot AI的帮助下,场景编写更加高效,促进了代码重用,并简化了自动化Rest API测试。

结论

本文展示了在自动化Rest API测试过程中采用像StackSpot AI这样的情境化人工智能工具的优势。通过整合合适的人工智能工具,整个软件开发周期的速度和效率都得到了提升。在这个场景下,软件质量流程也从新功能中获得了重大收益。

借助StackSpot AI,我们可以根据自己的标准和知识来源采纳果断的建议。这为他们的自动化Rest API测试和QA流程带来了前所未有的效率、可靠性和创新。


声明:本文为本站编辑转载,文章版权归原作者所有。文章内容为作者个人观点,本站只提供转载参考(依行业惯例严格标明出处和作译者),目的在于传递更多专业信息,普惠测试相关从业者,开源分享,推动行业交流和进步。 如涉及作品内容、版权和其它问题,请原作者及时与本站联系(QQ:1017718740),我们将第一时间进行处理。本站拥有对此声明的最终解释权!欢迎大家通过新浪微博(@测试窝)或微信公众号(测试窝)关注我们,与我们的编辑和其他窝友交流。
28° /288 人阅读/0 条评论 发表评论

登录 后发表评论
最新文章