2015-10-16 62 views
5

我试图使用REST Assured来检查我的服务器返回的HTML文档的一些属性。一个SSCCE证明那问题就如下:使用REST确保检查HTML文档

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")); 
    } 
} 

现在,这种尝试有30秒左右的时间以后,结束com.jayway.restassured.path.xml.exception.XmlPathException: Failed to parse the XML document所致,关闭所有可能出现的错误,java.net.ConnectException: Connection timed out

如果我用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>” - 但是,这是一个不同的问题,显然(但也可以自由地给予指示...)。无论如何,删除文档类型对我来说都不是一种选择。

所以,问题:你如何使用REST Assured检查带有文档类型的HTML文档的属性?它说in the documentationREST Assured providers预定义的解析器,例如HTML,XML和JSON。”,但我似乎无法找到关于如何激活和使用该HTML解析器的任何示例!没有“HtmlPath”类,例如XmlPath,例如,超时异常非常令人费解......

回答

3

我检查了您的代码。问题是Restassured的XmlPath不是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 { [email protected] == 'content' }"); 
     String content2 = doc.getString("**.findAll { [email protected] == 'content' }[1]"); 

     assertEquals("Hello world", title); 
     assertEquals("wrapped", content); 
     assertEquals("wrapped2", content2); 
    } 
} 
+0

酷,谢谢!似乎像一个魅力工作,我很高兴奖励你的赏金。 :)另外一个问题,但是,如果你不介意:使用属性访问语法,是否有可能以任何方式找到具有给定ID或类的元素,然后声明其内容? – ZeroOne

+0

@请参阅上面的更新答案。 –

+0

好的,谢谢!在这里,还有一个upvote。 :) – ZeroOne

5

如果您使用的是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"));