Files
httprunner/prepare/parameters/index.html
2019-12-11 17:20:18 +08:00

1518 lines
54 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 http-equiv="x-ua-compatible" content="ie=edge">
<meta name="description" content="HttpRunner V2.x User Documentation">
<meta name="author" content="debugtalk">
<meta name="lang:clipboard.copy" content="复制">
<meta name="lang:clipboard.copied" content="已复制">
<meta name="lang:search.language" content="jp">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="没有找到符合条件的结果">
<meta name="lang:search.result.one" content="找到 1 个符合条件的结果">
<meta name="lang:search.result.other" content="# 个符合条件的结果">
<meta name="lang:search.tokenizer" content="[\uff0c\u3002]+">
<link rel="shortcut icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.0.4, mkdocs-material-4.4.3">
<title>参数化数据驱动 - HttpRunner V2.x 中文使用文档</title>
<link rel="stylesheet" href="../../assets/stylesheets/application.30686662.css">
<link rel="stylesheet" href="../../assets/stylesheets/application-palette.a8b3c06d.css">
<meta name="theme-color" content="#3f51b5">
<script src="../../assets/javascripts/modernizr.74668098.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700|Roboto+Mono&display=fallback">
<style>body,input{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../../assets/fonts/material-icons.css">
<script>
window.ga = window.ga || function() {
(ga.q = ga.q || []).push(arguments)
}
ga.l = +new Date
/* Setup integration and send page view */
ga("create", "UA-114587036-2", "auto")
ga("set", "anonymizeIp", true)
ga("send", "pageview")
/* Register handler to log search on blur */
document.addEventListener("DOMContentLoaded", () => {
if (document.forms.search) {
var query = document.forms.search.query
query.addEventListener("blur", function() {
if (this.value) {
var path = document.location.pathname;
ga("send", "pageview", path + "?q=" + this.value)
}
})
}
})
</script>
<script async src="https://www.google-analytics.com/analytics.js"></script>
</head>
<body dir="ltr" data-md-color-primary="indigo" data-md-color-accent="indigo">
<svg class="md-svg">
<defs>
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448" viewBox="0 0 416 448" id="__github"><path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19T128 352t-18.125-8.5-10.75-19T96 304t3.125-20.5 10.75-19T128 256t18.125 8.5 10.75 19T160 304zm160 0q0 10-3.125 20.5t-10.75 19T288 352t-18.125-8.5-10.75-19T256 304t3.125-20.5 10.75-19T288 256t18.125 8.5 10.75 19T320 304zm40 0q0-30-17.25-51T296 232q-10.25 0-48.75 5.25Q229.5 240 208 240t-39.25-2.75Q130.75 232 120 232q-29.5 0-46.75 21T56 304q0 22 8 38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0 37.25-1.75t35-7.375 30.5-15 20.25-25.75T360 304zm56-44q0 51.75-15.25 82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5T212 416q-19.5 0-35.5-.75t-36.875-3.125-38.125-7.5-34.25-12.875T37 371.5t-21.5-28.75Q0 312 0 260q0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25 30.875Q171.5 96 212 96q37 0 70 8 26.25-20.5 46.75-30.25T376 64q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34 99.5z"/></svg>
</defs>
</svg>
<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" data-md-component="overlay" for="__drawer"></label>
<a href="#_1" tabindex="1" class="md-skip">
跳转至
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="../.." title="HttpRunner V2.x 中文使用文档" class="md-header-nav__button md-logo">
<i class="md-icon"></i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
HttpRunner V2.x 中文使用文档
</span>
<span class="md-header-nav__topic">
参数化数据驱动
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></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" placeholder="搜索" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
键入以开始搜索
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://github.com/HttpRunner/HttpRunner" title="前往 Github 仓库" class="md-source" data-md-source="github">
<div class="md-source__icon">
<svg viewBox="0 0 24 24" width="24" height="24">
<use xlink:href="#__github" width="24" height="24"></use>
</svg>
</div>
<div class="md-source__repository">
HttpRunner
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main" role="main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="../.." title="HttpRunner V2.x 中文使用文档" class="md-nav__button md-logo">
<i class="md-icon"></i>
</a>
HttpRunner V2.x 中文使用文档
</label>
<div class="md-nav__source">
<a href="https://github.com/HttpRunner/HttpRunner" title="前往 Github 仓库" class="md-source" data-md-source="github">
<div class="md-source__icon">
<svg viewBox="0 0 24 24" width="24" height="24">
<use xlink:href="#__github" width="24" height="24"></use>
</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="../.." title="介绍" class="md-nav__link">
介绍
</a>
</li>
<li class="md-nav__item">
<a href="../../Installation/" title="安装说明" class="md-nav__link">
安装说明
</a>
</li>
<li class="md-nav__item">
<a href="../../quickstart/" title="快速上手" class="md-nav__link">
快速上手
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-4" type="checkbox" id="nav-4">
<label class="md-nav__link" for="nav-4">
基础概念
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-4">
基础概念
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../concept/nominal/" title="名词解释" class="md-nav__link">
名词解释
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-5" type="checkbox" id="nav-5" checked>
<label class="md-nav__link" for="nav-5">
测试准备
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-5">
测试准备
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../record/" title="录制生成用例" class="md-nav__link">
录制生成用例
</a>
</li>
<li class="md-nav__item">
<a href="../project-structure/" title="项目文件组织" class="md-nav__link">
项目文件组织
</a>
</li>
<li class="md-nav__item">
<a href="../testcase-structure/" title="测试用例组织" class="md-nav__link">
测试用例组织
</a>
</li>
<li class="md-nav__item">
<a href="../request-hook/" title="hook机制" class="md-nav__link">
hook机制
</a>
</li>
<li class="md-nav__item">
<a href="../dot-env/" title="环境变量" class="md-nav__link">
环境变量
</a>
</li>
<li class="md-nav__item">
<a href="../testcase-layer/" title="测试用例分层" class="md-nav__link">
测试用例分层
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
参数化数据驱动
</label>
<a href="./" title="参数化数据驱动" class="md-nav__link md-nav__link--active">
参数化数据驱动
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">目录</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#_1" class="md-nav__link">
介绍
</a>
</li>
<li class="md-nav__item">
<a href="#testsuite" class="md-nav__link">
测试用例集testsuite准备
</a>
</li>
<li class="md-nav__item">
<a href="#_2" class="md-nav__link">
参数配置概述
</a>
</li>
<li class="md-nav__item">
<a href="#_3" class="md-nav__link">
参数配置详解
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#_4" class="md-nav__link">
独立参数 &amp; 直接指定参数列表
</a>
</li>
<li class="md-nav__item">
<a href="#_5" class="md-nav__link">
关联参数 &amp; 直接指定参数列表
</a>
</li>
<li class="md-nav__item">
<a href="#csv" class="md-nav__link">
独立参数 &amp; 引用 CSV 文件
</a>
</li>
<li class="md-nav__item">
<a href="#csv_1" class="md-nav__link">
关联参数 &amp; 引用 CSV 文件
</a>
</li>
<li class="md-nav__item">
<a href="#_6" class="md-nav__link">
独立参数 &amp; 引用自定义函数
</a>
</li>
<li class="md-nav__item">
<a href="#_7" class="md-nav__link">
关联参数 &amp; 引用自定义函数
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#_8" class="md-nav__link">
参数化运行
</a>
</li>
<li class="md-nav__item">
<a href="#_9" class="md-nav__link">
案例演示
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../validate-pretty/" title="Validate & Prettify" class="md-nav__link">
Validate & Prettify
</a>
</li>
<li class="md-nav__item">
<a href="../security/" title="信息安全" class="md-nav__link">
信息安全
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-6" type="checkbox" id="nav-6">
<label class="md-nav__link" for="nav-6">
测试执行
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-6">
测试执行
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../run-tests/cli/" title="运行测试(CLI)" class="md-nav__link">
运行测试(CLI)
</a>
</li>
<li class="md-nav__item">
<a href="../../run-tests/report/" title="测试报告" class="md-nav__link">
测试报告
</a>
</li>
<li class="md-nav__item">
<a href="../../run-tests/load-test/" title="性能测试" class="md-nav__link">
性能测试
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-7" type="checkbox" id="nav-7">
<label class="md-nav__link" for="nav-7">
开发扩展
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-7">
开发扩展
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../development/architecture/" title="Pipline" class="md-nav__link">
Pipline
</a>
</li>
<li class="md-nav__item">
<a href="../../development/dev-api/" title="基础库调用" class="md-nav__link">
基础库调用
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../FAQ/" title="FAQ" class="md-nav__link">
FAQ
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-9" type="checkbox" id="nav-9">
<label class="md-nav__link" for="nav-9">
实践案例
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-9">
实践案例
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../examples/testerhome-login/" title="TesterHome 登录" class="md-nav__link">
TesterHome 登录
</a>
</li>
<li class="md-nav__item">
<a href="../../examples/demo-klook/" title="klook" class="md-nav__link">
klook
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../related-docs/" title="相关资料" class="md-nav__link">
相关资料
</a>
</li>
<li class="md-nav__item">
<a href="../../CHANGELOG/" title="CHANGELOG" class="md-nav__link">
CHANGELOG
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">目录</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#_1" class="md-nav__link">
介绍
</a>
</li>
<li class="md-nav__item">
<a href="#testsuite" class="md-nav__link">
测试用例集testsuite准备
</a>
</li>
<li class="md-nav__item">
<a href="#_2" class="md-nav__link">
参数配置概述
</a>
</li>
<li class="md-nav__item">
<a href="#_3" class="md-nav__link">
参数配置详解
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#_4" class="md-nav__link">
独立参数 &amp; 直接指定参数列表
</a>
</li>
<li class="md-nav__item">
<a href="#_5" class="md-nav__link">
关联参数 &amp; 直接指定参数列表
</a>
</li>
<li class="md-nav__item">
<a href="#csv" class="md-nav__link">
独立参数 &amp; 引用 CSV 文件
</a>
</li>
<li class="md-nav__item">
<a href="#csv_1" class="md-nav__link">
关联参数 &amp; 引用 CSV 文件
</a>
</li>
<li class="md-nav__item">
<a href="#_6" class="md-nav__link">
独立参数 &amp; 引用自定义函数
</a>
</li>
<li class="md-nav__item">
<a href="#_7" class="md-nav__link">
关联参数 &amp; 引用自定义函数
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#_8" class="md-nav__link">
参数化运行
</a>
</li>
<li class="md-nav__item">
<a href="#_9" class="md-nav__link">
案例演示
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1>参数化数据驱动</h1>
<h2 id="_1">介绍<a class="headerlink" href="#_1" title="Permanent link">&para;</a></h2>
<p>在自动化测试中,经常会遇到如下场景:</p>
<ul>
<li>测试搜索功能,只有一个搜索输入框,但有 10 种不同类型的搜索关键字;</li>
<li>测试账号登录功能,需要输入用户名和密码,按照等价类划分后有 20 种组合情况。</li>
</ul>
<p>这里只是随意找了两个典型的例子,相信大家都有遇到过很多类似的场景。总结下来,就是在我们的自动化测试脚本中存在参数,并且我们需要采用不同的参数去运行。</p>
<p>经过概括,参数基本上分为两种类型:</p>
<ul>
<li>单个独立参数:例如前面的第一种场景,我们只需要变换搜索关键字这一个参数</li>
<li>多个具有关联性的参数:例如前面的第二种场景,我们需要变换用户名和密码两个参数,并且这两个参数需要关联组合</li>
</ul>
<p>然后,对于参数而言,我们可能具有一个参数列表,在脚本运行时需要按照不同的规则去取值,例如顺序取值、随机取值、循环取值等等。</p>
<p>这就是典型的参数化和数据驱动。</p>
<p>如需了解 HttpRunner 参数化数据驱动机制的实现原理和技术细节,可前往阅读<a href="http://debugtalk.com/post/httprunner-data-driven/">《HttpRunner 实现参数化数据驱动机制》</a></p>
<h2 id="testsuite">测试用例集testsuite准备<a class="headerlink" href="#testsuite" title="Permanent link">&para;</a></h2>
<p>从 2.0.0 版本开始HttpRunner 不再支持在测试用例文件中进行参数化配置;参数化的功能需要在 testsuite 中实现。变更的目的是让测试用例testcase的概念更纯粹关于测试用例和测试用例集的概念定义详见<a href="/prepare/parameters/">《测试用例组织》</a></p>
<p>参数化机制需要在测试用例集testsuite中实现。如需实现数据驱动机制需要创建一个 testsuite在 testsuite 中引用测试用例,并定义参数化配置。</p>
<p>测试用例集testsuite的格式如下所示</p>
<div class="codehilite"><pre><span></span><span class="nt">config</span><span class="p">:</span>
<span class="nt">name</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">testsuite description</span>
<span class="nt">testcases</span><span class="p">:</span>
<span class="nt">testcase1_name</span><span class="p">:</span>
<span class="nt">testcase</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">/path/to/testcase1</span>
<span class="nt">testcase2_name</span><span class="p">:</span>
<span class="nt">testcase</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">/path/to/testcase2</span>
</pre></div>
<p>需要注意的是testsuite 和 testcase 的格式存在较大区别,详见<a href="/prepare/testcase-structure/">《测试用例组织》</a></p>
<h2 id="_2">参数配置概述<a class="headerlink" href="#_2" title="Permanent link">&para;</a></h2>
<p>如需对某测试用例testcase实现参数化数据驱动需要使用 <code>parameters</code> 关键字,定义参数名称并指定数据源取值方式。</p>
<p>参数名称的定义分为两种情况:</p>
<ul>
<li>独立参数单独进行定义;</li>
<li>多个参数具有关联性的参数需要将其定义在一起,采用短横线(<code>-</code>)进行连接。</li>
</ul>
<p>数据源指定支持三种方式:</p>
<ul>
<li>在 YAML/JSON 中直接指定参数列表:该种方式最为简单易用,适合参数列表比较小的情况</li>
<li>通过内置的 parameterize可简写为P函数引用 CSV 文件:该种方式需要准备 CSV 数据文件,适合数据量比较大的情况</li>
<li>调用 debugtalk.py 中自定义的函数生成参数列表:该种方式最为灵活,可通过自定义 Python 函数实现任意场景的数据驱动机制,当需要动态生成参数列表时也需要选择该种方式</li>
</ul>
<p>三种方式可根据实际项目需求进行灵活选择,同时支持多种方式的组合使用。假如测试用例中定义了多个参数,那么测试用例在运行时会对参数进行笛卡尔积组合,覆盖所有参数组合情况。</p>
<p>使用方式概览如下:</p>
<div class="codehilite"><pre><span></span><span class="nt">config</span><span class="p">:</span>
<span class="nt">name</span><span class="p">:</span> <span class="s">&quot;demo&quot;</span>
<span class="nt">testcases</span><span class="p">:</span>
<span class="nt">testcase1_name</span><span class="p">:</span>
<span class="nt">testcase</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">/path/to/testcase1</span>
<span class="nt">parameters</span><span class="p">:</span>
<span class="nt">user_agent</span><span class="p">:</span> <span class="p p-Indicator">[</span><span class="s">&quot;iOS/10.1&quot;</span><span class="p p-Indicator">,</span> <span class="s">&quot;iOS/10.2&quot;</span><span class="p p-Indicator">,</span> <span class="s">&quot;iOS/10.3&quot;</span><span class="p p-Indicator">]</span>
<span class="nt">user_id</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">${P(user_id.csv)}</span>
<span class="nt">username-password</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">${get_account(10)}</span>
</pre></div>
<h2 id="_3">参数配置详解<a class="headerlink" href="#_3" title="Permanent link">&para;</a></h2>
<p>将参数名称定义和数据源指定方式进行组合,共有 6 种形式。现分别针对每一类情况进行详细说明。</p>
<h3 id="_4">独立参数 &amp; 直接指定参数列表<a class="headerlink" href="#_4" title="Permanent link">&para;</a></h3>
<p>对于参数列表比较小的情况,最简单的方式是直接在 YAML/JSON 中指定参数列表内容。</p>
<p>例如,对于独立参数 <code>user_id</code>,参数列表为 <code>[1001, 1002, 1003, 1004]</code>,那么就可以按照如下方式进行配置:</p>
<div class="codehilite"><pre><span></span><span class="nt">config</span><span class="p">:</span>
<span class="nt">name</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">testcase description</span>
<span class="nt">testcases</span><span class="p">:</span>
<span class="nt">create user</span><span class="p">:</span>
<span class="nt">testcase</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">demo-quickstart-6.yml</span>
<span class="nt">parameters</span><span class="p">:</span>
<span class="nt">user_id</span><span class="p">:</span> <span class="p p-Indicator">[</span><span class="nv">1001</span><span class="p p-Indicator">,</span> <span class="nv">1002</span><span class="p p-Indicator">,</span> <span class="nv">1003</span><span class="p p-Indicator">,</span> <span class="nv">1004</span><span class="p p-Indicator">]</span>
</pre></div>
<p>进行该配置后,测试用例在运行时就会对 user_id 实现数据驱动,即分别使用 <code>[1001, 1002, 1003, 1004]</code> 四个值运行测试用例。</p>
<details>
<summary>点击查看运行日志</summary>
<div class="codehilite"><pre><span></span>$ hrun docs/data/demo-quickstart-7.json
INFO Start to run testcase: create user 1001
/api/get-token
INFO POST http://127.0.0.1:5000/api/get-token
INFO status_code: 200, response_time(ms): 8.95 ms, response_length: 46 bytes
.
/api/users/1001
INFO POST http://127.0.0.1:5000/api/users/1001
INFO status_code: 201, response_time(ms): 3.02 ms, response_length: 54 bytes
.
----------------------------------------------------------------------
Ran 2 tests in 0.021s
OK
INFO Start to run testcase: create user 1002
/api/get-token
INFO POST http://127.0.0.1:5000/api/get-token
INFO status_code: 200, response_time(ms): 2.78 ms, response_length: 46 bytes
.
/api/users/1002
INFO POST http://127.0.0.1:5000/api/users/1002
INFO status_code: 201, response_time(ms): 2.84 ms, response_length: 54 bytes
.
----------------------------------------------------------------------
Ran 2 tests in 0.007s
OK
INFO Start to run testcase: create user 1003
/api/get-token
INFO POST http://127.0.0.1:5000/api/get-token
INFO status_code: 200, response_time(ms): 2.92 ms, response_length: 46 bytes
.
/api/users/1003
INFO POST http://127.0.0.1:5000/api/users/1003
INFO status_code: 201, response_time(ms): 5.56 ms, response_length: 54 bytes
.
----------------------------------------------------------------------
Ran 2 tests in 0.011s
OK
INFO Start to run testcase: create user 1004
/api/get-token
INFO POST http://127.0.0.1:5000/api/get-token
INFO status_code: 200, response_time(ms): 5.25 ms, response_length: 46 bytes
.
/api/users/1004
INFO POST http://127.0.0.1:5000/api/users/1004
INFO status_code: 201, response_time(ms): 7.02 ms, response_length: 54 bytes
.
----------------------------------------------------------------------
Ran 2 tests in 0.016s
OK
INFO Start to render Html report ...
INFO Generated Html report: /Users/debugtalk/MyProjects/HttpRunner-dev/httprunner-docs-v2x/reports/1548518757.html
</pre></div>
</details>
<p>可以看出,测试用例总共运行了 4 次,并且每次运行时都是采用的不同 user_id。</p>
<h3 id="_5">关联参数 &amp; 直接指定参数列表<a class="headerlink" href="#_5" title="Permanent link">&para;</a></h3>
<p>对于具有关联性的多个参数,例如 username 和 password那么就可以按照如下方式进行配置</p>
<div class="codehilite"><pre><span></span><span class="nt">config</span><span class="p">:</span>
<span class="nt">name</span><span class="p">:</span> <span class="s">&quot;demo&quot;</span>
<span class="nt">testcases</span><span class="p">:</span>
<span class="nt">testcase1_name</span><span class="p">:</span>
<span class="nt">testcase</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">/path/to/testcase1</span>
<span class="nt">parameters</span><span class="p">:</span>
<span class="nt">username-password</span><span class="p">:</span>
<span class="p p-Indicator">-</span> <span class="p p-Indicator">[</span><span class="s">&quot;user1&quot;</span><span class="p p-Indicator">,</span> <span class="s">&quot;111111&quot;</span><span class="p p-Indicator">]</span>
<span class="p p-Indicator">-</span> <span class="p p-Indicator">[</span><span class="s">&quot;user2&quot;</span><span class="p p-Indicator">,</span> <span class="s">&quot;222222&quot;</span><span class="p p-Indicator">]</span>
<span class="p p-Indicator">-</span> <span class="p p-Indicator">[</span><span class="s">&quot;user3&quot;</span><span class="p p-Indicator">,</span> <span class="s">&quot;333333&quot;</span><span class="p p-Indicator">]</span>
</pre></div>
<p>进行该配置后,测试用例在运行时就会对 username 和 password 实现数据驱动,即分别使用 <code>{"username": "user1", "password": "111111"}</code><code>{"username": "user2", "password": "222222"}</code><code>{"username": "user3", "password": "333333"}</code> 运行 3 次测试,并且保证参数值总是成对使用。</p>
<h3 id="csv">独立参数 &amp; 引用 CSV 文件<a class="headerlink" href="#csv" title="Permanent link">&para;</a></h3>
<p>对于已有参数列表,并且数据量比较大的情况,比较适合的方式是将参数列表值存储在 CSV 数据文件中。</p>
<p>对于 CSV 数据文件,需要遵循如下几项约定的规则:</p>
<ul>
<li>CSV 文件中的第一行必须为参数名称,从第二行开始为参数值,每个(组)值占一行;</li>
<li>若同一个 CSV 文件中具有多个参数,则参数名称和数值的间隔符需实用英文逗号;</li>
<li>在 YAML/JSON 文件引用 CSV 文件时文件路径为基于项目根目录debugtalk.py 所在路径)的相对路径。</li>
</ul>
<p>例如user_id 的参数取值范围为 10012000那么我们就可以创建 user_id.csv并且在文件中按照如下形式进行描述。</p>
<div class="codehilite"><pre><span></span>user_id
1001
1002
...
1999
2000
</pre></div>
<p>然后在 YAML/JSON 测试用例文件中,就可以通过内置的 <code>parameterize</code>(可简写为 <code>P</code>)函数引用 CSV 文件。</p>
<p>假设项目的根目录下有 data 文件夹user_id.csv 位于其中,那么 user_id.csv 的引用描述如下:</p>
<div class="codehilite"><pre><span></span><span class="nt">config</span><span class="p">:</span>
<span class="nt">name</span><span class="p">:</span> <span class="s">&quot;demo&quot;</span>
<span class="nt">testcases</span><span class="p">:</span>
<span class="nt">testcase1_name</span><span class="p">:</span>
<span class="nt">testcase</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">/path/to/testcase1</span>
<span class="nt">parameters</span><span class="p">:</span>
<span class="nt">user_id</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">${P(data/user_id.csv)}</span>
</pre></div>
<p><code>P</code> 函数的参数CSV 文件路径)是相对于项目根目录的相对路径。当然,这里也可以使用 CSV 文件在系统中的绝对路径,不过这样的话在项目路径变动时就会出现问题,因此推荐使用相对路径的形式。</p>
<h3 id="csv_1">关联参数 &amp; 引用 CSV 文件<a class="headerlink" href="#csv_1" title="Permanent link">&para;</a></h3>
<p>对于具有关联性的多个参数,例如 username 和 password那么就可以创建 <a href="/data/account.csv">account.csv</a>,并在文件中按照如下形式进行描述。</p>
<div class="codehilite"><pre><span></span>username,password
test1,111111
test2,222222
test3,333333
</pre></div>
<p>然后在 YAML/JSON 测试用例文件中,就可以通过内置的 <code>parameterize</code>(可简写为 <code>P</code>)函数引用 CSV 文件。</p>
<p>假设项目的根目录下有 data 文件夹account.csv 位于其中,那么 account.csv 的引用描述如下:</p>
<div class="codehilite"><pre><span></span><span class="nt">config</span><span class="p">:</span>
<span class="nt">name</span><span class="p">:</span> <span class="s">&quot;demo&quot;</span>
<span class="nt">testcases</span><span class="p">:</span>
<span class="nt">testcase1_name</span><span class="p">:</span>
<span class="nt">testcase</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">/path/to/testcase1</span>
<span class="nt">parameters</span><span class="p">:</span>
<span class="nt">username-password</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">${P(data/account.csv)}</span>
</pre></div>
<p>需要说明的是,在 parameters 中指定的参数名称必须与 CSV 文件中第一行的参数名称一致,顺序可以不一致,参数个数也可以不一致。</p>
<p>例如,在 <a href="/data/account.csv">account.csv</a> 文件中可以包含多个参数username、password、phone、age</p>
<div class="codehilite"><pre><span></span>username,password,phone,age
test1,111111,18600000001,21
test2,222222,18600000002,22
test3,333333,18600000003,23
</pre></div>
<p>而在 YAML/JSON 测试用例文件中指定参数时,可以只使用部分参数,并且参数顺序无需与 CSV 文件中参数名称的顺序一致。</p>
<div class="codehilite"><pre><span></span><span class="nt">config</span><span class="p">:</span>
<span class="nt">name</span><span class="p">:</span> <span class="s">&quot;demo&quot;</span>
<span class="nt">testcases</span><span class="p">:</span>
<span class="nt">testcase1_name</span><span class="p">:</span>
<span class="nt">testcase</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">/path/to/testcase1</span>
<span class="nt">parameters</span><span class="p">:</span>
<span class="nt">phone-username</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">${P(account.csv)}</span>
</pre></div>
<h3 id="_6">独立参数 &amp; 引用自定义函数<a class="headerlink" href="#_6" title="Permanent link">&para;</a></h3>
<p>对于没有现成参数列表,或者需要更灵活的方式动态生成参数的情况,可以通过在 debugtalk.py 中自定义函数生成参数列表,并在 YAML/JSON 引用自定义函数的方式。</p>
<p>例如,若需对 user_id 进行参数化数据驱动,参数取值范围为 10011004那么就可以在 debugtalk.py 中定义一个函数,返回参数列表。</p>
<div class="codehilite"><pre><span></span><span class="k">def</span> <span class="nf">get_user_id</span><span class="p">():</span>
<span class="k">return</span> <span class="p">[</span>
<span class="p">{</span><span class="s2">&quot;user_id&quot;</span><span class="p">:</span> <span class="mi">1001</span><span class="p">},</span>
<span class="p">{</span><span class="s2">&quot;user_id&quot;</span><span class="p">:</span> <span class="mi">1002</span><span class="p">},</span>
<span class="p">{</span><span class="s2">&quot;user_id&quot;</span><span class="p">:</span> <span class="mi">1003</span><span class="p">},</span>
<span class="p">{</span><span class="s2">&quot;user_id&quot;</span><span class="p">:</span> <span class="mi">1004</span><span class="p">}</span>
<span class="p">]</span>
</pre></div>
<p>然后,在 YAML/JSON 的 parameters 中就可以通过调用自定义函数的形式来指定数据源。</p>
<div class="codehilite"><pre><span></span><span class="nt">config</span><span class="p">:</span>
<span class="nt">name</span><span class="p">:</span> <span class="s">&quot;demo&quot;</span>
<span class="nt">testcases</span><span class="p">:</span>
<span class="nt">testcase1_name</span><span class="p">:</span>
<span class="nt">testcase</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">/path/to/testcase1</span>
<span class="nt">parameters</span><span class="p">:</span>
<span class="nt">user_id</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">${get_user_id()}</span>
</pre></div>
<p>另外,通过函数的传参机制,还可以实现更灵活的参数生成功能,在调用函数时指定需要生成的参数个数。</p>
<h3 id="_7">关联参数 &amp; 引用自定义函数<a class="headerlink" href="#_7" title="Permanent link">&para;</a></h3>
<p>对于具有关联性的多个参数,实现方式也类似。</p>
<p>例如,在 debugtalk.py 中定义函数 get_account生成指定数量的账号密码参数列表。</p>
<div class="codehilite"><pre><span></span><span class="k">def</span> <span class="nf">get_account</span><span class="p">(</span><span class="n">num</span><span class="p">):</span>
<span class="n">accounts</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">index</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">num</span><span class="o">+</span><span class="mi">1</span><span class="p">):</span>
<span class="n">accounts</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
<span class="p">{</span><span class="s2">&quot;username&quot;</span><span class="p">:</span> <span class="s2">&quot;user</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">index</span><span class="p">,</span> <span class="s2">&quot;password&quot;</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="n">index</span><span class="p">)</span> <span class="o">*</span> <span class="mi">6</span><span class="p">},</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">accounts</span>
</pre></div>
<p>那么在 YAML/JSON 的 parameters 中就可以调用自定义函数生成指定数量的参数列表。</p>
<div class="codehilite"><pre><span></span><span class="nt">config</span><span class="p">:</span>
<span class="nt">name</span><span class="p">:</span> <span class="s">&quot;demo&quot;</span>
<span class="nt">testcases</span><span class="p">:</span>
<span class="nt">testcase1_name</span><span class="p">:</span>
<span class="nt">testcase</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">/path/to/testcase1</span>
<span class="nt">parameters</span><span class="p">:</span>
<span class="nt">username-password</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">${get_account(10)}</span>
</pre></div>
<blockquote>
<p>需要注意的是,在自定义函数中,生成的参数列表必须为 <code>list of dict</code> 的数据结构,该设计主要是为了与 CSV 文件的处理机制保持一致。</p>
</blockquote>
<h2 id="_8">参数化运行<a class="headerlink" href="#_8" title="Permanent link">&para;</a></h2>
<p>完成以上参数定义和数据源准备工作之后,参数化运行与普通测试用例的运行完全一致。</p>
<p>采用 hrun 命令运行自动化测试:</p>
<div class="codehilite"><pre><span></span>$ hrun tests/data/demo_parameters.yml
</pre></div>
<p>采用 locusts 命令运行性能测试:</p>
<div class="codehilite"><pre><span></span>$ locusts -f tests/data/demo_parameters.yml
</pre></div>
<p>区别在于,自动化测试时遍历一遍后会终止执行,性能测试时每个并发用户都会循环遍历所有参数。</p>
<h2 id="_9">案例演示<a class="headerlink" href="#_9" title="Permanent link">&para;</a></h2>
<p>假设我们有一个获取 token 的<a href="/data/demo-testcase-get-token.yml">测试用例</a></p>
<details>
<summary>点击查看 YAML 测试用例</summary>
<div class="codehilite"><pre><span></span><span class="p p-Indicator">-</span> <span class="nt">config</span><span class="p">:</span>
<span class="nt">name</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">get token</span>
<span class="nt">base_url</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">http://127.0.0.1:5000</span>
<span class="nt">variables</span><span class="p">:</span>
<span class="nt">device_sn</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">${gen_random_string(15)}</span>
<span class="nt">os_platform</span><span class="p">:</span> <span class="s">&#39;ios&#39;</span>
<span class="nt">app_version</span><span class="p">:</span> <span class="s">&#39;2.8.6&#39;</span>
<span class="p p-Indicator">-</span> <span class="nt">test</span><span class="p">:</span>
<span class="nt">name</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">get token with $device_sn, $os_platform, $app_version</span>
<span class="nt">request</span><span class="p">:</span>
<span class="nt">headers</span><span class="p">:</span>
<span class="nt">Content-Type</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">application/json</span>
<span class="nt">User-Agent</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">python-requests/2.18.4</span>
<span class="nt">app_version</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">$app_version</span>
<span class="nt">device_sn</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">$device_sn</span>
<span class="nt">os_platform</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">$os_platform</span>
<span class="nt">json</span><span class="p">:</span>
<span class="nt">sign</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">${get_sign($device_sn, $os_platform, $app_version)}</span>
<span class="nt">method</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">POST</span>
<span class="nt">url</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">/api/get-token</span>
<span class="nt">extract</span><span class="p">:</span>
<span class="nt">token</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">content.token</span>
<span class="nt">validate</span><span class="p">:</span>
<span class="p p-Indicator">-</span> <span class="nt">eq</span><span class="p">:</span> <span class="p p-Indicator">[</span><span class="nv">status_code</span><span class="p p-Indicator">,</span> <span class="nv">200</span><span class="p p-Indicator">]</span>
<span class="p p-Indicator">-</span> <span class="nt">eq</span><span class="p">:</span> <span class="p p-Indicator">[</span><span class="nv">headers.Content-Type</span><span class="p p-Indicator">,</span> <span class="nv">application/json</span><span class="p p-Indicator">]</span>
<span class="p p-Indicator">-</span> <span class="nt">eq</span><span class="p">:</span> <span class="p p-Indicator">[</span><span class="nv">content.success</span><span class="p p-Indicator">,</span> <span class="nv">true</span><span class="p p-Indicator">]</span>
</pre></div>
</details>
<p>如果我们需要使用 device_sn、app_version 和 os_platform 这三个参数来进行参数化数据驱动,那么就可以创建一个 <a href="/data/demo-parameters-get-token.yml">testsuite</a>,并且进行参数化配置。</p>
<div class="codehilite"><pre><span></span><span class="nt">config</span><span class="p">:</span>
<span class="nt">name</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">get token with parameters</span>
<span class="nt">testcases</span><span class="p">:</span>
<span class="l l-Scalar l-Scalar-Plain">get token with $user_agent, $app_version, $os_platform</span><span class="p p-Indicator">:</span>
<span class="nt">testcase</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">demo-testcase-get-token.yml</span>
<span class="nt">parameters</span><span class="p">:</span>
<span class="nt">user_agent</span><span class="p">:</span> <span class="p p-Indicator">[</span><span class="s">&quot;iOS/10.1&quot;</span><span class="p p-Indicator">,</span> <span class="s">&quot;iOS/10.2&quot;</span><span class="p p-Indicator">,</span> <span class="s">&quot;iOS/10.3&quot;</span><span class="p p-Indicator">]</span>
<span class="nt">app_version</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">${P(app_version.csv)}</span>
<span class="nt">os_platform</span><span class="p">:</span> <span class="l l-Scalar l-Scalar-Plain">${get_os_platform()}</span>
</pre></div>
<p>其中,<code>user_agent</code> 使用了直接指定参数列表的形式。</p>
<p><a href="/data/app_version.csv">app_version</a> 通过 CSV 文件进行参数配置,对应的文件内容为:</p>
<div class="codehilite"><pre><span></span>app_version
2.8.5
2.8.6
</pre></div>
<p>os_platform 使用自定义函数的形式生成参数列表,对应的函数内容为:</p>
<div class="codehilite"><pre><span></span><span class="k">def</span> <span class="nf">get_os_platform</span><span class="p">():</span>
<span class="k">return</span> <span class="p">[</span>
<span class="p">{</span><span class="s2">&quot;os_platform&quot;</span><span class="p">:</span> <span class="s2">&quot;ios&quot;</span><span class="p">},</span>
<span class="p">{</span><span class="s2">&quot;os_platform&quot;</span><span class="p">:</span> <span class="s2">&quot;android&quot;</span><span class="p">}</span>
<span class="p">]</span>
</pre></div>
<p>那么,经过笛卡尔积组合,应该总共有 <code>3*2*2=12</code> 种参数组合情况。</p>
<details>
<summary>点击查看完整运行日志</summary>
<div class="codehilite"><pre><span></span>$ hrun docs/data/demo-parameters-get-token.yml
INFO Start to run testcase: get token with iOS/10.1, 2.8.5, ios
get token with PBJda7SXM2ReWlu, ios, 2.8.5
INFO POST http://127.0.0.1:5000/api/get-token
INFO status_code: 200, response_time(ms): 10.66 ms, response_length: 46 bytes
.
----------------------------------------------------------------------
Ran 1 test in 0.026s
OK
INFO Start to run testcase: get token with iOS/10.1, 2.8.5, android
get token with PBJda7SXM2ReWlu, android, 2.8.5
INFO POST http://127.0.0.1:5000/api/get-token
INFO status_code: 200, response_time(ms): 3.03 ms, response_length: 46 bytes
.
----------------------------------------------------------------------
Ran 1 test in 0.004s
OK
INFO Start to run testcase: get token with iOS/10.1, 2.8.6, ios
get token with PBJda7SXM2ReWlu, ios, 2.8.6
INFO POST http://127.0.0.1:5000/api/get-token
INFO status_code: 200, response_time(ms): 10.76 ms, response_length: 46 bytes
.
----------------------------------------------------------------------
Ran 1 test in 0.012s
OK
INFO Start to run testcase: get token with iOS/10.1, 2.8.6, android
get token with PBJda7SXM2ReWlu, android, 2.8.6
INFO POST http://127.0.0.1:5000/api/get-token
INFO status_code: 200, response_time(ms): 4.49 ms, response_length: 46 bytes
.
----------------------------------------------------------------------
Ran 1 test in 0.006s
OK
INFO Start to run testcase: get token with iOS/10.2, 2.8.5, ios
get token with PBJda7SXM2ReWlu, ios, 2.8.5
INFO POST http://127.0.0.1:5000/api/get-token
INFO status_code: 200, response_time(ms): 4.39 ms, response_length: 46 bytes
.
----------------------------------------------------------------------
Ran 1 test in 0.006s
OK
INFO Start to run testcase: get token with iOS/10.2, 2.8.5, android
get token with PBJda7SXM2ReWlu, android, 2.8.5
INFO POST http://127.0.0.1:5000/api/get-token
INFO status_code: 200, response_time(ms): 4.04 ms, response_length: 46 bytes
.
----------------------------------------------------------------------
Ran 1 test in 0.005s
OK
INFO Start to run testcase: get token with iOS/10.2, 2.8.6, ios
get token with PBJda7SXM2ReWlu, ios, 2.8.6
INFO POST http://127.0.0.1:5000/api/get-token
INFO status_code: 200, response_time(ms): 3.44 ms, response_length: 46 bytes
.
----------------------------------------------------------------------
Ran 1 test in 0.004s
OK
INFO Start to run testcase: get token with iOS/10.2, 2.8.6, android
get token with PBJda7SXM2ReWlu, android, 2.8.6
INFO POST http://127.0.0.1:5000/api/get-token
INFO status_code: 200, response_time(ms): 4.03 ms, response_length: 46 bytes
.
----------------------------------------------------------------------
Ran 1 test in 0.005s
OK
INFO Start to run testcase: get token with iOS/10.3, 2.8.5, ios
get token with PBJda7SXM2ReWlu, ios, 2.8.5
INFO POST http://127.0.0.1:5000/api/get-token
INFO status_code: 200, response_time(ms): 5.14 ms, response_length: 46 bytes
.
----------------------------------------------------------------------
Ran 1 test in 0.008s
OK
INFO Start to run testcase: get token with iOS/10.3, 2.8.5, android
get token with PBJda7SXM2ReWlu, android, 2.8.5
INFO POST http://127.0.0.1:5000/api/get-token
INFO status_code: 200, response_time(ms): 7.62 ms, response_length: 46 bytes
.
----------------------------------------------------------------------
Ran 1 test in 0.010s
OK
INFO Start to run testcase: get token with iOS/10.3, 2.8.6, ios
get token with PBJda7SXM2ReWlu, ios, 2.8.6
INFO POST http://127.0.0.1:5000/api/get-token
INFO status_code: 200, response_time(ms): 4.88 ms, response_length: 46 bytes
.
----------------------------------------------------------------------
Ran 1 test in 0.006s
OK
INFO Start to run testcase: get token with iOS/10.3, 2.8.6, android
get token with PBJda7SXM2ReWlu, android, 2.8.6
INFO POST http://127.0.0.1:5000/api/get-token
INFO status_code: 200, response_time(ms): 5.41 ms, response_length: 46 bytes
.
----------------------------------------------------------------------
Ran 1 test in 0.008s
OK
INFO Start to render Html report ...
INFO Generated Html report: /Users/debugtalk/MyProjects/HttpRunner-dev/httprunner-docs-v2x/reports/1551950193.html
</pre></div>
</details>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../testcase-layer/" title="测试用例分层" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
上一页
</span>
测试用例分层
</span>
</div>
</a>
<a href="../validate-pretty/" title="Validate & Prettify" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
下一页
</span>
Validate & Prettify
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<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 - 2019 debugtalk
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
<div class="md-footer-social">
<link rel="stylesheet" href="../../assets/fonts/font-awesome.css">
<a href="https://debugtalk.com" class="md-footer-social__link fa fa-globe"></a>
<a href="https://github.com/httprunner" class="md-footer-social__link fa fa-github"></a>
</div>
</div>
</div>
</footer>
</div>
<script src="../../assets/javascripts/application.ac79c3b0.js"></script>
<script src="../../assets/javascripts/lunr/lunr.stemmer.support.js"></script>
<script>app.initialize({version:"1.0.4",url:{base:"../.."}})</script>
<script src="../../js/slardar.js"></script>
</body>
</html>