RestAssured學(xué)習(二)

例3 - 復(fù)雜的解析和驗證
這正是rest-assured閃光點所在贰镣!由于rest-assured實現(xiàn)了Groovy呜象,它可以從Groovy集合的API的優(yōu)點中獲益。讓我們從下面的Groovy例子中開始探索:

def words = ['ant', 'buffalo', 'cat', 'dinosaur']
def wordsWithSizeGreaterThanFour = words.findAll { it.length() > 4 }

在第一行碑隆,我們簡單地定義了一個包含一些單詞的列表恭陡,不過第二行更加有趣。
這里我們檢索了列表里的所有長度大于4的單詞上煤,通過一個叫做findAll的Groovy閉包休玩。
這個閉包有一個內(nèi)部變量it,代表著列表中當前的元素。
結(jié)果是一個新的列表拴疤, wordsWithSizeGreaterThanFour,包含buffalo and dinosaur永部。

這里還有一些其它的有趣的方法,我們也可以使用在Groovy集合中:
find – 找到第一個匹配閉包謂詞(closure predicate)的元素
collect – 收集在集合里的每個元素都調(diào)用的閉包返回值(collect the return value of calling a closure on each item in a collection)
sum – 對集合里的元素進行求和
max/min – 返回集合里的最大值/最小值

moco的接口:

{
    "description":"復(fù)雜的驗證",
    "request":{
      "uri":"/getfindall",
      "method":"get"
    },
    "response":{
      "json":{
        "p2pdata":{
          "data":[{
            "words":"ant"
          },{
            "words":"buffalo"
          },{
            "words":"cat"
          },{
            "words":"dinosaur"
          }]
        }
      }
    }
  }

測試findAll的練習代碼:

    @Test
    public void sixteen(){
        given()
                .proxy(8888)
                .get("http://localhost:8889/getfindall")
//                .getBody().prettyPrint();
                .then()
                .body("p2pdata.data.words.findAll{it.length()>4}",hasItems("buffalo","dinosaur"));
    }

測試find的測試代碼:

        given()
                .proxy(8888)
                .get("http://localhost:8889/getfindall")
//                .getBody().prettyPrint();
                .then()
                .body("p2pdata.data.words.find{it.length()>4}",hasItems("buffalo"));

find呐矾、findAll都是去查找符合條件的字段值
collect是查找符合條件的集合苔埋,會根據(jù)條件得出相對應(yīng)的結(jié)果。比如
.body("p2pdata.data.words.collect{it.length()>4}",hasItems("buffalo"));
得出的結(jié)果就是Actual: [false, true, false, true]蜒犯,
.body("p2pdata.data.words.collect{it.length()}",hasItems("buffalo"));得出的結(jié)果是:
Actual: [3, 7, 3, 8]
所以collect是根據(jù)條件得出對應(yīng)的集合组橄。

測試sum():


image.png

測試max():


image.png

測試 min():


image.png

所以我們?nèi)绾卧谑褂胷est-assured驗證XML和JSON響應(yīng)時利用這些優(yōu)點?
XML示例
比如moco的接口返回如下xml:

<shopping>
      <category type="groceries">
        <item>Chocolate</item>
        <item>Coffee</item>
      </category>
      <category type="supplies">
        <item>Paper</item>
        <item quantity="4">Pens</item>
      </category>
      <category type="present">
        <item when="Aug 10">Kathryn's Birthday</item>
      </category>
</shopping>

moco接口:

  {
    "description":"返回內(nèi)容是xml",
    "request":{
      "uri":"/assertxmlresponse",
      "method":"get"
    },
    "response":{
      "text":"<shopping>\n<category type=\"groceries\">\n<item>Chocolate</item>\n<item>Coffee</item>\n</category>\n<category type=\"supplies\">\n<item>Paper</item>\n<item quantity=\"4\">Pens</item>\n</category>\n<category type=\"present\">\n<item when=\"Aug 10\">Kathryn's Birthday</item>\n</category>\n</shopping>",
      "headers":{
        "Content-Type":"text/xml"
      }
    }
  }

