Postman学习部分资料整理

来源:互联网 发布:unity3d 联网授权 编辑:程序博客网 时间:2024/06/10 21:56
一、导入导出打包的应用
在Postman中导入导出我们的 测试数据包 和 工作环境 非常的方便:
导出数据包:

导出数据包.png
导出工作环境:

导出工作环境 1.png

导出工作环境 2.png
导入数据包:

导入数据包.png
导入工作环境:

导入工作环境.png
二、发送请求和查看响应
1.发送请求
Postman的界面分为 左边的侧边栏 和 右边的请求构建器 两部分。请求构建器允许你可以快速的创建几乎任何类型的请求。一个HTTP请求的四部分:URL、Method、Headers、Body,在Postman中都可以设置。

界面分布.png
URL:
在你构建request请求的时候,首先要设置的就是URL。在URL输入框中输入你请求的链接,你可以单击Params按钮,在编辑器中输入key-value格式的URL参数。
在URL地址栏中的输入和编辑器中输入的key-value参数,不会自动的编码为 URL-encoded,选中要编码的文本,右键选择EncodeURIComponent,手动编码参数值。

URL设置.png

手动编码.png
你可以单独的添加参数,Postman会自动的把他和URL整合到一起,如果你从其他的地方粘贴了URL过来,Postman也会自动的把 Params中的参数进行设置。
一些API端点使用路径变量,你可以在Postman中设置,他们位于两个/ 中,样式如下:

URL变量样式.png
如果你要设置他,单击Params按钮,你会发现key部分已被自动设置好了,根据需要填写value部分就行。
Headers:
单击Headers切换按钮,你可以在key-value编辑器中设置任何字符串作为header的名称。

编辑headers.png
受限的headers和cookies
不幸的是一些headers收到Chrome和XMLHttpRequest规范的限制,以下headers被屏蔽:
Accept-Charset
Accept-Encoding
Access-Control-Request-Headers
Access-Control-Request-Method
Connection
Content-Length
Cookie
Cookie 2
Content-Transfer-Encoding
Date
Expect
Host
Keep-Alive
Origin
Referer
TE
Trailer
Transfer-Encoding
Upgrade
User-Agent
Via
从Postman v0.9.6版本开始,我们可以使用拦截器来发送这些受限的headers:

拦截器.png
安装完成后点击切换就可以使用这些headers发送请求了。
headers预设
你可以保存常用的headers在headr prest里面:

headers预设.png
Method:
单击HTTP的请求方法按钮,在给出的下拉菜单中选择使用的方法即可,对应的方法需要body的,body部分便被设置为可填写。

Method设置.png
body部分编辑:
当我们发送请求需要填写body部分时,Postman几乎可以让我们发送任何类型的HTTP请求。body编辑器分为4个部分:
form-data

form-data.png
form-data是web表单默认的传输格式,编辑器允许你通过设置key-value形式的数据来模拟填充表单。你可以在最后的选项中选择添加文件。
urlencoded

urlencoded.png
这个编码格式同样可以通过设置key-value的方式作为URL的参数。
raw

raw.png
一个raw请求可以包含任何内容。在这里你可以设置我们常用的JSON 和 XML数据格式。
二进制

二进制.png
在这里你可以发送视频、音频、文本等文件。
2.处理响应
Postman的响应查看器允许你方便的查看API的响应是否正确。
一个API响应器包括Body、Headers、status code三部分。Body 和 Headers在不同的选项卡中,status code在收到响应时在标签行的最右边显示。
保存响应内容

保存响应内容.png
如果你在收藏夹中保存了request请求,你可以在请求收到的对应的响应中单击save按钮,指定一个response的名字,来保存对应额response。一个request对应的所有的response都是有效的。
当我们要查看我们保存的response的时候,只需要点击我们的发送的request选择我们要查看的response即可:

response.png
查看响应
Postman的body标签中有三种查看方式:Pretty、Raw、Preview
Pretty:

pretty.png
Pretty方式,可以让JSON 和 XML的响应内容显示的更美观规整。
Raw:

raw显示.png
显示最原始的数据,可以帮助你判断是否minified
Preview:

preview.png
可以帮你把HTML页面自动解析显示出来。
Headers

headrs.png
这里显示了一些键值对,表示了HTTP请求中header中的信息。
Cookies
Postman v0.8.x 版本可以显示浏览器的cookie。
3.身份验证
Basic Auth

