当前位置: 首页 > 知识库问答 >
问题:

无法在登录后验证状态代码,也无法继续使用junit中的其他功能

艾泽语
2023-03-14

我正在尝试使用凭据登录网站,并尝试执行其他操作,例如新的POST调用。

@Test 
  public void test02CheckingAccount() { 
        model.setUsername(username);
        model.setPassword(password);
      SerenityRest.given()
         .param("username", model.getUsername())
         .param("password",  model.getPassword())
         .when().post("/somewebsite/login.htm");          
      expect().statusCode(302)
      .given()
      .param("customerId", 11111)
      .param("accountType", 0)
      .param("accountId", 12345)
      .when().post("/somewebsite/services_proxy/module/")
      .then()
      .log().all()
      .statusCode(200);

但我得到的断言是错误的,预期失败了。预期状态代码

但是如果我尝试在 expect().statusCode(302) 之后删除代码,它工作正常。

 @Test 
  public void test02CheckingAccount() { 
        model.setUsername(username);
        model.setPassword(password);
      SerenityRest.given()
         .param("username", model.getUsername())
         .param("password",  model.getPassword())
         .when().post("/somewebsite/login.htm");          
      expect().statusCode(302);

我看过其他帖子并做完全相同的事情,但这不起作用。

参考:REST有保证和多个员额

共有1个答案

韩寒
2023-03-14

你好:)这可能会有帮助

我在IntelliJ Maven项目上放心地使用TestNG,并可以展示我下面构建框架的一部分。我希望它能对你在使用涉及可重用规范的模板时有所帮助,比如状态验证和由于TestNG DataProvider对JSON对象的处理。

首先,我使用了一个粗略的抽象示例,用于使用虚拟URI和其他内容进行登录和注销。我打算展示主要原则:

Maven项目的先决条件:

  • 添加了TestNG,REST Assured,...在 pom 中.xml

项目名称:我的项目-

URI登录:http://myBanking/login请求登录:Json,带有POST方法的用户和密码验证所需的两个密钥:OAuth2和令牌

URI注销:超文本传输协议://myBank/logout请求注销:带有loginToken所需密钥的Json;POST方法的身份验证:没有限制

1.设置DataProvider Baseclass:

从提供程序基类开始,以防您可能有多个运行测试类,这些类应使用其自己的特定继承的 DataProvider。此方法从特定文件夹“.../myProject/src/test/Resources/LoginAndLogout”中的相关 json 文件返回 JSON 字符串读取。

import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Objects;

public abstract class DataProviderBase {

    protected static String readJson(String path) {

        String requestBody = null;

        try {
            URI uri = Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource(path)).toURI();
            requestBody = new String(Files.readAllBytes(Paths.get(uri)));
        } 
        catch (Exception e) {
            LOG.error(e.getMessage());
        }

        return requestBody;
    }

}

2. 设置数据提供程序子类(登录/注销):

现在我们可以为登录和注销测试用例创建一个特定的提供程序类。这使我们甚至可以读取带有Json数组的JSON文件,您可以在其中提取POST/PUT请求所需的各个JSON对象。每个JSONObject都反映了一个单独的测试用例。例如,我们有一个特定的DataProvider,用于使用3个单独的测试用例进行简单的登录检查:

import org.json.JSONArray;
import org.testng.annotations.DataProvider;

import java.util.ArrayList;

public class DataProviderLoginAndLogout  extends DataProviderBase {

    private static String readJsonLoginAndLogout(String fileName) {
        return readJson("loginAndLogout/" + fileName);
    }

    @DataProvider(name ="loginExampleTest")
    public static Object[][] loginExampleTest() {

        List<String> jsonElems = new ArrayList<>();
        String jsonArray = readJsonLoginAndLogout("loginExampleTest.json");
        new JSONArray(jsonArray).forEach(it-> jsonElems.add(it.toString()));

        return new Object[][]{
                { jsonElems.get(0), true },  // Positive Case
                { jsonElems.get(1), false }, // Negative Case (Wrong Username)
                { jsonElems.get(2), false }, // Negative Case (Wrong Password)
        };
    }