又比如我們想寫一個測試來檢驗類型為groceries的category節(jié)點有Chocolate和Coffee這兩個項目愧薛。在rest-assured可以這樣做:

     given()
                .proxy(8888)
                .get("http://localhost:8889/assertxmlresponse")
//                .getBody().prettyPrint();
                .then()
                .body("shopping.category.find { it.@type == 'groceries' }.item", hasItems("Chocolate", "Coffee"));

這里發(fā)生了什么事晨炕?首先使用XML路徑shopping.category獲取了所有categoriy的一個列表。在這個列表中我們又調(diào)用了一個方法毫炉,find瓮栗,來返回有type這個屬性且該屬性值為groceries的單個category節(jié)點。
在這個category上我們接下來繼續(xù)收集所有相關(guān)聯(lián)的項目(item)瞄勾。
由于這里與category相關(guān)聯(lián)的項目不止一個费奸,所以會返回一個列表。接下來我們通過Hamcrest matcher的hasItems方法來解析它进陡。

但是如果我們想取得一些項目(item)但又不想進行斷言驗證該怎么辦愿阐?您可以參考XmlPath:

        // Get the response body as a String
        String response = get("http://localhost:8889/assertxmlresponse").asString();
// And get the groceries from the response. "from" is statically imported from the XmlPath class
        List<String> groceries = from(response).getList("shopping.category.find { it.@type == 'groceries' }.item");

        for (String s : groceries){
            System.out.println(s);
        }

如果groceries是您對這個響應(yīng)里唯一的關(guān)注點,也可以使用一個捷徑:

        List<String> groceriesthree = get("http://localhost:8889/assertxmlresponse").xmlPath().getList("shopping.category.find { it.@type == 'groceries' }.item");
        for (String s : groceriesthree){
            System.out.println(s);
        }

深度優(yōu)先搜索
實際上之前的例子我們還可以繼續(xù)簡化:

        given()
                .proxy(8888)
                .get("http://localhost:8889/assertxmlresponse")
                .then()
                .body("**.find { it.@type == 'groceries' }", hasItems("Chocolate", "Coffee"));

**是一種在XML文件中做深度優(yōu)先搜索的捷徑趾疚。

我們搜索第一個type屬性值等于"groceries"的節(jié)點缨历。注意我們沒有在"item"這個XML路徑結(jié)束。

原因是在category節(jié)點返回一個列表的項目值時糙麦,自動調(diào)用了toString()這個方法(譯者注:這兩句有啥因果關(guān)系我沒搞懂)辛孵。

JSON示例
moco接口:

{
    "description":"返回內(nèi)容是json",
    "request":{
      "uri":"/assertjsonresponse",
      "method":"get"
    },
    "response":{
      "json":{

    "store":{
      "book":[
        {
          "author":"Nigel Rees",
          "category":"reference",
          "price":8.95,
          "title":"Sayings of the Century"
        },
        {
          "author":"Evelyn Waugh",
          "category":"fiction",
          "price":12.99,
          "title":"Sword of Honour"
        },
        {
          "author":"Herman Melville",
          "category":"fiction",
          "isbn":"0-553-21311-3",
          "price":8.99,
          "title":"Moby Dick"
        },
        {
          "author":"J. R. R. Tolkien",
          "category":"fiction",
          "isbn":"0-395-19395-8",
          "price":22.99,
          "title":"The Lord of the Rings"
        }
      ]
    }
  }

    }
  }

例1
在本例中我們發(fā)起一個請求"/store",并且做了一個斷言:搜集滿足price字段值小于10的所有book數(shù)組里的title字段赡磅,得到了"Sayings of the Century"和"Moby Dick"這兩個結(jié)果:

    @Test
    public void testtwenty(){
        given()
                .get("http://localhost:8889/assertjsonresponse")
                .then()
                .body("store.book.findAll{it.price < 10 }.title",hasItems("Sayings of the Century","Moby Dick"));
    }

就像上面XML的例子魄缚,我們使用閉包獲取所有price字段值低于10的book數(shù)組,并且返回相應(yīng)的title字段值集合焚廊。