基本认证.png
输入用户名和密码,点击 Update Request 生成 authorization header
Digest Auth

DigestAuth.png
Digest auth 比 Digest auth 更加复杂,使用当前request中的设置来生成authorization header,请确保在生成前你的设置的正确性。
OAuth 1.0

OAuth1.png
Postman的OAuth1.0工具让你可以生成支持OAuth1.0身份认证的请求,目前他不能获取access token。
OAuth 2.0

OAuth 2.0.png
Postman支持获取OAuth 2.0 token,并且可以非常简单的添加到request中。
从OAuth 2.0中获取access token,要遵循下面这些步骤:
  1. 在你的APP设置页面设置 https://www.getpostman.com/oauth2/callback作为 callback URL
  2. 获取 authorization URL, 从你的API提供者那里访问 token URL、 client ID 和 client secret。你可以设置一些API需要的参数范围来设置你再API中的访问级别。
  3. 按下 Request Token 按钮来启动OAuth 2.0 flow。如果一切设置正确,你将会被重定向到Postman的服务器,他将获取你的access token 并且发送到Postman的app,这样就给Postman添加了token,给他设置一个name,让你在以后可以快速的访问

OAuth 2.0设置.png
  1. access token将被保存在本地,显示在帮助列表。点击token名称,就可以把它添加到request中。
4.Requests History
所有你使用Postman发送的request都将保存在左侧边栏的History中,他会帮助你通过尝试不同的request来生成一个新的request,而不必浪费你太多的时间。你可以通过单击一个request的名字来加载他。

history.png
如果你创建了Postman的账户,你的历史数据将被同步到Postman的服务器,你可以在不同的平台上使用Postman的时候同步你的数据。
5.使用tab来控制多个请求
很多用户可能需要同时打开多个请求,你发送的request将被保持在当前的标签中,当你切换到其他的标签时,不用担心不能及时的接受response。

tabs.png
6.使用拦截器来读写cookie
和Mac上的应用不同,Chrome的应用本身并不支持获取cookie,你可以使用拦截器来实现这个功能。打开拦截器的时候,你可以检索特定域中的cookie,并发送包含cookie的request。
检索cookie:
  1. 启动拦截器

interceptor_cookies_1.png
  1. 在测试部分,你可以使用responseCookies对象,他将返回一个cookie对象的数组。使用postman.getResponseCookie(cookieName)检索cookie特定的名称。他将返回一个单独的cookie对象。
每个cookie都会包含下面这些属性:
domain、 hostOnly、httpOnly、 name,、path、 secure、 session、 storeId、 value
设置cookie:
  1. 确保打开了拦截器
  2. 在headers部分包含cookie的头
例如:Cookie: name=value; name2=value2
3.发送request,你设置的cookie将会和你的request一起发送。
7.捕捉request
现在Postman的拦截器可以从Chrome浏览器直接捕捉request,并保存到历史中。这意味着你可以及时的调试你的web应用的api。这里不需要安装或者配置代理,也不需要更改代码。你可以根据基于URL的正则表达式过滤request。
8.设置文件
你可以在Postman的设置中处理重定向

settings.png

重定向设置.png
General

  • Trim keys and values in request body
如果你使用表单数据或者URL编码模式来发送数据到服务器,这项设为true后就引起所有参数修整。
  • Send no-cache header
你可能想要这项设置为true,这会确保你收到及时刷新的response。
  • Send postman-token header
这主要是用来绕过Chrome的一个bug。如果一个XMLHttpRequest 处于等待状态,另一个request 发送了同样的参数,Chrome将会为两个request返回同样的response。发送一个随机的token将会避免这个问题。这同样也会帮助你区分服务器端的request。
  • XHR Timeout(ms)
设置app等待响应的时间,如果服务器没有响应的话。
  • Automatically follow redirects
防止我们的request返回一个300系列的response被自动重定向。你需要安装拦截器来防止重定向。
  • Open history/collection requests in a new tab
设置为 true,当你点击左侧边栏历史或者收藏里面的request时,会在一个新的tab中打开。
设置为false,则会在当前tab中打开。
  • Response Font Size
设置response视图中的字体大小
  • UI Size
设置UI的大小
  • Retain headers on clicking on links
