
Hurl 请求链实战在单个 Hurl 文件中串联多个请求并用 JSONPath 断言 REST API【免费下载链接】hurlHurl, run and test HTTP requests with plain text.项目地址: https://gitcode.com/GitHub_Trending/hu/hurl本篇指南基于 Hurl 官方教程中的 Chaining Requests 章节演示如何在同一个.hurl文件中按顺序组织多个 HTTP 请求从追加第二个请求开始逐步扩展到测试返回 JSON 的 REST API、使用[Query]参数段、应用类型化谓词与count/regex过滤器。读完后你将能够编写一个包含多个 entry 的完整 Hurl 测试文件理解hurl --test的执行语义并掌握对 JSON 响应做精确断言的各种写法。教程上下文从 basic.hurl 继续本教程承接前两步你的第一个 Hurl 文件 与 添加断言。在开始请求链之前basic.hurl里只有一个请求已经对首页 HTML 与响应头做了大量断言# Checking our home page: GET http://localhost:3000 HTTP 200 [Asserts] xpath string(//head/title) Movies Box xpath //h3 count 2 xpath string((//h3)[1]) contains Popular xpath string((//h3)[2]) contains Featured Today # Testing HTTP response headers: header Content-Type text/html; charsetutf-8 cookie x-session-id exists cookie x-session-id[HttpOnly] exists此时只有一个 HTTP 请求但响应上已经积累了大量测试。教程强调的原则是断言写得越多测试套件就越不易脆弱。接下来要把其他请求也加进来继续增加测试。追加第二个请求同一文件中的多个 entry在同一个文件里直接在第一请求之后写第二个请求即可。这里验证目标对坏链接服务器应返回 404 页面404 是 HTTP 标准的 Not Found 状态码语义可参考 MDN 文档。修改后的basic.hurl# Checking our home page: GET http://localhost:3000 HTTP 200 [Asserts] xpath string(//head/title) Movies Box xpath //h3 count 2 xpath string((//h3)[1]) contains Popular xpath string((//h3)[2]) contains Featured Today # Testing HTTP response headers: header Content-Type text/html; charsetutf-8 cookie x-session-id exists cookie x-session-id[HttpOnly] exists # Check that we have a 404 response for broken links: GET http://localhost:3000/not-found HTTP 404 [Asserts] header Content-Type text/html; charsetutf-8 xpath string(//h2) Error xpath string(//h3) Not Found现在文件里有两个entry每个 entry 由一个请求和一个期望响应描述expected response description组成。两个请求按文件顺序依次执行每个响应都可以被独立测试。响应描述是可选的。文件也可以只写请求GET http://localhost:3000 GET http://localhost:3000/not-found但这种写法几乎等于不做测试。不过这类文件在另一种场景下很有用当你把 Hurl 当作取数工具用纯文本发请求、拿回响应内容而非测试工具时。运行验证$ hurl --test basic.hurl basic.hurl: Success (2 request(s) in 21 ms) -------------------------------------------------------------------------------- Executed files: 1 Executed requests: 2 (90.9/s) Succeeded files: 1 (100.0%) Failed files: 0 (0.0%) Duration: 22 ms测试仍然通过此时已经是两个请求按序执行。--test模式的执行语义从 手册 对--test选项的说明可以确认几个影响链式测试行为的细节--test激活测试模式HTTP 响应体不再打印到标准输出而是逐个 Hurl 文件报告进度全部跑完后输出一段文本汇总即上面看到的Executed files / Succeeded files表格测试模式下多个文件默认并行执行每个文件一个工作线程、互不共享状态要按文件顺序串行执行加--jobs 1该选项对应环境变量HURL_TEST属于仅命令行可用的选项。注意区分两个层面文件与文件之间在测试模式下可并行而单个文件内部的多个请求始终是顺序执行的——后一个请求可以用前一个请求捕获到的值教程后续章节的 Captures 会用到这一特性。测试 REST APIJSONPath 断言到目前为止测试的是两个 HTML 端点。下面测试 REST API示例网站在http://localhost:3000/api/health暴露了一个 health 资源。先在 shell 里直接验证。Hurl 作为经典 CLI 应用可以像很多 Unix 工具一样从标准输入读取请求用-或管道并把结果管道给其他工具如jq$ echo GET http://localhost:3000/api/health | hurl {status:RUNNING,healthy:true,operationId:6212054377712155,reportedDate:2023-07-21T16:11:24.053Z} $ echo GET http://localhost:3000/api/health | hurl | jq { status: RUNNING, healthy: true, operationId: 8629192252836205, reportedDate: 2023-08-04T11:04:52.516Z }这意味着 Hurl 既能写文件化、可版本化的回归测试也能当交互式探针使用——排查问题时先echo ... | hurl看一眼真实响应再把请求固化进.hurl文件加断言。把 health API 加进basic.hurl用JSONPath 断言# Check our health API: GET http://localhost:3000/api/health HTTP 200 [Asserts] header Content-Type application/json; charsetutf-8 jsonpath $.status RUNNING jsonpath $.healthy true jsonpath $.operationId existsJSONPath 断言与 XPath 断言结构相同一个查询JSONPath 表达式用于检查 JSON 对象 一个谓词。与 XPath 断言一样JSONPath 谓词的值是带类型的字符串、布尔、数字、日期和集合都受支持见 JSONPath 断言。从源码结构看请求执行结果与 JSONPath 断言的求值/比较逻辑集中在运行器中例如 packages/hurl/src/runner/result.rs 里包含JsonPathAssert相关处理断言语义本身的规范则以 docs/spec 下的说明为准。从浏览器 XHR 到 API 断言教程的第二个例子来自 Movies Box 网站的用户功能可以按演员、导演、上映年份搜索电影搜索页在http://localhost:3000/search。输入 1982 就能看到 1982 年上映的电影。搜索页通过浏览器的 XHR 请求后端 REST APIhttp://localhost:3000/api/search获取结果——用浏览器开发者工具可以看到这条请求把这个页面上看到的请求直接变成 Hurl 断言就是对 API 做回归测试的典型路径# Check search API: GET http://localhost:3000/api/search?q1982sortname HTTP 200 [Asserts] header Content-Type application/json; charsetutf-8 jsonpath $ count 5 jsonpath $[0].name Blade Runner jsonpath $[0].director Ridley Scott jsonpath $[0].release_date 1982-06-25教程提示Movies Box 为了教学方便直接内置了 mock 数据生产应用不应这样做。更稳妥的做法是通过环境变量为应用提供 integration/debug 模式或 mock 数据库让断言在已知数据上运行。这里用到了count过滤器jsonpath $ count 5断言整个结果数组有 5 个元素count统计集合元素个数见 filters 文档。使用 [Query] 参数段代替 URL 拼接上面的 URL 直接写了查询参数?q1982sortname。Hurl 也支持把它们放进请求的[Query]段# Check search API: GET http://localhost:3000/api/search [Query] q: 1982 sort: name HTTP 200 [Asserts] header Content-Type application/json; charsetutf-8 jsonpath $ count 5 jsonpath $[0].name Blade Runner jsonpath $[0].director Ridley Scott jsonpath $[0].release_date 1982-06-25关于[Query]段请求语法文档 给出了几条需要记住的规则查询参数由字段: 值组成段以[Query]开头参数段中的值不做 URL 编码这与直接写在 URL 里的参数不同URL 里需要手工转义如Install%20Linux因此含空格、特殊字符的值用参数段写起来更直观如果 URL 和[Query]段同时存在参数最终请求会合并两者一起发送而不是相互覆盖各请求段[Cookies]、[Query]、[Form]等之间无固定顺序可以任意混合书写但请求体必须位于请求的最后。谓词与过滤器从等于到格式校验到这里只测试了服务端返回值等于期望值。Hurl 的断言体系由三层组成查询xpath/jsonpath/header/cookie 等、过滤器对查询结果做变换、谓词对变换后的值做判断。谓词predicates除与exists外断言文档的谓词表 定义了更多类型化谓词谓词语义示例startsWith查询结果以谓词值开头字符串或二进制jsonpath $.movie startsWith TheendsWith查询结果以谓词值结尾字符串或二进制jsonpath $.movie endsWith Backcontains集合包含该值或字符串/二进制包含该子串jsonpath $.numbers contains 42matches查询字符串部分匹配正则模式jsonpath $.release matches /\d{4}/任何谓词都可以通过前缀not取反如not contains。类型约束要注意startsWith/contains只能作用于字符串和字节matches只能作用于字符串查询结果是数字时不能套用字符串谓词。把release_date的断言从精确相等放宽为前缀匹配# Check search API: GET http://localhost:3000/api/search [Query] q: 1982 sort: name HTTP 200 [Asserts] header Content-Type application/json; charsetutf-8 jsonpath $ count 5 jsonpath $[0].name Blade Runner jsonpath $[0].director Ridley Scott jsonpath $[0].release_date startsWith 1982startsWith 1982只验证年份开头。如果想既宽松又严格——只关心年份、但要求日期整体符合YYYY-MM-DD格式——就引入过滤器。regex 过滤器从查询值中提取片段filters 文档 中的regex过滤器提取正则的捕获组内容模式至少需要一组捕获组正则语法遵循 RustregexcrateHurl 用 Rust 编写正则实现与regexcrate 的语法一致。最终写法# Check search API: GET http://localhost:3000/api/search [Query] q: 1982 sort: name HTTP 200 [Asserts] header Content-Type application/json; charsetutf-8 jsonpath $ count 5 jsonpath $[0].name Blade Runner jsonpath $[0].director Ridley Scott jsonpath $[0].release_date regex /(\d{4})-\d{2}-\d{2}/ 1982逐段拆解这条断言jsonpath $[0].release_date—— JSONPath 查询从响应中提取第一部电影的上映日期regex /(\d{4})-\d{2}-\d{2}/—— regex 过滤器正则写法与 JavaScript 一样用/.../包裹其中捕获组(\d{4})把 4 位年份从完整日期中提取出来 1982—— 谓词断言提取出的年份等于期望值。这条断言同时完成了两件事格式校验不匹配YYYY-MM-DD就失败 值校验年份必须是 1982。过滤器可以级联组合来细化查询值这是 Hurl 断言表达力的核心来源——前面已经用过一次countjsonpath $ count 5这里是第二次使用过滤器。完整的四请求测试文件与运行结果最终包含四个 HTTP 请求的basic.hurl完整形态# Checking our home page: GET http://localhost:3000 HTTP 200 [Asserts] xpath string(//head/title) Movies Box xpath //h3 count 2 xpath string((//h3)[1]) contains Popular xpath string((//h3)[2]) contains Featured Today # Testing HTTP response headers: header Content-Type text/html; charsetutf-8 cookie x-session-id exists cookie x-session-id[HttpOnly] exists # Check that we have a 404 response for broken links: GET http://localhost:3000/not-found HTTP 404 [Asserts] header Content-Type text/html; charsetutf-8 xpath string(//h2) Error xpath string(//h3) Not Found # Check our health API: GET http://localhost:3000/api/health HTTP 200 [Asserts] header Content-Type application/json; charsetutf-8 jsonpath $.status RUNNING jsonpath $.healthy true jsonpath $.operationId exists # Check search API: GET http://localhost:3000/api/search [Query] q: 1982 sort: name HTTP 200 [Asserts] header Content-Type application/json; charsetutf-8 jsonpath $ count 5 jsonpath $[0].name Blade Runner jsonpath $[0].director Ridley Scott jsonpath $[0].release_date regex /(\d{4})-\d{2}-\d{2}/ 1982运行$ hurl --test basic.hurl basic.hurl: Success (4 request(s) in 21 ms) -------------------------------------------------------------------------------- Executed files: 1 Executed requests: 4 (181.8/s) Succeeded files: 1 (100.0%) Failed files: 0 (0.0%) Duration: 22 ms每个请求的所有断言全部成功Failed files为 0。小结Hurl 文件由多个entry组成entry 之间用空行分隔按顺序执行同一文件里可以混合 HTML 页面测试与 REST API 测试每个响应独立断言响应描述HTTP 200、[Asserts]等是可选的纯请求文件适合把 Hurl 当取数 CLI 用可配echo ... | hurl | jq管道JSONPath 断言 查询 谓词谓词值带类型startsWith/endsWith/contains/matches等谓词都可用not取反查询参数优先用[Query]段书写值不做 URL 编码与 URL 内参数合并发送过滤器count、regex等可与查询、谓词自由组合实现提取 变换 判断三级断言。教程的收尾建议同样值得记住随着 Hurl 文件增长不要吝啬写注释——Hurl 文件本身就会成为应用一份可执行的文档executable documentation它既是测试也是随时可运行的接口说明。下一章 调试技巧 会讲解断言失败时如何快速定位问题。【免费下载链接】hurlHurl, run and test HTTP requests with plain text.项目地址: https://gitcode.com/GitHub_Trending/hu/hurl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考