然后使用hasItems這個匹配器來斷言得到我們預(yù)期的結(jié)果冶匹。使用JsonPath 我們可以用下面的方法替代:

        String response = get("http://localhost:8889/assertjsonresponse").asString();
// And get all books with price < 10 from the response. "from" is statically imported from the JsonPath class
        List<String> bookTitles = JsonPath.from(response).getList("store.book.findAll { it.price < 10 }.title");
        for (String s : bookTitles){
            System.out.println(s);
        }

例2
考慮下該如何斷言所有author字段值長度總和是否大于50的結(jié)果。

這是個挺難以回答的問題咆瘟,也正展示了閉包和Groovy集合的強大之處嚼隘。在rest-assured里可以:

        given()
                .get("http://localhost:8889/assertjsonresponse")
                .then()
                .body("store.book.author.collect{it.length() }.sum()",greaterThan(50));

首先我們通過(store.book.author)得到了所有的author字段值,然后使用閉包里的方法{ it.length() }解析這個集合袒餐。

它所做的是對列表里的每一個author字段執(zhí)行一次length()方法飞蛹,然后返回一個新的列表须肆。在這個列表中,我們再調(diào)用sum()方法來求得字符長度的總和桩皿。

最終的結(jié)果是53,并且我們使用greaterThan匹配器的斷言結(jié)果是大于50 幢炸。

但是實際上可以繼續(xù)簡化這種寫法泄隔。可以再次參考"words"這個例子

def words = ['ant', 'buffalo', 'cat', 'dinosaur']

Groovy有一個便利的方法可以遍歷列表中的所有元素宛徊,使用*來調(diào)用佛嬉。舉個例子:

def words = ['ant', 'buffalo', 'cat', 'dinosaur']assert [3, 6, 3, 8] == words*.length()

Groovy返回了一個新的包含words中每個字段字符長度的列表。我們也可以把rest-assured中的這個語法用在author列表中:

        given()
                .get("http://localhost:8889/assertjsonresponse")
                .then()
                .body("store.book.author*.length().sum()",greaterThan(50));

當然我們可以使用JsonPath來獲取這個結(jié)果:

        int sumOfAllAuthorLengths = JsonPath.from(response).getInt("store.book.author*.length().sum()");
        assertThat(sumOfAllAuthorLengths,is(53));
        System.out.println(sumOfAllAuthorLengths);

其它例子
Micha Kops曾寫過一篇很優(yōu)秀的博客闸天,里面包含大量示例(包括可檢出的代碼)暖呕。您可以由此進入試讀

Bas Dijkstra也開展過不少關(guān)于rest-assured的開源研究和資源苞氮。你可以由此進入試讀湾揽,如果您想試用或者作出貢獻,他的github倉庫里有些可以嘗試的練習題笼吟。

關(guān)于float和double
浮點型數(shù)字必須和Java的基本類型"float"區(qū)分開库物。舉個例子,如果我們看下面的JSON對象:

  {
    "description":"返回內(nèi)容是json",
    "request":{
      "uri":"/assertfloatresponse",
      "method":"get"
    },
    "response":{
      "json":{
        "price":12.12
      }

    }
  }

如下的測試將會失敗贷帮,因為我們在拿一個"double"在比較戚揭,而不是"float":

        given()
                .get("http://localhost:8889/assertfloatresponse")
                .then()
                .body("price", equalTo(12.12));

想用"float"比較的話寫法應(yīng)該是:

        given()
                .get("http://localhost:8889/assertfloatresponse")
                .then()
                .body("price", equalTo(12.12f));

語法關(guān)注點
當閱讀rest-assured的博客時,你也許會看到許多使用"given / expect / when"語法的例子撵枢,舉個例子:

        given()
                .expect()
                .body("price", equalTo(12.12f))
                .when()
                .get("http://localhost:8889/assertfloatresponse");