如果你在response中你点击了一个连接,Postman会为这个URL创建一个新的GET request。如果你想要保留headers 在request之前设置他,就设置为true。当你主要方为一些受保护的资源的时候这个功能将会非常有用。
  • Language detection
如果你测试的API没有在header中返回 Content-Type ,则response不会数据转换成合适的格式。你可以强制指定body的数据类型为JSON等格式。
  • Variable delimiter
变量是保存在双花括号中的,但是你可以改变成其他的字符,这项并不推荐设置除非你出现了问题需要更改这里。
  • Force windows line endings
Refer to this Github issue to know more
  • Instant dialog boxes
禁用 eye-candy 并立即显示所有的对框框模式
  • Send anonymous usage data to Postman
来禁止匿名用户使用数据的选项,这是的Postman的保护性更好。
Theme

选择你喜欢的两种主题风格
Shortcuts

设置常用的快捷键
Data

导入导出我们设置的环境和数据,这回覆盖你现在的收藏和环境,所以小心使用。当然你可以把你现在的环境先导出作为备份。
Add-ons

Interceptor
Postman proxy
Sync



一、开始使用收藏夹
收藏夹会使你的工作效率更上一层楼
收藏夹可以让单个的request分组在一起,这些request可以被进一步的管理到文件夹来更准确的反应你的API。request也可以在保存到收藏夹时存储response例子。你也可以给你的request增加名称或相关描述,使得开发者可以更轻松的使用你的API。

collection.png
1.创建一个收藏夹

单击收藏夹侧边栏标签下面的new collection按钮来创建一个新的收藏夹。

create collection.png
在弹出的对话框中输入收藏夹的名称和描述然后点击Create按钮创建

create.png
2.收藏夹操作

  • Edit

editing.png
在这里可以更改收藏夹的名称和对收藏夹添加描述信息。
  • Share

share.png
收藏夹可以当做JSON文件下载,这允许你可以和其让人分享你的Postman内容。你可以以匿名的身份分享你的收藏夹但是建议你当你上传一个收藏夹时创建一个Postman的账户,以便更新你的收藏夹,你也可以公开它或者删除它。
如果你是一个使用Postman Cloud的团队中的一员,你可以分享你的收藏夹到整个团队或者只分享这个收藏夹的一部分。
  • Delete
删除一个收藏夹会同时删除这个收藏夹本地的分备份。但是不会删除你通过getpostman.com分享的收藏夹。
  • Add Folder

Add Folder.png
文件夹是收藏夹的子集。你可以在一个收藏夹中创建很多文件夹。你可以直接添加一个request到一个文件夹里。文件夹同时也支持Markdown-based描述
现在你只能在收藏夹下面拥有一级文件夹。
  • Saving requests inside a collection

保存request.png

Saving requests inside a collection.png
在这里你可以添加相关的Request描述,指定保存到的收藏夹或文件夹。
点击Save按钮保存request到收藏夹。
注意:表单格式的request和二进制格式的request中包含的文件是不会被保存的收藏夹的。这是由于HTML5规范的限制。
  • Searching
你可以用侧边栏的搜索框来搜索收藏夹、文件夹、request等。
3.文件夹、request的选项

  • Editing
在这里你可以在这里编辑名称和描述,描述支持Markdown
  • Duplicating
这会创建一个文件夹或request的拷贝。新的文件夹或request会被创建为原来的同级。
  • Deleting
删除文件夹会删除里面的request。删除request会删除其保存的所有的response。
二、收藏夹浏览框
收藏夹浏览框帮助你在Postman界面里浏览收藏夹的原始数据信息。
点击 Expand 按钮打开收藏夹的浏览框

consuming_API_documentation_1.png
这里你可以浏览整个收藏夹信息,也可以打开里面的request。收藏夹浏览框可以让你进行一些常规的操作,由于Postman可以导入Swagger、WADL、RAML的文档,你可以管理这些API,这会让你的开发更容易。

consuming_API_documentation_2.png
三、分享你的收藏夹
你可以在你的团队里分享你的收藏夹,你可能需要确保你的团队是在线的,你可以在你的团队页面看到一些计划的细节。如果你也在线,你可以点击Share按钮分享你的收藏夹

share-menu-option.png

share-modal.png
在收藏夹分享对话框里,你可以选择分享的方式为只读,这意味着订阅他的用户不能对他进行编辑。
一个团队分享的收藏夹可以在团队文库里查看。在这里你可以订阅他人分享的收藏夹。

