Проверка HTML-документа с помощью REST Assured

Я пытаюсь использовать REST Assured для проверки некоторых свойств в HTML-документе, возвращаемом моим сервером. SSCCE, демонстрирующий проблему, будет выглядеть следующим образом:

import static com.jayway.restassured.path.xml.config.XmlPathConfig.xmlPathConfig;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import org.junit.Test;

import com.jayway.restassured.path.xml.XmlPath;

public class HtmlDocumentTest {

  @Test
  public void titleShouldBeHelloWorld() {
    final XmlPath xml = new XmlPath("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
      + "<html xmlns=\"http://www.w3.org/1999/xhtml\">"
      + "<head><title>Hello world</title></head><body></body></html>")
      .using(xmlPathConfig().with().feature("http://apache.org/xml/features/disallow-doctype-decl", false));
    assertThat(xml.get("//title[text()]"), is("Hello world"));
  }
}

Теперь эта попытка заканчивается com.jayway.restassured.path.xml.exception.XmlPathException: Failed to parse the XML document, вызванным, выключив все возможные ошибки, java.net.ConnectException: Connection timed out примерно через 30 секунд!

Если я удалю строку с xmlPathConfig().with().feature(...), тест сразу же завершится ошибкой из-за DOCTYPE is disallowed when the feature "http://apache.org/xml/features/disallow-doctype-decl" set to true..

Если я удалю строку doctype из документа, синтаксический анализ будет успешным, но тест завершится неудачно из-за ошибки утверждения "Expected: is "Hello world" but: was <Hello worldnull>" - однако, это, очевидно, другая проблема (но не стесняйтесь давать инструкции и по этому поводу ...) . И удаление doctype в любом случае для меня не вариант.

Итак, вопрос: как вы проверяете свойства документа HTML с типом документа с помощью REST Assured? в документации сказано, что «поставщики с гарантированным REST предопределенные парсеры, например, HTML, XML и JSON. ", но я не могу найти никаких примеров того, как именно активировать и работать с этим парсером HTML! Нет класса "HtmlPath", такого как, например, XmlPath, и это исключение тайм-аута очень озадачивает ...


person ZeroOne    schedule 16.10.2015    source источник


Ответы (3)


Я проверил ваш код. Дело в том, что XmlPath of Restassured не является Xpath, а использует синтаксис доступа к свойствам. Если вы добавите основной текст в образец HTML, вы увидите, что ваш XPath мало что делает. Фактическое название языка запросов - GPath. Следующий пример работает, обратите внимание также на использование CompatibilityMode.HTML, у которого есть нужная вам конфигурация:

import static org.junit.Assert.assertEquals;
import org.junit.Test;
import com.jayway.restassured.path.xml.XmlPath;
import com.jayway.restassured.path.xml.XmlPath.CompatibilityMode;

public class HtmlDocumentTest {

    @Test
    public void titleShouldBeHelloWorld() {
        XmlPath doc = new XmlPath(
                CompatibilityMode.HTML,
                "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
                        + "<html xmlns=\"http://www.w3.org/1999/xhtml\">"
                        + "<head><title>Hello world</title></head>"
                        + "<body>some body"
                        + "<div class=\"content\">wrapped</div>"
                        + "<div class=\"content\">wrapped2</div>"
                        + "</body></html>");

        String title = doc.getString("html.head.title");
        String content = doc.getString("html.body.div.find { it.@class == 'content' }");
        String content2 = doc.getString("**.findAll { it.@class == 'content' }[1]");

        assertEquals("Hello world", title);
        assertEquals("wrapped", content);
        assertEquals("wrapped2", content2);
    }
}
person revau.lt    schedule 28.10.2015
comment
Почему бы не использовать этот ответ вместо stackoverflow.com/a/58301335/6648326? - person MasterJoe; 30.06.2020

Если вы используете DSL (задано / когда / тогда), то XmlPath с CompatibilityMode.HTML используется автоматически, если заголовок типа содержимого ответа содержит html совместимый тип мультимедиа (например, text/html). Например, если /index.html содержит следующую html-страницу:

<html>
    <title>My page</title>
    <body>Something</body>
</html>

тогда вы можете проверить заголовок и тело следующим образом:

when().
        get("/index.html").
then().
        statusCode(200).
        body("html.title", equalTo("My page"), 
             "html.body",  equalTo("Something"));
person Johan    schedule 09.01.2016
comment
Почему бы не использовать этот ответ вместо stackoverflow.com/a/58301335/6648326? - person MasterJoe; 30.06.2020

Вот пример кода с последним API-интерфейсом rest assured, т. Е. Io.restassured, а не более старым jayway.restassured. Пояснение к коду находится в комментариях к коду.

//Demo for an api which returns a json string inside html. The json string is just an array of objects.

import io.restassured.RestAssured;
import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;

import java.util.List;

import static io.restassured.RestAssured.*;

public void testMyApi() {
    Response response =
            when().
                    get("www.myapi.com/data").
            then().
                    extract().
                    response();
    
    String bodyTxt = response.htmlPath().getString("body");//Get the body element of the html response.
    JsonPath jsonObj = new JsonPath(bodyTxt);//helps us to find things in a json string.

    List<String> rootItems = jsonObj.getList("$");//get root element of the json part.

    System.out.println(rootItems);
}
person MasterJoe    schedule 30.06.2020