這是一種“遺留語法”民晒,這實際上是rest-assured 1.x.版本用來寫測試用例的方式。然而這種運作方式令許多用戶迷惑甚至惱怒锄禽。這是因為一開始沒有把"given / when / then"作為主要的技術(shù)來使用潜必。所以rest-assured得2.0版本之前差不多不支持這種類似BDD-like測試的標準用法。"given / expect / when"在2.0仍然可用但是"given / when / then"可讀性更強所以在測試用例中更為推薦沟绪。然而使用"given / expect / when"還有一個好處刮便,就是所有的期望中的錯誤可以在同時展示出來,這是新語法做不到的(自從預(yù)期結(jié)果放在了最后面)绽慈。這意味著如果你有多個預(yù)期結(jié)果想要檢驗?zāi)憧梢?


image.png

rest-assured將同時報告狀態(tài)碼預(yù)期和響應(yīng)體預(yù)期結(jié)果都是錯的恨旱。將這些用新語法重寫:


image.png

將會僅僅報告首個預(yù)期/斷言失敗的內(nèi)容(比如預(yù)期狀態(tài)碼是400實際是200),第二個斷言將不執(zhí)行坝疼。您將不得不重新運行這個用例以期獲取到第二個斷言的結(jié)果搜贤。

語法糖
rest-assured中另一件值得注意的是,有些語法僅僅存在于語法糖中钝凶,舉個例子仪芒,"and"在一行代碼中使用可以增強可讀性.
moco接口:

{
    "description":"驗證and",
    "request":{
      "uri":"/assertandrequest",
      "method":"get",
      "headers":{
        "token":"1234567890"
      },
      "queries":{
        "name":"qinzhenxia"
      }
    },
    "response":{
      "json":{
        "price":"12"
      }

    }
  }

測試代碼:

        given().param("name","qinzhenxia").and().header("token","1234567890").when().get("http://localhost:8889/assertandrequest").then().statusCode(200).and().body("price",equalTo("12"));

這等價于:

        given()
                .param("name","qinzhenxia")
                .header("token","1234567890")
                .when()
                .get("http://localhost:8889/assertandrequest")
                .then()
                .statusCode(200)
                .body("price",equalTo("12"));

獲得響應(yīng)體信息
你也可以獲得響應(yīng)的內(nèi)容唁影。比方說你想通過發(fā)起一個get請求"/lotto"并獲取其響應(yīng)內(nèi)容。你可以以多種方式:

InputStream stream = get("/lotto").asInputStream(); // Don't forget to close this one when you're done
byte[] byteArray = get("/lotto").asByteArray();
String json = get("/lotto").asString();

從已驗證的響應(yīng)體中提取值
您可以從響應(yīng)信息中提取值掂名,或者使用extract方法僅僅返回response本身的一個實例据沈。如何你想獲取響應(yīng)里的值,并將其作為接下來的請求內(nèi)容饺蔑,這會很有用锌介。下面是一個叫做title的資源返回的JSON數(shù)據(jù):

  {
    "description":"驗證從response中提取內(nèi)容",
    "request":{
      "uri":"/getpath",
      "method":"get",
      "headers":{
        "token":"1234567890"
      },
      "queries":{
        "name":"qinzhenxia"
      }
    },
    "response":{
      "headers":{
        "token":"0987654321"
      },
      "json":{
        "title" : "My Title",
        "_links": {
          "self": { "href": "/title" },
          "next": { "href": "http://www.baidu.com" }
        }

      }

    }
  }

又校驗了接口,利用extract方法從返回結(jié)果中獲取想要的數(shù)據(jù)

        String nextlink = given()
                .param("name","qinzhenxia")
                .header("token","1234567890")
                .when()
                .get("http://localhost:8889/getpath")
                .then()
                .contentType(ContentType.JSON)
                .body("title",equalTo("My Title"))
                .extract()
                .path("_links.next.href");


        System.out.println(nextlink);

如果您想提取多個值猾警,也可以考慮返回整個響應(yīng)體:

        Response response = given()
                .param("name","qinzhenxia")
                .header("token","1234567890")
                .when()
                .get("http://localhost:8889/getpath")
                .then()
                .contentType(ContentType.JSON)
                .body("title",equalTo("My Title"))
                .extract()
                .response();

        String headers = response.header("token");
        String nextlinktwo = response.path("_links.next.href");

        System.out.println(headers);
        System.out.println(nextlinktwo);