sharing_1.png
四、运行收藏夹
点击运行按钮,你可以运行你的收藏夹。如果需要你可以运行它数千次。

runing collection.png
收藏夹的运行按钮会按收藏夹内request的顺序依次运行他们。他同样也运行每个request的test,同时会生成运行的情况的概述,你可以比较他们并查看他们的不同。
你需要做的就是选择一个收藏夹和所需的环境,通常来说你可以添加一个CSV或者JSON文件,使得Postman可以从中取得数据。
收藏夹的运行窗口是独立于Postman的主窗口来运行的。你可以在主窗口里更改你的收藏夹,运行窗口也会同步更新。
运行窗口选项
  • Collection/Folder
如果收藏夹里有文件夹,文件夹里的request同样也会被执行。
  • Environment
选择你需要的运行环境
  • Iterations
你想运行 你的收藏夹的次数,这里没有一个官方的限制次数。
  • Data
加载 CSV/JSON 数据文件
点击 Start Test按钮,Postman将会开始运行,并显示运行的解惑。一旦运行结束你可以开始新的运行或者在历史中选择运行数据
查看运行结果
点击运行后,会在一个新的标签页面里生成运行数据。

cr-3.png
Postman显示你的运行参数,也显示了通过的测试和失败的测试个数,以及平均的响应时间。
你可以查看运行的基本统计数据,你可以比较相比以前多少测试通过了,是不是你的API设计的更好了。

request.png
REQUESTS 标签显示了所有运行的request的响应时间、测试结果、最后收到的状态码。这帮助你可以快速的得到整个API的状态。如果当运行多次某个测试失败了,这个测试就会标记为失败。如果一切都运行正常,你可以看到很多绿色标记。

cr-7.png




一、环境变量
当使用API的时候,你可能经常需要使用不同的设置。环境设置可以让你使用变量自定义request。这个方法可以让你轻松的在不同的设置之间改变而不用改变你的request。你不需要担心要记住Postman中所有的这些变量的值。环境可以下载保存为JSON文件,以后可以再加载他。

manage environment.png

environment.png
环境变量被设置为键值对,键为变量的名字。
变量可以以这个形式使用: {{variableName}},这个字符串{{variableName}} 将会被他的值所替代。例如:环境变量名为 'url',值为 'http://localhost' ,你可以在request的URL字段中使用{{url}},{{url}}将会在request发送时被替换成 'http://localhost'。
只有当前环境中的变量才是有效的。使用环境变量选择器选择一个环境

env_selector.png
环境变量可以帮助你分离敏感数据例如keys和passwords。你最好保存所有的敏感值到一个环境中,提供一个虚拟的环境来使用。如果你信任这个用户,你也可以给他你的环境。
警告:环境和全局变量被存储为字符串。如果你正在存储对象或数组,请确保在存储前使用JSON.stringify()格式化他们 ,在检索时使用 JSON.parse()。
二、全局变量
全局变量提供了一组总是有效的变量。你可以有很多环境变量,但是同一时间只能有一组有效。但是你可以像使用环境变量一样使用全局变量。
如果一个有效的环境变量名和全局变量名重名,那么全局变量名将被环境变量名覆盖。
三、设置环境变量
在不同的环境中测试request
1.Create an environment

  • 点击No environment按钮

test_multi_environments_1.png
  • 选择 Manage environments,点击Add按钮。

test_multi_environments_2.png
  • 填写变量名和变量值

test_multi_environments_3.png
  • 提交
2.创建你将要测试使用的环境

我们可以duplicata(复制)我们刚创建的环境,这样我们就不必再填写一次了。
3. 在request中使用环境变量

环境变量可以使用在以下地方:
  • URL
  • URL params
  • Header values
  • form-data/url-encoded values
  • Raw body content
  • Helper fields
在你要使用的变量名上附上双花括号。

test_multi_environments_4.png
4.选择要使用的环境

当我们选择了环境之后,Postman将会用变量的值替代所有的变量。如果没有选择环境,Postman将会在全局变量中寻找对应的变量。
5.发送request

6.改变环境,再次发送request。

7.重复上述步骤直到所有的环境都被测试。



一、Pre Request Scripts
Postman v0.10+ 版本支持pre-request scripts。

