update docs with mkdocs

This commit is contained in:
debugtalk
2018-02-12 21:37:49 +08:00
parent 3e0d117a05
commit b03fca59fe
12 changed files with 225 additions and 525 deletions

View File

@@ -1,19 +0,0 @@
FAQ
===
Unable to install PyUnitReport dependency library automatically
---------------------------------------------------------------
If there is something goes wrong in installation like below. ::
Downloading/unpacking PyUnitReport (from HttpRunner)
Could not find any downloads that satisfy the requirement PyUnitReport (from HttpRunner)
You could install ``PyUnitReport`` manully at first. ::
pip install PyUnitReport
And then everything will be OK when you reinstall ``HttpRunner``. ::
pip install HttpRunner

78
docs/Installation.md Normal file
View File

@@ -0,0 +1,78 @@
## Installation
`HttpRunner` is available on [`PyPI`][PyPI] and can be installed through pip or easy_install.
```bash
$ pip install HttpRunner
```
or
```bash
$ easy_install HttpRunner
```
If you want to keep up with the latest version, you can install with github repository url.
```bash
$ pip install git+https://github.com/HttpRunner/HttpRunner.git#egg=HttpRunner
```
## Upgrade
If you have installed `HttpRunner` before and want to upgrade to the latest version, you can use the `-U` option.
This option works on each installation method described above.
```bash
$ pip install -U HttpRunner
$ easy_install -U HttpRunner
$ pip install -U git+https://github.com/HttpRunner/HttpRunner.git#egg=HttpRunner
```
## Check Installation
When HttpRunner is installed, a **httprunner** (**hrun** for short) command should be available in your shell (if you're not using
virtualenv—which you should—make sure your python script directory is on your path).
To see `HttpRunner` version:
```bash
$ httprunner -V # same as: hrun -V
HttpRunner version: 0.8.1b
PyUnitReport version: 0.1.3b
```
To see available options, run:
```bash
$ httprunner -h # same as: hrun -h
usage: httprunner [-h] [-V] [--log-level LOG_LEVEL] [--report-name REPORT_NAME]
[--failfast] [--startproject STARTPROJECT]
[testset_paths [testset_paths ...]]
HttpRunner.
positional arguments:
testset_paths testset file path
optional arguments:
-h, --help show this help message and exit
-V, --version show version
--log-level LOG_LEVEL
Specify logging level, default is INFO.
--report-name REPORT_NAME
Specify report name, default is generated time.
--failfast Stop the test run on the first error or failure.
--startproject STARTPROJECT
Specify new project name.
```
## Supported Python Versions
HttpRunner supports Python 2.7, 3.4, 3.5, and 3.6. And we strongly recommend you to use `Python 3.6`.
`HttpRunner` has been tested on `macOS`, `Linux` and `Windows` platforms.
[PyPI]: https://pypi.python.org/pypi

View File

@@ -1,76 +0,0 @@
.. default-role:: code
Installation
============
``HttpRunner`` is available on `PyPI`_ and can be installed through pip or easy_install. ::
$ pip install HttpRunner
or ::
$ easy_install HttpRunner
If you want to keep up with the latest version, you can install with github repository url. ::
$ pip install git+https://github.com/HttpRunner/HttpRunner.git#egg=HttpRunner
Upgrade
-------
If you have installed ``HttpRunner`` before and want to upgrade to the latest version, you can use the ``-U`` option.
This option works on each installation method described above. ::
$ pip install -U HttpRunner
$ easy_install -U HttpRunner
$ pip install -U git+https://github.com/HttpRunner/HttpRunner.git#egg=HttpRunner
Check Installation
------------------
When HttpRunner is installed, a **httprunner** (**hrun** for short) command should be available in your shell (if you're not using
virtualenv—which you should—make sure your python script directory is on your path).
To see ``HttpRunner`` version: ::
$ httprunner -V # same as: hrun -V
HttpRunner version: 0.8.1b
PyUnitReport version: 0.1.3b
To see available options, run::
$ httprunner -h # same as: hrun -h
usage: httprunner [-h] [-V] [--log-level LOG_LEVEL] [--report-name REPORT_NAME]
[--failfast] [--startproject STARTPROJECT]
[testset_paths [testset_paths ...]]
HttpRunner.
positional arguments:
testset_paths testset file path
optional arguments:
-h, --help show this help message and exit
-V, --version show version
--log-level LOG_LEVEL
Specify logging level, default is INFO.
--report-name REPORT_NAME
Specify report name, default is generated time.
--failfast Stop the test run on the first error or failure.
--startproject STARTPROJECT
Specify new project name.
Supported Python Versions
-------------------------
HttpRunner supports Python 2.7, 3.4, 3.5, and 3.6. And we strongly recommend you to use ``Python 3.6``.
``HttpRunner`` has been tested on ``macOS``, ``Linux`` and ``Windows`` platforms.
.. _PyPI: https://pypi.python.org/pypi