JSON (使用 JsonPath)
一個查看jsonpath例子的網(wǎng)頁:
https://www.programcreek.com/java-api-examples/index.php?api=com.jayway.restassured.path.json.JsonPath

一旦我們?nèi)〉昧隧憫?yīng)體孔祸,可以使用JsonPath來提取相應(yīng)的數(shù)據(jù):

int lottoId = from(json).getInt("lotto.lottoId");
List<Integer> winnerIds = from(json).get("lotto.winners.winnerId");

代碼:

        Response response = given()
                .param("name","qinzhenxia")
                .header("token","1234567890")
                .when()
                .get("http://localhost:8889/getpath")
                .then()
                .contentType(ContentType.JSON)
                .body("title",equalTo("My Title"))
                .extract()
                .response();
        //使用jsonpath獲取返回值response.asString()  一定要用asString()方法才能
        String hrefvalue = JsonPath.from(response.asString()).getString("_links.next.href");
        System.out.println("使用jsonpath獲取hrefvalue:"+hrefvalue);

或者更高效一些:

JsonPath jsonPath = new JsonPath(json).setRoot("lotto");
int lottoId = jsonPath.getInt("lottoId");
List<Integer> winnerIds = jsonPath.get("winners.winnderId");

代碼:

        //setRoot()設(shè)置根路徑
        JsonPath jsonPath = new JsonPath(response.asString()).setRoot("_links");
        String hrefvaluetwo = jsonPath.getString("next.href");
        System.out.println("使用jsonpath獲取hrefvaluetwo:"+hrefvaluetwo);

注意這里我們獨立地使用了JsonPath,而沒有依賴rest-assured本身的功能发皿,看getting started guide 獲取更多信息.

JsonPath 配置
您可以為JsonPath配置反序列化對象(object de-serializers)崔慧,舉個例子:

JsonPath jsonPath = new JsonPath(SOME_JSON).using(new JsonPathConfig("UTF-8"));

也可以靜態(tài)配置好JsonPath,這樣所有的JsonPath實例都會共享這個配置:

JsonPath.config = new JsonPathConfig("UTF-8");

更多JsonPath的內(nèi)容參照這篇博客穴墅。

注意這里的JsonPath基于Groovy的GPath惶室,不要和Jayway的搞混了。

注:暫時可能用不到封救。

XML (使用XmlPath)
您也可以使用XmlPath相應(yīng)的功能:

String xml = post("/greetXML?firstName=John&lastName=Doe").andReturn().asString();
// Now use XmlPath to get the first and last name
String firstName = from(xml).get("greeting.firstName");
String lastName = from(xml).get("greeting.firstName");

// or a bit more efficiently:
XmlPath xmlPath = new XmlPath(xml).setRoot("greeting");
String firstName = xmlPath.get("firstName");
String lastName = xmlPath.get("lastName");

注意拇涤,您可以獨立于rest-assured,單獨使用XmlPath的功能誉结,更多信息參見getting started guide鹅士。

XmlPath配置:
你可以配置XmlPath的對象反序列化器和字符編碼,舉個例子:

XmlPath xmlPath = new XmlPath(SOME_XML).using(new XmlPathConfig("UTF-8"));

也可以靜態(tài)地配置XmlPath惩坑,使得所有的實例都能共享這套配置:

XmlPath.config = new XmlPathConfig("UTF-8");

更多關(guān)于XmlPath的信息參閱這篇博客掉盅。

獲取某個路徑下的值

如您你只是想發(fā)起一個請求并返回一個路徑下的值,你可以使用一個捷徑:

int lottoId = get("/lotto").path("lotto.lottoid");

rest-assured會基于響應(yīng)體的content-type自動決定是使用JsonPath還是XmlPath以舒。如果這個類型在rest-assured沒有被定義趾痘,它將會自動到default parser中查找。你可以自行(代碼指定)決定使用哪種蔓钟,比如:

String firstName = post("/greetXML?firstName=John&lastName=Doe").andReturn().xmlPath().getString("firstName");

xmlPath, jsonPathhtmlPath都是可選項永票。