prerequest script.png
pre-request scripts是一个关联了收藏夹内request,并且在发送request之前执行的代码片段。这对于在request header中包含时间戳或者在URL参数中发送一个随机字符串都是非常有用的。
例如:如果要在request的header中包含一个时间戳,你可以设置一个环境变量由一个函数返回他的值。
postman.setEnvironmentVariable('timestampHeader',new Date());
你可以在header中使 timestampHeader 变量,当request发送的时候,你的pre-request script将被执行,这个timestampHeader 变量的值将会替换{{timestampHeader}}。
注意:我们设置的环境对使用的环境变量必须是有效的。
二、Writing Tests
1.基本结构

![Uploading prerequest script_871640.png . . .]

Basic structure.png
Postman给了你一个环境让你能够为每个request编写、执行你的test,而不用担心任何额外的设置。
一个Postman的test本质上是JavaScript的代码可以用来为一些特殊的test设置值。你可以在对象中设置一个描述性的键作为一个元素,然后声明他如果是true或false。
tests[“Body contains user_id”] = responseBody.has(“user_id”)
这回核对body中是否包含了user_id这个字符串。如果你需要,你可以增加更多的键,这取决于你要用test做多少的事情。
test被保存为收藏夹request的一部分,这对于后端或前端的工程师来确保API运行的正常都是非常有意义的。
2.SNIPPETS

在写test的时候这里有些事情需要注意,Postman尝试使得列出常用的片段更简单。你可以选择你想添加的片段,然后适当的代码将被添加到test的编辑器中。这是一个很好的方法来快速的构建test
3.查看结果


view result.png
Postman在你执行一个request的时候执行test,当然你可以选择不考虑test。结果被显示在一个tab里,并在头部显示多少test通过了测试。你设置在test中的变量将会被列在这里。如果值是true,这个test就会通过。你可以保持test tab活动直到你确保所有的test执行完。
三、Testing Sandbox
Postman的sandbox是一个JavaScript的执行环境,这使得你能够为request写pre-request scripts和test scripts 。不论你写的代码是pre-request scripts还是test script都会在sandbox中执行。
1.常用的库和工具

  • Lodash
JS utility library
  • jQuery (Deprecated):
Cross-platform JavaScript library. This will be removed in future versions of the sandbox.
  • BackboneJS (Deprecated):
Provides simple models, views, and collections. This will be removed in future versions of the sandbox.
  • SugarJS:
Extends native JS objects with useful methods
  • tv4 JSON schema validator:
Validates JSON objects against v4 of the json-schema draft
  • CryptoJS:
standard and secure cryptographic algorithms. Supported algorithms: AES, DES, EvpKDF, HMAC-MD5, HMAC-SHA1/3/256/512, MD5, PBKDF2, Rabbit, SHA1/3/224/256/512, TripleDES
  • xml2Json(xmlString):
This function behaves the same in Newman and Postman
  • xmlToJson(xmlString)(Deprecated):
This function does NOT behave the same in Newman and Postman
  • postman.getResponseHeader(headerName) (Test-only):
returns the response header with name "headerName", if it exists. Returns null if no such header exists. Note: According to W3C specifications, header names are case-insensitive. This method takes care of this.
postman.getResponseHeader("Content-type") and postman.getResponseHeader("content-Type") will return the same value.
2.环境和全局变量
  • postman.setEnvironmentVariable(variableName, variableValue) : Sets an environment variable "variableName", and assigns the string "variableValue" to it. You must have an environment selected for this method to work. Note: Only strings can be stored. Storing other types of data will result in unexpected behavior.
  • postman.setGlobalVariable(variableName, variableValue):
Sets a global variable "variableName", and assigns the string "variableValue" to it. Note: Only strings can be stored. Storing other types of data will result in unexpected behavior.
  • postman.clearEnvironmentVariable(variableName):
Clears the environment variable named "variableName". You must have an environment selected for this method to work.
  • postman.clearGlobalVariable(variableName):
Clears the global variable named "variableName".
  • postman.clearEnvironmentVariables():
Clears all environment variables. You must have an environment selected for this method to work.
  • postman.clearGlobalVariables():
Clears all global variables.
  • environment:
A dictionary of variables in the current environment. Use environment["foo"]
to access the value of the "foo" environment variable.
  • globals:
A dictionary of global variables. Useglobals["bar"]
to access the value of the "bar" global variable.
3.动态变量
Postman也有一些动态变量,你可以用在你的request中。这个现在主要还是在实现阶段,更多的功能以后被被添加进来。注意:动态变量不可以用于SandBox中,你只能在request的URL、headers、body中以放在双花括号中间的形式使用。
  • {{$guid}}: Adds a v4 style guid
  • {{$timestamp}}: Adds the current timestamp.
  • {{$randomInt}}: Adds a random integer between 0 and 1000
4. Cookies
+ responseCookies {array}(Postman-only):
Gets all cookies set for the domain. You will need to enable theInterceptor for this to work.
  • postman.getResponseCookie(cookieName)(Postman-only):
Gets the response cookie with the given name. You will need to enable the interceptor for this to work. Check out theblog post.
5.Request/response相关属性
  • request {object}:
Postman makes the request object available to you while writing scripts. This object is read-only. Changing properties of this object will have no effect. Note: Variables will NOT be resolved in the request object. The request object is composed of the following:
  • data {object}:
this is a dictionary of form data for the request. (request.data["key"]=="value")
    • headers {object}:
this is a dictionary of headers for the request (request.headers["key"]=="value")
    • method {string}:
GET/POST/PUT etc.
    • url {string}:
the url for the request.
  • responseHeaders {object}(Test-only)(Deprecated):
This is a map of the response headers. This is case-sensitive, and should not be used. Check thepostman.getResponseHeader()
method listed above.
  • responseBody {string}(Test-only):
A string containing the raw response body text. You can use this as an input to JSON.parse, or xml2Json.
  • responseTime {number}(Test-only):
The response time in milliseconds
  • responseCode {object}(Test-only):
Contains three properties:
  • code {number}:
The response code (200 for OK, 404 for Not Found etc)
    • name {string}:
The status code text
    • detail {string}:
An explanation of the response code
  • tests {object}(Test-only):
This object is for you to populate. Postman will treat each property of this object as a boolean test.
  • iteration {number}:
Only available in the Collection Runner and Newman. Represents the current test run index. Starts from 0.
(Test-only): This object is only available in the test script section. Using this in a pre-request script will throw an error.
四、Testing 实例
我们来看一些Postman用于test的例子。这些例子中的大多数在Postman中是有效的,他们像一行JavaScript语句一样简答。在你的request中你可以有很多的test。
注意:test脚本在从服务器收到response后执行
1.设置环境变量:
postman.setEnvironmentVariable("key", "value");
2.设置全局变量:
postman.setGlobalVariable("key", "value");
3.检查response的body中是否包含字符串:
tests["Body matches string"] = responseBody.has("string_you_want_to_search");
4.把XML的body转换成JSON对象:
var jsonObject = xml2Json(responseBody);
5.检查response的body是都为一个字符串:
tests["Body is correct"] = responseBody === "response_body_string";
6.检查JSON的值:
var data = JSON.parse(responseBody);tests["Your test name"] = data.value === 100;
7.内容类型存在(检查不区分大小写)
tests["Content-Type is present"] = postman.getResponseHeader("Content-Type"); //Note: the getResponseHeader() method returns the header value, if it exists.
8.内容类型存在(区分大小写):
tests["Content-Type is present"] = responseHeaders.hasOwnProperty("Content-Type");
9.response的响应时间小于200ms:
tests["Response time is less than 200ms"] = responseTime < 200;
10.状态码为200:
tests["Status code is 200"] = responseCode.code === 200;
11.Code name contains a string:
tests["Status code name has string"] = responseCode.name.has("Created");
12.成功的POST request状态码:
tests["Successful POST request"] = responseCode.code === 201 || responseCode.code === 202;
13.Use TinyValidator for JSON data
var schema = { "items": { "type": "boolean" }};var data1 = [true, false];var data2 = [true, 123];console.log(tv4.error);tests["Valid Data1"] = tv4.validate(data1, schema);tests["Valid Data2"] = tv4.validate(data2, schema);
14.Sample data files
JSON files are composed of key/value pairs:
Download JSON file
For CSV files, the top row needs to contain variable names
Download CSV file


文章节选 TestHome 简书等
https://testerhome.com/topics/6695
https://testerhome.com/topics/9480
https://testerhome.com/solochen84
简书 链接:
http://www.jianshu.com/p/61cfcb436ee4



原创粉丝点击