    @DataProvider(name ="loginWithLogout")
    public static Object[][] loginWithLogout() {

        List<String> jsonElems = new ArrayList<>();
        String jsonArray = readJsonLoginAndLogout("loginWithLogout.json");
        new JSONArray(jsonArray).forEach(it-> jsonElems.add(it.toString()));

        return new Object[][]{
                { jsonElems.get(0) }, // Positive Login
        };
    }

    // You can add more DataProvider Methods for other Tests here ...
}

3.安装前Rest后:

到目前为止还不错,我们终于可以创建一个简单的BeforeAfter类来继承Sub Test类。

import ... ... // Imports Hidden because to long otherwise

public class BeforeAfterRest {

    @Parameters({"systemURL"})
    @BeforeMethod
    public void beforeMethod(Method method, @Optional("http://myBanking") String systemURL) {

        baseURI = systemURL;

    // You can add Logger Functions here, but this is just rough example
    }


    protected RequestSpecification requestBodyAndContentType(String json) {

        return new RequestSpecBuilder().build().body(json).contentType("application/json");
    }

    protected RequestSpecification oAuth2(String json, String authToken) {

        return requestBodyAndContentType(json).auth().oauth2(authToken);
    }

    protected ResponseSpecification httpStatusOkContentTypeJson = new ResponseSpecBuilder().
            expectStatusCode(200).expectContentType(ContentType.JSON).build();

    protected ResponseSpecification httpStatusUnprocessableEntityContentTypeJson = new ResponseSpecBuilder().
            expectStatusCode(422).expectContentType(ContentType.JSON).build();

    protected ResponseSpecification isValidResponseContentTypeJson(boolean isValid) {

        return isValid ? httpStatusOkContentTypeJson : httpStatusUnprocessableEntityContentTypeJson;
    }

    protected ResponseSpecification logResponseBody = new ResponseSpecBuilder().log(LogDetail.BODY).build();

    protected Object getKeyAsObject(String jsonBody, String keyPath) {

        return new JsonPath(jsonBody).get(keyPath);
    }

    protected String getKey(String jsonBody, String keyPath) {

        return (String) getKeyAsObject(jsonBody, keyPath);
    }

    ...
    // Added more getKey Methods for other Types: Integer, Boolean, List, ...

    protected String getModifiedJson(String oldJson, HashMap<String, Object> modifyMap) {

        JSONObject jsonObject = new JSONObject(oldJson);

        modifyMap.keySet().forEach(key -> jsonObject.put(key, modifyMap.get(key)));

        return jsonObject.toString();
    }

}

4. 创建特定测试:

在实现测试之前,我们应该通过IntelliJ在相应的文件夹中添加所需的JSON文件“...src/test/resources/loginAndLogout/...”对于我们的第一个测试“loginExampleTest”,我们创建了一个新的文件“loginExampleTest.json”,其中包含以下内容:

[
  {
    "username": "validUsername",
    "password": "validPassword"
  },
  {
    "username": "invalidUsername",
    "password": "validPassword"
  },
  {
    "username": "validUsername",
    "password": "invalidPassword"
  }
]

现在我们可以实现两个示例测试。一个用于默认登录,第二个用于快速登录,然后注销。

import ... .DataProviderLoginAndLogout;
import ... .BeforeAfterRest;

import org.testng.annotations.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;


public class LoginLogoutTest extends BeforeAfterRest {


    private Response responseLogin(String json) {

        return given( oAuth2(json, getAuthToken()) ).when().post("/login");
    }

   private Response responseLogout(String json) {

        return given( requestBodyAndContentType(json) ).when().post("/logout");
    }

   private String getAuthToken() {
       // ...
       // Extract Token from Endpoint for Authentication 
       // ...
       return authToken;
   }

    @Test(dataProvider = "loginExampleTest", dataProviderClass = DataProviderLoginAndLogout.class)
    public void loginExampleTest(String json, boolean isValid) {

    // Call POST Method, proof for Status depending on valid or invalid Login Credentials.
        String res = responseLogin(json).
                     then().spec(logResponseBody).
                     assertThat().spec(isValidResponseContentTypeJson(isValid)).spec(bodySizeNotEmpty).
                     extract().asPrettyString();
 
       if (isValid) {
           assertThat( res ).contains("loginToken");
           assertThat( getKey(res, "loginToken") ).isNotNull();
       }
       else {
           assertThat( res ).contains("Error");
       }
    }