Headers, cookies, status等

  {
    "description":"驗證從response中提取內(nèi)容",
    "request":{
      "uri":"/getheadersAndCookies",
      "method":"get",
      "headers":{
        "token":"1234567890",
        "otherheader":"1111111111"
      },
      "queries":{
        "name":"qinzhenxia"
      }
    },
    "response":{
      "status":200,
      "cookies":{
        "xintai_ucenter_sso":"UCENTER-ad78845d-0277-4384-8759-8ceee5ecaf0a"
      },
      "headers":{
        "token":"0987654321",
        "otherheader":"22222222222"
      },
      "json":{
        "title" : "My Title",
        "_links": {
          "self": { "href": "/title" },
          "next": { "href": "http://www.baidu.com" }
        }

      }

    }
  }
    @Test
    public void testtwentyfour(){
        Response response = given()
                .param("name","qinzhenxia")
                .header("token","1234567890")
                .header("otherheader","1111111111")
                .when()
                .get("http://localhost:8889/getheadersAndCookies")
                .then()
//                .contentType(ContentType.JSON)
                .body("title",equalTo("My Title"))
                .extract()
                .response();

        //獲取所有headers
        Headers header = response.getHeaders();
        String getheader = header.toString();
        System.out.println("獲取所有的headers:"+getheader);//moco的接口只能返回一個

        System.out.println("---------------------------");
        //獲取單個header
        String getoneheader = response.getHeader("token");
        String getoneheadertwo = response.getHeader("otherheader");
        System.out.println("token的值是:"+getoneheader+",otherheader的值是:"+getoneheadertwo);

        System.out.println("---------------------------");

        //獲取多個cookie,moco的接口只能返回一個
        Map<String,String> map = response.getCookies();
        for (Map.Entry<String,String> entry : map.entrySet()){
            System.out.println("key:"+entry.getKey()+",values:"+entry.getValue());
        }

        System.out.println("---------------------------");
        String ddd = response.getCookie("xintai_ucenter_sso");
        //獲取單個cookie
        System.out.println(ddd);

        //獲取狀態(tài)行
        System.out.println("狀態(tài)行是:"+response.getStatusLine());

        //獲取狀態(tài)碼
        System.out.println("狀態(tài)碼是:"+response.getStatusCode());

    }

多個 header 和 cookie
header 和 cookie 可以包含同名的多個值滥沫。
多個 header
要獲取header的所有值侣集,您需要首先從Response對象中獲取Headers 對象。您需要首先從Response對象中獲取Headers對象兰绣。您可以使用Headers.getValues(
)方法返回一個具有所有header值的List列表世分。

多個 cookie
要獲取cookie的所有值,您需要首先從Response對象中獲取Cookie對象缀辩。您可以使用Cookie.getValues()方法獲取所有值臭埋,該方法返回包含所有Cookie值的List列表踪央。

詳細的 Cookies 信息
如果您需要獲取Cookie的路徑或過期日期等詳細信息,您需要從REST Assured獲取一個detailed cookie瓢阴。您可以使用Response.getDetailedCookie(java.lang.String) 方法獲取單個Cookie畅蹂,包括與給定名稱相關(guān)聯(lián)的所有屬性。

您還可以使用Response.getDetailedCookies()方法獲取所有詳細的響應(yīng)cookies荣恐。

指定請求數(shù)據(jù)
除了指定請求參數(shù)魁莉,您還可以指定header,Cookie募胃,正文和Content Type
請求HTTP資源
您通常通過調(diào)用request specification中的“HTTP方法”執(zhí)行請求。例如:

when().get("/x"). ..;

其中get是HTTP請求方法畦浓。

從REST Assured 3.0.0開始痹束,您可以通過使用該方法為請求使用任何HTTP動詞。

when().       request("CONNECT", "/somewhere").then().       statusCode(200);

這將向服務(wù)器發(fā)送“連接”請求讶请。

參數(shù)化

通常您可以這樣指定參數(shù):

given().       param("param1", "value1").       param("param2", "value2").when().       get("/something");

REST Assured將自動嘗試基于HTTP方法確定哪個參數(shù)類型(即查詢或表單參數(shù))祷嘶。在GET的情況下,查詢參數(shù)將被自動使用夺溢,在POST的情況下將使用表單參數(shù)论巍。在某些情況下,重要的是在PUT或POST中分離表單和查詢參數(shù)风响。你可以這樣使用:

given().       formParam("formParamName", "value1").       queryParam("queryParamName", "value2").when().       post("/something");

get請求可以常用param嘉汰、params;
post請求可以常用body状勤、formParam鞋怀、queryParam

參數(shù)也可以url上進行設(shè)置:

..when().get("/name?firstName=John&lastName=Doe");

參數(shù)如果上傳的是文件,字節(jié)數(shù)組持搜,輸入流或文本的可以參照Multi-part類型的表單數(shù)據(jù)部分

多值參數(shù)
多值參數(shù)是每個參數(shù)名稱具有多于一個值的參數(shù)(即密似,每個名稱的值的列表)。您可以使用var-args指定這些值:

given().param("myList", "value1", "value2"). .. 

或者使用 list 列表:

List<String> values = new ArrayList<String>();
values.add("value1");
values.add("value2");

given().param("myList", values). .. 

無值參數(shù)
您還可以指定一個沒有值的請求或表單參數(shù):

given().param("paramName"). ..

路徑參數(shù)
您還可以在請求中指定所謂的路徑參數(shù)葫盼,例如

post("/reserve/{hotelId}/{roomNumber}", "My Hotel", 23);
這些種類的路徑參數(shù)在REST Assured中稱為“未命名路徑參數(shù)”残腌,因為它們是基于索引的(hotelId將等于“My Hotel”,因為它是第一個占位符)贫导。

您還可以使用命名路徑參數(shù):

given().
pathParam("hotelId", "My Hotel").
pathParam("roomNumber", 23).
when().
post("/reserve/{hotelId}/{roomNumber}").
then().
..
路徑參數(shù)使得更容易讀取請求路徑抛猫,且使請求路徑能夠在具有不同參數(shù)值的許多測試中容易地重復(fù)使用。

從版本2.8.0開始脱盲,您可以混合未賦值和賦值好的路徑參數(shù):

given().
pathParam("hotelId", "My Hotel").
when().
post("/reserve/{hotelId}/{roomNumber}", 23).
then().
..
這里 roomNumber 的值被替換魏23邑滨,hotelId的值被替換為My Hotel

注意,指定太少或太多的參數(shù)將導(dǎo)致錯誤消息钱反。對于高級用例掖看,您可以從[過濾器](#過濾器)添加匣距,更改,刪除(甚至冗余的路徑參數(shù))哎壳。

Cookie
通常模式下毅待,您可以通過以下方法指定Cookie:

given().cookie("username", "John").when().get("/cookie").then().body(equalTo("username"));
也可以像這樣給cookie指定多個值:

given().cookie("cookieName", "value1", "value2"). ..
這將創(chuàng)建兩個cookie:cookieName = value1和cookieName = value2。

您還可以使用以下方式指定詳細的Cookie:

Cookie someCookie = new Cookie.Builder("some_cookie", "some_value").setSecured(true).setComment("some comment").build();
given().cookie(someCookie).when().get("/cookie").then().assertThat().body(equalTo("x"));
或同時指定cookies(多個cookie的情況):

Cookie cookie1 = Cookie.Builder("username", "John").setComment("comment 1").build();
Cookie cookie2 = Cookie.Builder("token", 1234).setComment("comment 2").build();
Cookies cookies = new Cookies(cookie1, cookie2);
given().cookies(cookies).when().get("/cookie").then().body(equalTo("username, token"));

    @Test
    public void testtwentysenven(){
        //多個cookie
        Cookie cookie1 = new Cookie.Builder("token","1234567890").setComment("the frist cookie").build();
        Cookie cookie2 = new Cookie.Builder("tokentwo","77777").setComment("the sencond cookie").build();

        Cookies cookie = new Cookies(cookie1,cookie2);

        given()
                .proxy(8888)
                .param("name","qinzhenxia")
                .pathParam("test","testing")
                .cookies(cookie)
                .when()
                .get("http://localhost:8889/{test}/{getmoreCookies}","getmoreCookies")
                .then()
                .body("title",equalTo("My Title"));

    }

Header

given().header("MyHeader", "Something").and(). ..given().headers("MyHeader", "Something", "MyOtherHeader", "SomethingElse").and(). ..

也可以給一個headers指定多個值:

given().header("headerName", "value1", "value2"). ..

這將創(chuàng)建兩個header,headerName = value1和headerName = value2

Header 合并/覆蓋

默認情況下归榕,header合并可以這樣:

given().header("x", "1").header("x", "2"). ..

請求將包含兩個標頭尸红,“x:1”和“x:2”。您可以在[HeaderConfig](http://static.javadoc.io/io.rest-assured/rest-assured/3.0.1/io/restassured/config/HeaderConfig.html)的基礎(chǔ)上進行更改刹泄。例如:

given().        config(RestAssuredConfig.config().headerConfig(headerConfig().overwriteHeadersWithName("x"))).        header("x", "1").        header("x", "2").when().        get("/something")....

這意味著只有header “x = 2”被發(fā)送到服務(wù)器

Content Type

given().contentType(ContentType.TEXT). ..given().contentType("application/json"). ..

請求正文

given().body("some body"). .. // Works for POST, PUT and DELETE requestsgiven().request().body("some body"). .. // More explicit (optional)
given().body(new byte[]{42}). .. // Works for POST, PUT and DELETEgiven().request().body(new byte[]{42}). .. // More explicit (optional)

您還可以將Java對象序列化為JSON或XML外里。點擊這里了解詳情。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末特石,一起剝皮案震驚了整個濱河市盅蝗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌姆蘸,老刑警劉巖墩莫,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異逞敷,居然都是意外死亡狂秦,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門推捐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來裂问,“玉大人,你說我怎么就攤上這事牛柒°碉” “怎么了?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵焰络,是天一觀的道長戴甩。 經(jīng)常有香客問我,道長闪彼,這世上最難降的妖魔是什么甜孤? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮畏腕,結(jié)果婚禮上缴川,老公的妹妹穿的比我還像新娘。我一直安慰自己描馅,他們只是感情好把夸,可當我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著铭污,像睡著了一般恋日。 火紅的嫁衣襯著肌膚如雪膀篮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天岂膳,我揣著相機與錄音誓竿,去河邊找鬼。 笑死谈截,一個胖子當著我的面吹牛筷屡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播簸喂,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼毙死,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了喻鳄?” 一聲冷哼從身側(cè)響起规哲,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎诽表,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體隅肥,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡竿奏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了腥放。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泛啸。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖秃症,靈堂內(nèi)的尸體忽然破棺而出候址,到底是詐尸還是另有隱情,我是刑警寧澤种柑,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布岗仑,位于F島的核電站,受9級特大地震影響聚请,放射性物質(zhì)發(fā)生泄漏荠雕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一驶赏、第九天 我趴在偏房一處隱蔽的房頂上張望炸卑。 院中可真熱鬧,春花似錦煤傍、人聲如沸盖文。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽五续。三九已至洒敏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間返帕,已是汗流浹背桐玻。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留荆萤,地道東北人镊靴。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像链韭,于是被迫代替她去往敵國和親偏竟。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架敞峭,建立于...
    Hsinwong閱讀 22,353評論 1 92
  • Getting Started Burp Suite 是用于攻擊web 應(yīng)用程序的集成平臺踊谋。它包含了許多工具,并為...
    Eva_chenx閱讀 28,655評論 0 14
  • 一說到REST旋讹,我想大家的第一反應(yīng)就是“啊殖蚕,就是那種前后臺通信方式〕良#”但是在要求詳細講述它所提出的各個約束睦疫,以及如...
    時待吾閱讀 3,415評論 0 19
  • 本帖內(nèi)容摘抄自:https://testerhome.com/topics/7060,在此基礎(chǔ)上增加練習筆記(在看...
    零下的雨閱讀 9,593評論 0 4
  • 會話(Session)跟蹤是Web程序中常用的技術(shù)鞭呕,用來跟蹤用戶的整個會話蛤育。常用的會話跟蹤技術(shù)是Cookie與Se...
    chinariver閱讀 5,601評論 1 49