View File

@@ -1,20 +0,0 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = python -msphinx
SPHINXPROJ = HttpRunner
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View File

15
docs/_static/my.css vendored
View File

@@ -1,15 +0,0 @@
@import 'https://media.readthedocs.org/css/sphinx_rtd_theme.css';
.wy-nav-content {
max-width: 1020px
}
.rst-content .topic {
border: silver 1px solid;
margin: 10px auto;
padding: 10px;
}
.rst-content .highlight>pre {
line-height: 1.5;
}

View File

@@ -1,192 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# HttpRunner documentation build configuration file, created by
# sphinx-quickstart on Wed Nov 8 14:28:04 2017.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
import os
on_rtd = os.environ.get('READTHEDOCS') == 'True'
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.githubpages'
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
from recommonmark.parser import CommonMarkParser
source_parsers = {
'.md': CommonMarkParser,
}
source_suffix = ['.rst', '.md']
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = 'HttpRunner'
copyright = '2017, DebugTalk'
author = 'debugtalk'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.8'
# The full version, including alpha/beta/rc tags.
release = '0.8.1'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'zh'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
if on_rtd:
html_theme = 'default'
html_context = {
'css_files': [
'https://media.readthedocs.org/css/sphinx_rtd_theme.css',
'https://media.readthedocs.org/css/readthedocs-doc-embed.css',
'_static/my.css',
],
}
else:
import sphinx_rtd_theme
html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
html_style = 'my.css'
html_show_sourcelink = False
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# This is required for the alabaster theme
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
# html_sidebars = {
# '**': [
# 'about.html',
# 'navigation.html',
# 'relations.html', # needs 'show_related': True theme option to display
# 'searchbox.html',
# # 'donate.html',
# ]
# }
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'HttpRunnerdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'HttpRunner.tex', 'HttpRunner Documentation',
'debugtalk', 'manual'),
]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'httprunner', 'HttpRunner Documentation',
[author], 1)
]
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'HttpRunner', 'HttpRunner Documentation',
author, 'HttpRunner', 'One line description of project.',
'Miscellaneous'),
]

3
docs/index.md Normal file
View File

@@ -0,0 +1,3 @@
Welcome to HttpRunner's documentation!
点击此处查看[中文使用说明文档](http://cn.httprunner.top)。

View File

@@ -1,20 +0,0 @@
.. HttpRunner documentation master file, created by
sphinx-quickstart on Wed Nov 8 14:28:04 2017.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to HttpRunner's documentation!
======================================
.. toctree::
:maxdepth: 1
:caption: Contents
Introduction
Installation
quickstart
write-testcases
run-testcases
load-test
development
FAQ

View File

@@ -328,8 +328,8 @@ This is just a starting point, see the `advanced guide` for the advanced feature
[requests]: http://docs.python-requests.org/en/master/
[requests.request]: http://docs.python-requests.org/en/master/api/#requests.request
[comparator]: comparator.md
[extraction-and-validation]: extraction-and-validation.md
[comparator]: write-testcases.md#comparator
[extraction-and-validation]: write-testcases.md#extraction-and-validation
[quickstart-demo-rev-0]: ../examples/quickstart-demo-rev-0.yml
[quickstart-demo-rev-1]: ../examples/quickstart-demo-rev-1.yml
[quickstart-demo-rev-2]: ../examples/quickstart-demo-rev-2.yml

142
docs/write-testcases.md Normal file
View File

@@ -0,0 +1,142 @@
It is recommended to write testcases in `YAML` format.
## demo
Here is a testset example of typical scenario: get `token` at the beginning, and each subsequent requests should take the `token` in the headers.
```yaml
- config:
name: "create user testsets."
variables:
- user_agent: 'iOS/10.3'
- device_sn: ${gen_random_string(15)}
- os_platform: 'ios'
- app_version: '2.8.6'
request:
base_url: "http://127.0.0.1:5000"
headers:
Content-Type: application/json
device_sn: $device_sn
- test:
name: get token
request:
url: /api/get-token
method: POST
headers:
user_agent: $user_agent
device_sn: $device_sn
os_platform: $os_platform
app_version: $app_version
json:
sign: ${get_sign($user_agent, $device_sn, $os_platform, $app_version)}
extract:
- token: content.token
validate:
- eq: ["status_code", 200]
- len_eq: ["content.token", 16]
- test:
name: create user which does not exist
request:
url: /api/users/1000
method: POST
headers:
token: $token
json:
name: "user1"
password: "123456"
validate:
- eq: ["status_code", 201]
- eq: ["content.success", true]
```
Function invoke is supported in `YAML/JSON` format testcases, such as `gen_random_string` and `get_sign` above. This mechanism relies on the `debugtak.py` hot plugin, with which we can define functions in `debugtak.py` file, and then functions can be auto discovered and invoked in runtime.
For detailed regulations of writing testcases, you can read the [`quickstart`](quickstart.md) documents.
## Comparator
`HttpRunner` currently supports the following comparators.
| comparator | Description | A(check), B(expect) | examples |
| -- | -- | -- | -- |
| `eq`, `==` | value is equal | A == B | 9 eq 9 |
| `lt` | less than | A < B | 7 lt 8 |
| `le` | less than or equals | A <= B | 7 le 8, 8 le 8 |
| `gt` | greater than | A > B | 8 gt 7 |
| `ge` | greater than or equals | A >= B | 8 ge 7, 8 ge 8 |
| `ne` | not equals | A != B | 6 ne 9 |
| `str_eq` | string equals | str(A) == str(B) | 123 str_eq '123' |
| `len_eq`, `count_eq` | length or count equals | len(A) == B | 'abc' len_eq 3, [1,2] len_eq 2 |
| `len_gt`, `count_gt` | length greater than | len(A) > B | 'abc' len_gt 2, [1,2,3] len_gt 2 |
| `len_ge`, `count_ge` | length greater than or equals | len(A) >= B | 'abc' len_ge 3, [1,2,3] len_gt 3 |
| `len_lt`, `count_lt` | length less than | len(A) < B | 'abc' len_lt 4, [1,2,3] len_lt 4 |
| `len_le`, `count_le` | length less than or equals | len(A) <= B | 'abc' len_le 3, [1,2,3] len_le 3 |
| `contains` | contains | [1, 2] contains 1 | 'abc' contains 'a', [1,2,3] len_lt 4 |
| `contained_by` | contained by | A in B | 'a' contained_by 'abc', 1 contained_by [1,2] |
| `type_match` | A is instance of B | isinstance(A, B) | 123 type_match 'int' |
| `regex_match` | regex matches | re.match(B, A) | 'abcdef' regex 'a\w+d' |
| `startswith` | starts with | A.startswith(B) is True | 'abc' startswith 'ab' |
| `endswith` | ends with | A.endswith(B) is True | 'abc' endswith 'bc' |
## Extraction and Validation
Suppose we get the following HTTP response.
```javascript
// status code: 200
// response headers
{
"Content-Type": "application/json"
}
// response body content
{
"success": False,
"person": {
"name": {
"first_name": "Leo",
"last_name": "Lee",
},
"age": 29,
"cities": ["Guangzhou", "Shenzhen"]
}
}
```
In `extract` and `validate`, we can do chain operation to extract data field in HTTP response.
For instance, if we want to get `Content-Type` in response headers, then we can specify `headers.content-type`; if we want to get `first_name` in response content, we can specify `content.person.name.first_name`.
There might be slight difference on list, cos we can use index to locate list item. For example, `Guangzhou` in response content can be specified by `content.person.cities.0`.
```javascript
// get status code
status_code
// get headers field
headers.content-type
// get content field
body.success
content.success
text.success
content.person.name.first_name
content.person.cities.1
```
```yaml
extract:
- content_type: headers.content-type
- first_name: content.person.name.first_name
validate:
- eq: ["status_code", 200]
- eq: ["headers.content-type", "application/json"]
- gt: ["headers.content-length", 40]
- eq: ["content.success", true]
- len_eq: ["content.token", 16]
```

View File

@@ -1,181 +0,0 @@
.. default-role:: code
Write testcases
===============
It is recommended to write testcases in `YAML` format.
demo
----
And here is testset example of typical scenario: get `token` at the beginning, and each subsequent requests should take the `token` in the headers.
.. code-block:: yaml
- config:
name: "create user testsets."
variables:
- user_agent: 'iOS/10.3'
- device_sn: ${gen_random_string(15)}
- os_platform: 'ios'
- app_version: '2.8.6'
request:
base_url: http://127.0.0.1:5000
headers:
Content-Type: application/json
device_sn: $device_sn
- test:
name: get token
request:
url: /api/get-token
method: POST
headers:
user_agent: $user_agent
device_sn: $device_sn
os_platform: $os_platform
app_version: $app_version
json:
sign: ${get_sign($user_agent, $device_sn, $os_platform, $app_version)}
extract:
- token: content.token
validate:
- eq: ["status_code", 200]
- len_eq: ["content.token", 16]
- test:
name: create user which does not exist
request:
url: /api/users/1000
method: POST
headers:
token: $token
json:
name: "user1"
password: "123456"
validate:
- eq: ["status_code", 201]
- eq: ["content.success", true]
Function invoke is supported in `YAML/JSON` format testcases, such as `gen_random_string` and `get_sign` above. This mechanism relies on the `debugtak.py` hot plugin, with which we can define functions in `debugtak.py` file, and then functions can be auto discovered and invoked in runtime.
For detailed regulations of writing testcases, you can read the :doc:`quickstart` documents.
Comparator
----------
``HttpRunner`` currently supports the following comparators.
+---------------------------+---------------------------+-------------------------+--------------------------+
| comparator | Description | A(check), B(expect) | examples |
+===========================+===========================+=========================+==========================+
| ``eq``, ``==`` | value is equal | A == B | 9 eq 9 |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``lt`` | less than | A < B | 7 lt 8 |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``le`` | less than or equals | A <= B | 7 le 8, 8 le 8 |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``gt`` | greater than | A > B | 8 gt 7 |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``ge`` | greater than or equals | A >= B | 8 ge 7, 8 ge 8 |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``ne`` | not equals | A != B | 6 ne 9 |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``str_eq`` | string equals | str(A) == str(B) | 123 str_eq '123' |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``len_eq``, ``count_eq`` | length or count equals | len(A) == B | | 'abc' len_eq 3 |
| | | | | [1,2] len_eq 2 |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``len_gt``, ``count_gt`` | length greater than | len(A) > B | | 'abc' len_gt 2 |
| | | | | [1,2,3] len_gt 2 |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``len_ge``, ``count_ge`` | length greater than | len(A) >= B | | 'abc' len_ge 3 |
| | or equals | | | [1,2,3] len_gt 3 |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``len_lt``, ``count_lt`` | length less than | len(A) < B | | 'abc' len_lt 4 |
| | | | | [1,2,3] len_lt 4 |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``len_le``, ``count_le`` | length less than | len(A) <= B | | 'abc' len_le 3 |
| | or equals | | | [1,2,3] len_le 3 |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``contains`` | contains | [1, 2] contains 1 | | 'abc' contains 'a' |
| | | | | [1,2,3] len_lt 4 |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``contained_by`` | contained by | A in B | | 'a' contained_by 'abc' |
| | | | | 1 contained_by [1,2] |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``type_match`` | A is instance of B | isinstance(A, B) | 123 type_match 'int' |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``regex_match`` | regex matches | re.match(B, A) | 'abcdef' regex 'a\w+d' |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``startswith`` | starts with | A.startswith(B) is True | 'abc' startswith 'ab' |
+---------------------------+---------------------------+-------------------------+--------------------------+
| ``endswith`` | ends with | A.endswith(B) is True | 'abc' endswith 'bc' |
+---------------------------+---------------------------+-------------------------+--------------------------+
Extraction and Validation
-------------------------
Suppose we get the following HTTP response.
.. code-block:: javascript
// status code: 200
// response headers
{
"Content-Type": "application/json"
}
// response body content
{
"success": False,
"person": {
"name": {
"first_name": "Leo",
"last_name": "Lee",
},
"age": 29,
"cities": ["Guangzhou", "Shenzhen"]
}
}
In `extract` and `validate`, we can do chain operation to extract data field in HTTP response.
For instance, if we want to get `Content-Type` in response headers, then we can specify `headers.content-type`; if we want to get `first_name` in response content, we can specify `content.person.name.first_name`.
There might be slight difference on list, cos we can use index to locate list item. For example, `Guangzhou` in response content can be specified by `content.person.cities.0`.
.. code-block:: javascript
// get status code
status_code
// get headers field
headers.content-type
// get content field
body.success
content.success
text.success
content.person.name.first_name
content.person.cities.1
.. code-block:: yaml
extract:
- content_type: headers.content-type
- first_name: content.person.name.first_name
validate:
- eq: ["status_code", 200]
- eq: ["headers.content-type", "application/json"]
- gt: ["headers.content-length", 40]
- eq: ["content.success", true]
- len_eq: ["content.token", 16]
.. _QuickStart: http://