    @Test(dataProvider = "loginWithLogout", dataProviderClass = DataProviderLoginAndLogout.class)
    public void loginWithLogout(String loginJson) {

        // Create simple Logout Body Json with empty token.
        String logoutJson = "{\"loginToken\": \"\"}";

        String resLogin = responseLogin(loginJson).
                     then().spec(logResponseBody).spec(bodySizeNotEmpty).
                     assertThat().spec(httpStatusOkContentTypeJson).
                     extract().asPrettyString();

        assertThat( getKey(resLogin, "loggedIn") ).isEqualTo("True");
        assertThat( getKey(resLogin, "loginToken") ).isNotNull();
 
        String loginToken = getKey(resLogin, "loginToken");
        HashMap<String,Object> modifyMapForToken = new HashMap<String,Object>() {{ put("loginToken", loginToken); }}

        // Overwriting the Logout JSON with setting "loginToken" thanks to getModifiedJson Method.
        // It is more useful for huge complex JSONs when modifying several keys.
        logoutJson = getModifiedJson(logoutJson, modifyMapForToken);

        String resLogout = responseLogout(logoutJson).
                     then().spec(logResponseBody).
                     assertThat().spec(httpStatusOkContentTypeJson).spec(bodySizeNotEmpty).
                     extract().asPrettyString();  

        assertThat( getKey(resLogout, "loggedOut") ).isEqualTo("true");
    }

}

我希望它有点用...在处理具有部分嵌套JSON的其他复杂endpoint时,我的方法应该更有用...这只是一个粗略的简单例子。

 类似资料:
  • 我开发了一个代号为one的应用程序。它在Android系统中正常运行。我也在努力让它在Iphone上运行。 1) 我已经购买了一个开发者苹果账户,支付了100美元。2) 我已经生成了一个。windows中的证书文件,使用说明。https://knowledge.digicert.com/solution/SO27347.html3)我使用ios签名来使用那里的证书。 然而,其中一个问题是,IOS证

  • 我有MySQL数据库,有以房间号、可用性、clean_status、价格和room_type命名的列。列可用性的数据为可用或不可用,列clean_status的数据为脏或已清理。我试图从数据库获取数据,如果选择的房间是'不可用'或'脏',我想显示错误消息,说明'房间应该是可用的或清洁之前添加客户'。我已经使用ResultSet并执行工作。早些时候它显示了错误消息。我修改了代码并使其可执行。但是它没

  • 本文向大家介绍spring aop action中验证用户登录状态的实例代码,包括了spring aop action中验证用户登录状态的实例代码的使用技巧和注意事项,需要的朋友参考一下 最近在学习ssh框架时,照着网上做了一个商城系统,之前在一些需要用户存在的操作中,都是在每一个action中写重复的代码,这样做现在想起来并不好,想起了spring的aop,于是想通过aop来给每个需要用户操作的

  • 问题内容: 我刚刚安装了SQL Server 2012,并打开了SQL Server Management Studio,当我尝试登录时会出现此问题: 无法连接到… 我的问题是我怎么知道服务器名称是什么? 当我转到SQL Server配置管理器时,我找不到应该存在的SQL Server服务! 有答案吗? 谢谢。 问题答案: 如果安装了SQL Express,则正确的服务器名称是: 或者 如果这样做

  • 我试着用laravel做一个登录/注册的简单应用。。。我目前使用的是5.2版本的laravel。 在路线上,我写道: 所以现在当我尝试注册用户在localhost:8888/auth/register-我填写字段,但当我点击注册然后我得到错误消息: 用户中的FatalErrorException。php第8行:找不到类“lightlight\Foundation\Auth\User” 那么我如何在

  • 我正在研究React应用程序与KeyCloak的集成。我已经在本地计算机上安装了keycloak服务器版本11.0.2。我能够访问管理登录并创建管理用户。我还使用keycloak创建了一个具有凭据的自定义客户端和用户。我的react应用程序是在我的机器的端口9000上托管的,而keycloak是在8080(默认)端口上托管的。现在,当我重定向到我的应用程序URL时,它会自动重定向到下面的URL: