Files
httprunner/user/write_testcase/index.html
T

1235 lines
50 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="zh" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="HttpRunner V3.x User Documentation">
<meta name="author" content="debugtalk">
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.2.3, mkdocs-material-7.3.6">
<title>Write Testcase - HttpRunner V3.x Docs</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.a57b2b03.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/palette.3f5d1f46.min.css">
<meta name="theme-color" content="#4051b5">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700%7CRoboto+Mono&display=fallback">
<style>:root{--md-text-font-family:"Roboto";--md-code-font-family:"Roboto Mono"}</style>
<script>window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)},ga.l=+new Date,ga("create","UA-114587036-3","auto"),ga("set","anonymizeIp",!0),ga("send","pageview"),document.addEventListener("DOMContentLoaded",function(){document.forms.search&&document.forms.search.query.addEventListener("blur",function(){var e;this.value&&(e=document.location.pathname,ga("send","pageview",e+"?q="+this.value))}),"undefined"!=typeof location$&&location$.subscribe(function(e){ga("send","pageview",e.pathname)})})</script>
<script async src="https://www.google-analytics.com/analytics.js"></script>
</head>
<body dir="ltr" data-md-color-scheme="" data-md-color-primary="indigo" data-md-color-accent="indigo">
<script>function __prefix(e){return new URL("../..",location).pathname+"."+e}function __get(e,t=localStorage){return JSON.parse(t.getItem(__prefix(e)))}</script>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#write-testcase" class="md-skip">
跳转至
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../.." title="HttpRunner V3.x Docs" class="md-header__button md-logo" aria-label="HttpRunner V3.x Docs" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54z"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
HttpRunner V3.x Docs
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Write Testcase
</span>
</div>
</div>
</div>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="搜索" placeholder="搜索" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
正在初始化搜索引擎
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/httprunner/httprunner" title="前往仓库" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
</div>
<div class="md-source__repository">
HttpRunner
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../.." title="HttpRunner V3.x Docs" class="md-nav__button md-logo" aria-label="HttpRunner V3.x Docs" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54z"/></svg>
</a>
HttpRunner V3.x Docs
</label>
<div class="md-nav__source">
<a href="https://github.com/httprunner/httprunner" title="前往仓库" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
</div>
<div class="md-source__repository">
HttpRunner
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." class="md-nav__link">
README
</a>
</li>
<li class="md-nav__item">
<a href="../../installation/" class="md-nav__link">
Installation
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3" type="checkbox" id="__nav_3" checked>
<label class="md-nav__link" for="__nav_3">
User Guide
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="User Guide" data-md-level="1">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
User Guide
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../concepts/" class="md-nav__link">
Concepts
</a>
</li>
<li class="md-nav__item">
<a href="../scaffold/" class="md-nav__link">
Scaffold
</a>
</li>
<li class="md-nav__item">
<a href="../gen_tests/" class="md-nav__link">
Record & Generate testcase
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
Write Testcase
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
Write Testcase
</a>
<nav class="md-nav md-nav--secondary" aria-label="目录">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
目录
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#record-generate-testcase" class="md-nav__link">
record &amp; generate testcase
</a>
</li>
<li class="md-nav__item">
<a href="#testcase-structure" class="md-nav__link">
testcase structure
</a>
</li>
<li class="md-nav__item">
<a href="#chain-call" class="md-nav__link">
chain call
</a>
</li>
<li class="md-nav__item">
<a href="#config" class="md-nav__link">
config
</a>
<nav class="md-nav" aria-label="config">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#name-required" class="md-nav__link">
name (required)
</a>
</li>
<li class="md-nav__item">
<a href="#base_url-optional" class="md-nav__link">
base_url (optional)
</a>
</li>
<li class="md-nav__item">
<a href="#variables-optional" class="md-nav__link">
variables (optional)
</a>
</li>
<li class="md-nav__item">
<a href="#verify-optional" class="md-nav__link">
verify (optional)
</a>
</li>
<li class="md-nav__item">
<a href="#export-optional" class="md-nav__link">
export (optional)
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#teststeps" class="md-nav__link">
teststeps
</a>
<nav class="md-nav" aria-label="teststeps">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#runrequestname" class="md-nav__link">
RunRequest(name)
</a>
<nav class="md-nav" aria-label="RunRequest(name)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#with_variables" class="md-nav__link">
.with_variables
</a>
</li>
<li class="md-nav__item">
<a href="#methodurl" class="md-nav__link">
.method(url)
</a>
</li>
<li class="md-nav__item">
<a href="#with_params" class="md-nav__link">
.with_params
</a>
</li>
<li class="md-nav__item">
<a href="#with_headers" class="md-nav__link">
.with_headers
</a>
</li>
<li class="md-nav__item">
<a href="#with_cookies" class="md-nav__link">
.with_cookies
</a>
</li>
<li class="md-nav__item">
<a href="#with_data" class="md-nav__link">
.with_data
</a>
</li>
<li class="md-nav__item">
<a href="#with_json" class="md-nav__link">
.with_json
</a>
</li>
<li class="md-nav__item">
<a href="#extract" class="md-nav__link">
extract
</a>
<nav class="md-nav" aria-label="extract">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#with_jmespath" class="md-nav__link">
.with_jmespath
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#validate" class="md-nav__link">
validate
</a>
<nav class="md-nav" aria-label="validate">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#assert_xxx" class="md-nav__link">
.assert_XXX
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#runtestcasename" class="md-nav__link">
RunTestCase(name)
</a>
<nav class="md-nav" aria-label="RunTestCase(name)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#with_variables_1" class="md-nav__link">
.with_variables
</a>
</li>
<li class="md-nav__item">
<a href="#call" class="md-nav__link">
.call
</a>
</li>
<li class="md-nav__item">
<a href="#export" class="md-nav__link">
.export
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../run_testcase/" class="md-nav__link">
Run Testcase
</a>
</li>
<li class="md-nav__item">
<a href="../testing_report/" class="md-nav__link">
Testing Report
</a>
</li>
<li class="md-nav__item">
<a href="../run_loadtest/" class="md-nav__link">
Run load test
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../sponsors/" class="md-nav__link">
Sponsors
</a>
</li>
<li class="md-nav__item">
<a href="../../CHANGELOG/" class="md-nav__link">
CHANGELOG
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="目录">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
目录
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#record-generate-testcase" class="md-nav__link">
record &amp; generate testcase
</a>
</li>
<li class="md-nav__item">
<a href="#testcase-structure" class="md-nav__link">
testcase structure
</a>
</li>
<li class="md-nav__item">
<a href="#chain-call" class="md-nav__link">
chain call
</a>
</li>
<li class="md-nav__item">
<a href="#config" class="md-nav__link">
config
</a>
<nav class="md-nav" aria-label="config">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#name-required" class="md-nav__link">
name (required)
</a>
</li>
<li class="md-nav__item">
<a href="#base_url-optional" class="md-nav__link">
base_url (optional)
</a>
</li>
<li class="md-nav__item">
<a href="#variables-optional" class="md-nav__link">
variables (optional)
</a>
</li>
<li class="md-nav__item">
<a href="#verify-optional" class="md-nav__link">
verify (optional)
</a>
</li>
<li class="md-nav__item">
<a href="#export-optional" class="md-nav__link">
export (optional)
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#teststeps" class="md-nav__link">
teststeps
</a>
<nav class="md-nav" aria-label="teststeps">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#runrequestname" class="md-nav__link">
RunRequest(name)
</a>
<nav class="md-nav" aria-label="RunRequest(name)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#with_variables" class="md-nav__link">
.with_variables
</a>
</li>
<li class="md-nav__item">
<a href="#methodurl" class="md-nav__link">
.method(url)
</a>
</li>
<li class="md-nav__item">
<a href="#with_params" class="md-nav__link">
.with_params
</a>
</li>
<li class="md-nav__item">
<a href="#with_headers" class="md-nav__link">
.with_headers
</a>
</li>
<li class="md-nav__item">
<a href="#with_cookies" class="md-nav__link">
.with_cookies
</a>
</li>
<li class="md-nav__item">
<a href="#with_data" class="md-nav__link">
.with_data
</a>
</li>
<li class="md-nav__item">
<a href="#with_json" class="md-nav__link">
.with_json
</a>
</li>
<li class="md-nav__item">
<a href="#extract" class="md-nav__link">
extract
</a>
<nav class="md-nav" aria-label="extract">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#with_jmespath" class="md-nav__link">
.with_jmespath
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#validate" class="md-nav__link">
validate
</a>
<nav class="md-nav" aria-label="validate">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#assert_xxx" class="md-nav__link">
.assert_XXX
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#runtestcasename" class="md-nav__link">
RunTestCase(name)
</a>
<nav class="md-nav" aria-label="RunTestCase(name)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#with_variables_1" class="md-nav__link">
.with_variables
</a>
</li>
<li class="md-nav__item">
<a href="#call" class="md-nav__link">
.call
</a>
</li>
<li class="md-nav__item">
<a href="#export" class="md-nav__link">
.export
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="write-testcase">Write Testcase<a class="headerlink" href="#write-testcase" title="Permanent link">&para;</a></h1>
<p>HttpRunner v3.x supports three testcase formats, <code>pytest</code>, <code>YAML</code> and <code>JSON</code>. It is extremely recommended to write and maintain testcases in <code>pytest</code> format instead of former <code>YAML/JSON</code> format.</p>
<p>The format relations are illustrated as below:</p>
<p><img alt="" src="/images/httprunner-formats.png" /></p>
<h2 id="record-generate-testcase">record &amp; generate testcase<a class="headerlink" href="#record-generate-testcase" title="Permanent link">&para;</a></h2>
<p>If the SUT (system under test) is ready, the most efficient way is to capture HTTP traffic first and then generate testcases with HAR file. Refer to <a href="/user/gen_tests/"><code>Record &amp; Generate testcase</code></a> for more details.</p>
<p>Based on the generated pytest testcase, you can then do some adjustment as needed, thus you need to know the details of testcase format.</p>
<h2 id="testcase-structure">testcase structure<a class="headerlink" href="#testcase-structure" title="Permanent link">&para;</a></h2>
<p>Each testcase is a subclass of <code>HttpRunner</code>, and must have two class attributes: <code>config</code> and <code>teststeps</code>.</p>
<ul>
<li>config: configure testcase level settings, including <code>base_url</code>, <code>verify</code>, <code>variables</code>, <code>export</code>.</li>
<li>teststeps: list of teststep (<code>List[Step]</code>), each step is corresponding to a API request or another testcase reference call. Besides, <code>variables</code>/<code>extract</code>/<code>validate</code>/<code>hooks</code> mechanisms are supported to create extremely complex test scenarios.</li>
</ul>
<div class="codehilite"><pre><span></span><code><span class="kn">from</span> <span class="nn">httprunner</span> <span class="kn">import</span> <span class="n">HttpRunner</span><span class="p">,</span> <span class="n">Config</span><span class="p">,</span> <span class="n">Step</span><span class="p">,</span> <span class="n">RunRequest</span><span class="p">,</span> <span class="n">RunTestCase</span>
<span class="k">class</span> <span class="nc">TestCaseRequestWithFunctions</span><span class="p">(</span><span class="n">HttpRunner</span><span class="p">):</span>
<span class="n">config</span> <span class="o">=</span> <span class="p">(</span>
<span class="n">Config</span><span class="p">(</span><span class="s2">&quot;request methods testcase with functions&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">variables</span><span class="p">(</span>
<span class="o">**</span><span class="p">{</span>
<span class="s2">&quot;foo1&quot;</span><span class="p">:</span> <span class="s2">&quot;config_bar1&quot;</span><span class="p">,</span>
<span class="s2">&quot;foo2&quot;</span><span class="p">:</span> <span class="s2">&quot;config_bar2&quot;</span><span class="p">,</span>
<span class="s2">&quot;expect_foo1&quot;</span><span class="p">:</span> <span class="s2">&quot;config_bar1&quot;</span><span class="p">,</span>
<span class="s2">&quot;expect_foo2&quot;</span><span class="p">:</span> <span class="s2">&quot;config_bar2&quot;</span><span class="p">,</span>
<span class="p">}</span>
<span class="p">)</span>
<span class="o">.</span><span class="n">base_url</span><span class="p">(</span><span class="s2">&quot;https://postman-echo.com&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">verify</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>
<span class="o">.</span><span class="n">export</span><span class="p">(</span><span class="o">*</span><span class="p">[</span><span class="s2">&quot;foo3&quot;</span><span class="p">])</span>
<span class="p">)</span>
<span class="n">teststeps</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">Step</span><span class="p">(</span>
<span class="n">RunRequest</span><span class="p">(</span><span class="s2">&quot;get with params&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">with_variables</span><span class="p">(</span>
<span class="o">**</span><span class="p">{</span><span class="s2">&quot;foo1&quot;</span><span class="p">:</span> <span class="s2">&quot;bar11&quot;</span><span class="p">,</span> <span class="s2">&quot;foo2&quot;</span><span class="p">:</span> <span class="s2">&quot;bar21&quot;</span><span class="p">,</span> <span class="s2">&quot;sum_v&quot;</span><span class="p">:</span> <span class="s2">&quot;${sum_two(1, 2)}&quot;</span><span class="p">}</span>
<span class="p">)</span>
<span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;/get&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">with_params</span><span class="p">(</span><span class="o">**</span><span class="p">{</span><span class="s2">&quot;foo1&quot;</span><span class="p">:</span> <span class="s2">&quot;$foo1&quot;</span><span class="p">,</span> <span class="s2">&quot;foo2&quot;</span><span class="p">:</span> <span class="s2">&quot;$foo2&quot;</span><span class="p">,</span> <span class="s2">&quot;sum_v&quot;</span><span class="p">:</span> <span class="s2">&quot;$sum_v&quot;</span><span class="p">})</span>
<span class="o">.</span><span class="n">with_headers</span><span class="p">(</span><span class="o">**</span><span class="p">{</span><span class="s2">&quot;User-Agent&quot;</span><span class="p">:</span> <span class="s2">&quot;HttpRunner/${get_httprunner_version()}&quot;</span><span class="p">})</span>
<span class="o">.</span><span class="n">extract</span><span class="p">()</span>
<span class="o">.</span><span class="n">with_jmespath</span><span class="p">(</span><span class="s2">&quot;body.args.foo2&quot;</span><span class="p">,</span> <span class="s2">&quot;foo3&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">validate</span><span class="p">()</span>
<span class="o">.</span><span class="n">assert_equal</span><span class="p">(</span><span class="s2">&quot;status_code&quot;</span><span class="p">,</span> <span class="mi">200</span><span class="p">)</span>
<span class="o">.</span><span class="n">assert_equal</span><span class="p">(</span><span class="s2">&quot;body.args.foo1&quot;</span><span class="p">,</span> <span class="s2">&quot;bar11&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">assert_equal</span><span class="p">(</span><span class="s2">&quot;body.args.sum_v&quot;</span><span class="p">,</span> <span class="s2">&quot;3&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">assert_equal</span><span class="p">(</span><span class="s2">&quot;body.args.foo2&quot;</span><span class="p">,</span> <span class="s2">&quot;bar21&quot;</span><span class="p">)</span>
<span class="p">),</span>
<span class="n">Step</span><span class="p">(</span>
<span class="n">RunRequest</span><span class="p">(</span><span class="s2">&quot;post form data&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">with_variables</span><span class="p">(</span><span class="o">**</span><span class="p">{</span><span class="s2">&quot;foo2&quot;</span><span class="p">:</span> <span class="s2">&quot;bar23&quot;</span><span class="p">})</span>
<span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="s2">&quot;/post&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">with_headers</span><span class="p">(</span>
<span class="o">**</span><span class="p">{</span>
<span class="s2">&quot;User-Agent&quot;</span><span class="p">:</span> <span class="s2">&quot;HttpRunner/${get_httprunner_version()}&quot;</span><span class="p">,</span>
<span class="s2">&quot;Content-Type&quot;</span><span class="p">:</span> <span class="s2">&quot;application/x-www-form-urlencoded&quot;</span><span class="p">,</span>
<span class="p">}</span>
<span class="p">)</span>
<span class="o">.</span><span class="n">with_data</span><span class="p">(</span><span class="s2">&quot;foo1=$foo1&amp;foo2=$foo2&amp;foo3=$foo3&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">validate</span><span class="p">()</span>
<span class="o">.</span><span class="n">assert_equal</span><span class="p">(</span><span class="s2">&quot;status_code&quot;</span><span class="p">,</span> <span class="mi">200</span><span class="p">)</span>
<span class="o">.</span><span class="n">assert_equal</span><span class="p">(</span><span class="s2">&quot;body.form.foo1&quot;</span><span class="p">,</span> <span class="s2">&quot;$expect_foo1&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">assert_equal</span><span class="p">(</span><span class="s2">&quot;body.form.foo2&quot;</span><span class="p">,</span> <span class="s2">&quot;bar23&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">assert_equal</span><span class="p">(</span><span class="s2">&quot;body.form.foo3&quot;</span><span class="p">,</span> <span class="s2">&quot;bar21&quot;</span><span class="p">)</span>
<span class="p">),</span>
<span class="p">]</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span>
<span class="n">TestCaseRequestWithFunctions</span><span class="p">()</span><span class="o">.</span><span class="n">test_start</span><span class="p">()</span>
</code></pre></div>
<h2 id="chain-call">chain call<a class="headerlink" href="#chain-call" title="Permanent link">&para;</a></h2>
<p>One of the most awesome features of HttpRunner v3.x is <code>chain call</code>, with which you do not need to remember any testcase format details and you can get intelligent completion when you write testcases in IDE.</p>
<p><img alt="" src="/images/httprunner-chain-call-config.png" /></p>
<p><img alt="" src="/images/httprunner-chain-call-step-validate.png" /></p>
<h2 id="config">config<a class="headerlink" href="#config" title="Permanent link">&para;</a></h2>
<p>Each testcase should have one <code>config</code> part, in which you can configure testcase level settings.</p>
<h3 id="name-required">name (required)<a class="headerlink" href="#name-required" title="Permanent link">&para;</a></h3>
<p>Specify testcase name. This will be displayed in execution log and test report.</p>
<h3 id="base_url-optional">base_url (optional)<a class="headerlink" href="#base_url-optional" title="Permanent link">&para;</a></h3>
<p>Specify common schema and host part of the SUT, e.g. <code>https://postman-echo.com</code>. If <code>base_url</code> is specified, url in teststep can only set relative path part. This is especially useful if you want to switch between different SUT environments.</p>
<h3 id="variables-optional">variables (optional)<a class="headerlink" href="#variables-optional" title="Permanent link">&para;</a></h3>
<p>Specify common variables of testcase. Each teststep can reference config variable which is not set in step variables. In other words, step variables have higher priority than config variables.</p>
<h3 id="verify-optional">verify (optional)<a class="headerlink" href="#verify-optional" title="Permanent link">&para;</a></h3>
<p>Specify whether to verify the servers TLS certificate. This is especially useful if we want to record HTTP traffic of testcase execution, because SSLError will be occurred if verify is not set or been set to True.</p>
<blockquote>
<p>SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1076)'))</p>
</blockquote>
<h3 id="export-optional">export (optional)<a class="headerlink" href="#export-optional" title="Permanent link">&para;</a></h3>
<p>Specify the exported session variables of testcase. Consider each testcase as a black box, config <code>variables</code> is the input part, and config <code>export</code> is the output part. In particular, when a testcase is referenced in another testcase's step, and will be extracted some session variables to be used in subsequent teststeps, then the extracted session variables should be configured in config <code>export</code> part.</p>
<h2 id="teststeps">teststeps<a class="headerlink" href="#teststeps" title="Permanent link">&para;</a></h2>
<p>Each testcase should have one or multiple ordered test steps (<code>List[Step]</code>), each step is corresponding to a API request or another testcase reference call.</p>
<p><img alt="" src="/images/httprunner-testcase.png" /></p>
<blockquote>
<p>Notice: The concept of API in HttpRunner v2.x has been deprecated for simplification. You can consider API as a testcase that has only one request step.</p>
</blockquote>
<h3 id="runrequestname">RunRequest(name)<a class="headerlink" href="#runrequestname" title="Permanent link">&para;</a></h3>
<p><code>RunRequest</code> is used in a step to make request to API and do some extraction or validations for response.</p>
<p>The argument <code>name</code> of RunRequest is used to specify teststep name, which will be displayed in execution log and test report.</p>
<h4 id="with_variables">.with_variables<a class="headerlink" href="#with_variables" title="Permanent link">&para;</a></h4>
<p>Specify teststep variables. The variables of each step are independent, thus if you want to share variables in multiple steps, you should define variables in config variables. Besides, the step variables will override the ones that have the same name in config variables.</p>
<h4 id="methodurl">.method(url)<a class="headerlink" href="#methodurl" title="Permanent link">&para;</a></h4>
<p>Specify HTTP method and the url of SUT. These are corresponding to <code>method</code> and <code>url</code> arguments of <a href="https://requests.readthedocs.io/en/master/api/#requests.request"><code>requests.request</code></a>.</p>
<p>If <code>base_url</code> is set in config, url can only set relative path part.</p>
<h4 id="with_params">.with_params<a class="headerlink" href="#with_params" title="Permanent link">&para;</a></h4>
<p>Specify query string for the request url. This is corresponding to the <code>params</code> argument of <a href="https://requests.readthedocs.io/en/master/api/#requests.request"><code>requests.request</code></a>.</p>
<h4 id="with_headers">.with_headers<a class="headerlink" href="#with_headers" title="Permanent link">&para;</a></h4>
<p>Specify HTTP headers for the request. This is corresponding to the <code>headers</code> argument of <a href="https://requests.readthedocs.io/en/master/api/#requests.request"><code>requests.request</code></a>.</p>
<h4 id="with_cookies">.with_cookies<a class="headerlink" href="#with_cookies" title="Permanent link">&para;</a></h4>
<p>Specify HTTP request cookies. This is corresponding to the <code>cookies</code> argument of <a href="https://requests.readthedocs.io/en/master/api/#requests.request"><code>requests.request</code></a>.</p>
<h4 id="with_data">.with_data<a class="headerlink" href="#with_data" title="Permanent link">&para;</a></h4>
<p>Specify HTTP request body. This is corresponding to the <code>data</code> argument of <a href="https://requests.readthedocs.io/en/master/api/#requests.request"><code>requests.request</code></a>.</p>
<h4 id="with_json">.with_json<a class="headerlink" href="#with_json" title="Permanent link">&para;</a></h4>
<p>Specify HTTP request body in json. This is corresponding to the <code>json</code> argument of <a href="https://requests.readthedocs.io/en/master/api/#requests.request"><code>requests.request</code></a>.</p>
<h4 id="extract">extract<a class="headerlink" href="#extract" title="Permanent link">&para;</a></h4>
<h5 id="with_jmespath">.with_jmespath<a class="headerlink" href="#with_jmespath" title="Permanent link">&para;</a></h5>
<p>Extract JSON response body with <a href="https://jmespath.org/">jmespath</a>.</p>
<blockquote>
<p>with_jmespath(jmes_path: Text, var_name: Text)</p>
</blockquote>
<ul>
<li>jmes_path: jmespath expression, refer to <a href="https://jmespath.org/tutorial.html">JMESPath Tutorial</a> for more details</li>
<li>var_name: the variable name that stores extracted value, it can be referenced by subsequent test steps</li>
</ul>
<h4 id="validate">validate<a class="headerlink" href="#validate" title="Permanent link">&para;</a></h4>
<h5 id="assert_xxx">.assert_XXX<a class="headerlink" href="#assert_xxx" title="Permanent link">&para;</a></h5>
<p>Extract JSON response body with <a href="https://jmespath.org/">jmespath</a> and validate with expected value.</p>
<blockquote>
<p>assert_XXX(jmes_path: Text, expected_value: Any, message: Text = "")</p>
</blockquote>
<ul>
<li>jmes_path: jmespath expression, refer to <a href="https://jmespath.org/tutorial.html">JMESPath Tutorial</a> for more details</li>
<li>expected_value: the specified expected value, variable or function reference can also be used here</li>
<li>message (optional): used to indicate assertion error reason</li>
</ul>
<p>The image below shows HttpRunner builtin validators.</p>
<p><img alt="" src="/images/httprunner-step-request-validate.png" /></p>
<h3 id="runtestcasename">RunTestCase(name)<a class="headerlink" href="#runtestcasename" title="Permanent link">&para;</a></h3>
<p><code>RunTestCase</code> is used in a step to reference another testcase call.</p>
<p>The argument <code>name</code> of RunTestCase is used to specify teststep name, which will be displayed in execution log and test report.</p>
<h4 id="with_variables_1">.with_variables<a class="headerlink" href="#with_variables_1" title="Permanent link">&para;</a></h4>
<p>Same with RunRequest's <code>.with_variables</code>.</p>
<h4 id="call">.call<a class="headerlink" href="#call" title="Permanent link">&para;</a></h4>
<p>Specify referenced testcase class.</p>
<h4 id="export">.export<a class="headerlink" href="#export" title="Permanent link">&para;</a></h4>
<p>Specify session variable names to export from referenced testcase. The exported variables can be referenced by subsequent test steps.</p>
<div class="codehilite"><pre><span></span><code><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">getcwd</span><span class="p">())</span>
<span class="kn">from</span> <span class="nn">httprunner</span> <span class="kn">import</span> <span class="n">HttpRunner</span><span class="p">,</span> <span class="n">Config</span><span class="p">,</span> <span class="n">Step</span><span class="p">,</span> <span class="n">RunRequest</span><span class="p">,</span> <span class="n">RunTestCase</span>
<span class="kn">from</span> <span class="nn">examples.postman_echo.request_methods.request_with_functions_test</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">TestCaseRequestWithFunctions</span> <span class="k">as</span> <span class="n">RequestWithFunctions</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">class</span> <span class="nc">TestCaseRequestWithTestcaseReference</span><span class="p">(</span><span class="n">HttpRunner</span><span class="p">):</span>
<span class="n">config</span> <span class="o">=</span> <span class="p">(</span>
<span class="n">Config</span><span class="p">(</span><span class="s2">&quot;request methods testcase: reference testcase&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">variables</span><span class="p">(</span>
<span class="o">**</span><span class="p">{</span>
<span class="s2">&quot;foo1&quot;</span><span class="p">:</span> <span class="s2">&quot;testsuite_config_bar1&quot;</span><span class="p">,</span>
<span class="s2">&quot;expect_foo1&quot;</span><span class="p">:</span> <span class="s2">&quot;testsuite_config_bar1&quot;</span><span class="p">,</span>
<span class="s2">&quot;expect_foo2&quot;</span><span class="p">:</span> <span class="s2">&quot;config_bar2&quot;</span><span class="p">,</span>
<span class="p">}</span>
<span class="p">)</span>
<span class="o">.</span><span class="n">base_url</span><span class="p">(</span><span class="s2">&quot;https://postman-echo.com&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">verify</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">teststeps</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">Step</span><span class="p">(</span>
<span class="n">RunTestCase</span><span class="p">(</span><span class="s2">&quot;request with functions&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">with_variables</span><span class="p">(</span>
<span class="o">**</span><span class="p">{</span><span class="s2">&quot;foo1&quot;</span><span class="p">:</span> <span class="s2">&quot;testcase_ref_bar1&quot;</span><span class="p">,</span> <span class="s2">&quot;expect_foo1&quot;</span><span class="p">:</span> <span class="s2">&quot;testcase_ref_bar1&quot;</span><span class="p">}</span>
<span class="p">)</span>
<span class="o">.</span><span class="n">call</span><span class="p">(</span><span class="n">RequestWithFunctions</span><span class="p">)</span>
<span class="o">.</span><span class="n">export</span><span class="p">(</span><span class="o">*</span><span class="p">[</span><span class="s2">&quot;foo3&quot;</span><span class="p">])</span>
<span class="p">),</span>
<span class="n">Step</span><span class="p">(</span>
<span class="n">RunRequest</span><span class="p">(</span><span class="s2">&quot;post form data&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">with_variables</span><span class="p">(</span><span class="o">**</span><span class="p">{</span><span class="s2">&quot;foo1&quot;</span><span class="p">:</span> <span class="s2">&quot;bar1&quot;</span><span class="p">})</span>
<span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="s2">&quot;/post&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">with_headers</span><span class="p">(</span>
<span class="o">**</span><span class="p">{</span>
<span class="s2">&quot;User-Agent&quot;</span><span class="p">:</span> <span class="s2">&quot;HttpRunner/${get_httprunner_version()}&quot;</span><span class="p">,</span>
<span class="s2">&quot;Content-Type&quot;</span><span class="p">:</span> <span class="s2">&quot;application/x-www-form-urlencoded&quot;</span><span class="p">,</span>
<span class="p">}</span>
<span class="p">)</span>
<span class="o">.</span><span class="n">with_data</span><span class="p">(</span><span class="s2">&quot;foo1=$foo1&amp;foo2=$foo3&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">validate</span><span class="p">()</span>
<span class="o">.</span><span class="n">assert_equal</span><span class="p">(</span><span class="s2">&quot;status_code&quot;</span><span class="p">,</span> <span class="mi">200</span><span class="p">)</span>
<span class="o">.</span><span class="n">assert_equal</span><span class="p">(</span><span class="s2">&quot;body.form.foo1&quot;</span><span class="p">,</span> <span class="s2">&quot;bar1&quot;</span><span class="p">)</span>
<span class="o">.</span><span class="n">assert_equal</span><span class="p">(</span><span class="s2">&quot;body.form.foo2&quot;</span><span class="p">,</span> <span class="s2">&quot;bar21&quot;</span><span class="p">)</span>
<span class="p">),</span>
<span class="p">]</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span>
<span class="n">TestCaseRequestWithTestcaseReference</span><span class="p">()</span><span class="o">.</span><span class="n">test_start</span><span class="p">()</span>
</code></pre></div>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="Footer">
<a href="../gen_tests/" class="md-footer__link md-footer__link--prev" aria-label="上一页: Record &amp; Generate testcase" rel="prev">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
</div>
<div class="md-footer__title">
<div class="md-ellipsis">
<span class="md-footer__direction">
上一页
</span>
Record & Generate testcase
</div>
</div>
</a>
<a href="../run_testcase/" class="md-footer__link md-footer__link--next" aria-label="下一页: Run Testcase" rel="next">
<div class="md-footer__title">
<div class="md-ellipsis">
<span class="md-footer__direction">
下一页
</span>
Run Testcase
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11H4z"/></svg>
</div>
</a>
</nav>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2017 - 2021 debugtalk
</div>
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
<div class="md-footer-social">
<a href="https://debugtalk.com" target="_blank" rel="noopener" title="debugtalk.com" class="md-footer-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54z"/></svg>
</a>
<a href="https://github.com/httprunner" target="_blank" rel="noopener" title="github.com" class="md-footer-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 512"><path d="M186.1 328.7c0 20.9-10.9 55.1-36.7 55.1s-36.7-34.2-36.7-55.1 10.9-55.1 36.7-55.1 36.7 34.2 36.7 55.1zM480 278.2c0 31.9-3.2 65.7-17.5 95-37.9 76.6-142.1 74.8-216.7 74.8-75.8 0-186.2 2.7-225.6-74.8-14.6-29-20.2-63.1-20.2-95 0-41.9 13.9-81.5 41.5-113.6-5.2-15.8-7.7-32.4-7.7-48.8 0-21.5 4.9-32.3 14.6-51.8 45.3 0 74.3 9 108.8 36 29-6.9 58.8-10 88.7-10 27 0 54.2 2.9 80.4 9.2 34-26.7 63-35.2 107.8-35.2 9.8 19.5 14.6 30.3 14.6 51.8 0 16.4-2.6 32.7-7.7 48.2 27.5 32.4 39 72.3 39 114.2zm-64.3 50.5c0-43.9-26.7-82.6-73.5-82.6-18.9 0-37 3.4-56 6-14.9 2.3-29.8 3.2-45.1 3.2-15.2 0-30.1-.9-45.1-3.2-18.7-2.6-37-6-56-6-46.8 0-73.5 38.7-73.5 82.6 0 87.8 80.4 101.3 150.4 101.3h48.2c70.3 0 150.6-13.4 150.6-101.3zm-82.6-55.1c-25.8 0-36.7 34.2-36.7 55.1s10.9 55.1 36.7 55.1 36.7-34.2 36.7-55.1-10.9-55.1-36.7-55.1z"/></svg>
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "../..", "features": [], "translations": {"clipboard.copy": "\u590d\u5236", "clipboard.copied": "\u5df2\u590d\u5236", "search.config.lang": "ja", "search.config.pipeline": "trimmer, stemmer", "search.config.separator": "[\\uff0c\\u3002]+", "search.placeholder": "\u641c\u7d22", "search.result.placeholder": "\u952e\u5165\u4ee5\u5f00\u59cb\u641c\u7d22", "search.result.none": "\u6ca1\u6709\u627e\u5230\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.one": "\u627e\u5230 1 \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.other": "# \u4e2a\u7b26\u5408\u6761\u4ef6\u7684\u7ed3\u679c", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.term.missing": "Missing", "select.version.title": "Select version"}, "search": "../../assets/javascripts/workers/search.fcfe8b6d.min.js", "version": null}</script>
<script src="../../assets/javascripts/bundle.b1047164.min.js"></script>
</body>
</html>