Merge branch 'master' into master

This commit is contained in:
debugtalk
2022-03-22 17:06:56 +08:00
committed by GitHub
43 changed files with 1562 additions and 906 deletions

View File

@@ -2,11 +2,8 @@ name: integration_test
on:
push:
branches:
- dev
pull_request:
branches:
- master
types: [synchronize]
jobs:
integration_test:
@@ -14,32 +11,35 @@ jobs:
name: integration_test - ${{ matrix.python-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
max-parallel: 6
matrix:
python-version: [3.6, 3.7, 3.8]
os: [ubuntu-latest, macos-latest] # TODO: windows-latest
python-version: ['3.7', '3.8', '3.9', '3.10']
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
architecture: x64
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install poetry
poetry --version
poetry install -vv -E upload
- name: Test package installation
- name: Test build package
run: |
poetry build
ls dist/*.whl | xargs pip install # test installation
hrun -V
har2case -h
httprunner run -h
httprunner startproject -h
httprunner har2case -h
ls -l dist/
- name: Test commands
run: |
poetry run hrun -V
poetry run har2case -h
poetry run httprunner run -h
poetry run httprunner startproject -h
poetry run httprunner har2case -h
- name: Run smoketest - postman echo
run: |
poetry run hrun examples/postman_echo/request_methods

View File

@@ -2,11 +2,8 @@ name: unittest
on:
push:
branches:
- dev
pull_request:
branches:
- master
types: [synchronize]
jobs:
unittest:
@@ -14,17 +11,19 @@ jobs:
name: unittest - ${{ matrix.python-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
max-parallel: 12
matrix:
python-version: [3.6, 3.7, 3.8]
python-version: ['3.7', '3.8', '3.9', '3.10']
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
architecture: x64
- name: Install dependencies
run: |
python -m pip install --upgrade pip

View File

@@ -1,67 +0,0 @@
# HttpRunner
[![downloads](https://pepy.tech/badge/httprunner)](https://pepy.tech/project/httprunner)
[![unittest](https://github.com/httprunner/httprunner/workflows/unittest/badge.svg
)](https://github.com/httprunner/httprunner/actions)
[![integration-test](https://github.com/httprunner/httprunner/workflows/integration_test/badge.svg
)](https://github.com/httprunner/httprunner/actions)
[![codecov](https://codecov.io/gh/httprunner/httprunner/branch/master/graph/badge.svg)](https://codecov.io/gh/httprunner/httprunner)
[![pypi version](https://img.shields.io/pypi/v/httprunner.svg)](https://pypi.python.org/pypi/httprunner)
[![pyversions](https://img.shields.io/pypi/pyversions/httprunner.svg)](https://pypi.python.org/pypi/httprunner)
[![TesterHome](https://img.shields.io/badge/TTF-TesterHome-2955C5.svg)](https://testerhome.com/github_statistics)
*HttpRunner* is a simple & elegant, yet powerful HTTP(S) testing framework. Enjoy! ✨ 🚀 ✨
## Design Philosophy
- Convention over configuration
- ROI matters
- Embrace open source, leverage [`requests`][requests], [`pytest`][pytest], [`pydantic`][pydantic], [`allure`][allure] and [`locust`][locust].
## Key Features
- Inherit all powerful features of [`requests`][requests], just have fun to handle HTTP(S) in human way.
- Define testcase in YAML or JSON format, run with [`pytest`][pytest] in concise and elegant manner.
- Record and generate testcases with [`HAR`][HAR] support.
- Supports `variables`/`extract`/`validate`/`hooks` mechanisms to create extremely complex test scenarios.
- With `debugtalk.py` plugin, any function can be used in any part of your testcase.
- With [`jmespath`][jmespath], extract and validate json response has never been easier.
- With [`pytest`][pytest], hundreds of plugins are readily available.
- With [`allure`][allure], test report can be pretty nice and powerful.
- With reuse of [`locust`][locust], you can run performance test without extra work.
- CLI command supported, perfect combination with `CI/CD`.
## Sponsors
Thank you to all our sponsors! ✨🍰✨ ([become a sponsor](docs/sponsors.md))
### 金牌赞助商Gold Sponsor
[<img src="docs/assets/hogwarts.png" alt="霍格沃兹测试学院" width="400">](https://ceshiren.com/)
> [霍格沃兹测试学院](https://ceshiren.com/) 是业界领先的测试开发技术高端教育品牌,隶属于测吧(北京)科技有限公司。学院课程均由 BAT 一线测试大咖执教,提供实战驱动的接口自动化测试、移动自动化测试、性能测试、持续集成与 DevOps 等技术培训,以及测试开发优秀人才内推服务。[点击学习!](https://ke.qq.com/course/254956?flowToken=1014690)
霍格沃兹测试学院是 HttpRunner 的首家金牌赞助商。
### 开源服务赞助商Open Source Sponsor
[<img src="docs/assets/sentry-logo-black.svg" alt="Sentry" width="150">](https://sentry.io/_/open-source/)
HttpRunner is in Sentry Sponsored plan.
## Subscribe
关注 HttpRunner 的微信公众号,第一时间获得最新资讯。
![](docs/assets/qrcode.jpg)
[requests]: http://docs.python-requests.org/en/master/
[pytest]: https://docs.pytest.org/
[pydantic]: https://pydantic-docs.helpmanual.io/
[locust]: http://locust.io/
[jmespath]: https://jmespath.org/
[allure]: https://docs.qameta.io/allure/
[HAR]: http://httparchive.org/

View File

@@ -1,5 +1,19 @@
# Release History
## 3.1.8 (2022-03-22)
- change: load yaml file with FullLoader
## 3.1.7 (2022-03-22)
- fix #1117: ignore comments and blank lines when parsing .env file
- fix #1141: parameterize failure caused by pydantic version
- fix #1165: ImportError caused by jinja2 version
- fix: failure in getting client and server IP/port when requesting HTTPS
- fix: upgrade dependencies for security
- change: remove support for dead python 3.6, upgrade supported python version to 3.7/3.8/3.9/3.10
- change: replace events reporter from sentry to Google Analytics
## 3.1.6 (2021-07-18)
**Fixed**
@@ -259,7 +273,7 @@
**Added**
- feat: add `make` sub-command to generate python testcases from YAML/JSON
- feat: add `make` sub-command to generate python testcases from YAML/JSON
- feat: format generated python testcases with [`black`](https://github.com/psf/black)
- test: add postman echo & httpbin as testcase examples

70
docs/README.md Normal file
View File

@@ -0,0 +1,70 @@
# HttpRunner
[![downloads](https://pepy.tech/badge/httprunner)](https://pepy.tech/project/httprunner)
[![unittest](https://github.com/httprunner/httprunner/workflows/unittest/badge.svg
)](https://github.com/httprunner/httprunner/actions)
[![integration-test](https://github.com/httprunner/httprunner/workflows/integration_test/badge.svg
)](https://github.com/httprunner/httprunner/actions)
[![codecov](https://codecov.io/gh/httprunner/httprunner/branch/master/graph/badge.svg)](https://codecov.io/gh/httprunner/httprunner)
[![pypi version](https://img.shields.io/pypi/v/httprunner.svg)](https://pypi.python.org/pypi/httprunner)
[![pyversions](https://img.shields.io/pypi/pyversions/httprunner.svg)](https://pypi.python.org/pypi/httprunner)
[![TesterHome](https://img.shields.io/badge/TTF-TesterHome-2955C5.svg)](https://testerhome.com/github_statistics)
*HttpRunner* is a simple & elegant, yet powerful HTTP(S) testing framework. Enjoy! ✨ 🚀 ✨
> 欢迎参加 HttpRunner [用户调研问卷][survey],你的反馈将帮助 HttpRunner 更好地成长!
## Design Philosophy
- Convention over configuration
- ROI matters
- Embrace open source, leverage [`requests`][requests], [`pytest`][pytest], [`pydantic`][pydantic], [`allure`][allure] and [`locust`][locust].
## Key Features
- [x] Inherit all powerful features of [`requests`][requests], just have fun to handle HTTP(S) in human way.
- [x] Define testcase in YAML or JSON format, run with [`pytest`][pytest] in concise and elegant manner.
- [x] Record and generate testcases with [`HAR`][HAR] support.
- [x] Supports `variables`/`extract`/`validate`/`hooks` mechanisms to create extremely complex test scenarios.
- [x] With `debugtalk.py` plugin, any function can be used in any part of your testcase.
- [x] With [`jmespath`][jmespath], extract and validate json response has never been easier.
- [x] With [`pytest`][pytest], hundreds of plugins are readily available.
- [x] With [`allure`][allure], test report can be pretty nice and powerful.
- [x] With reuse of [`locust`][locust], you can run performance test without extra work.
- [x] CLI command supported, perfect combination with `CI/CD`.
## Sponsors
Thank you to all our sponsors! ✨🍰✨ ([become a sponsor](sponsors.md))
### 金牌赞助商Gold Sponsor
[<img src="assets/hogwarts.jpeg" alt="霍格沃兹测试开发学社" width="400">](https://ceshiren.com/)
> [霍格沃兹测试开发学社](http://qrcode.testing-studio.com/f?from=httprunner&url=https://ceshiren.com)是业界领先的测试开发技术高端教育品牌,隶属于[测吧(北京)科技有限公司](http://qrcode.testing-studio.com/f?from=httprunner&url=https://www.testing-studio.com) 。学院课程由一线大厂测试经理与资深测试开发专家参与研发,实战驱动。课程涵盖 web/app 自动化测试、接口测试、性能测试、安全测试、持续集成/持续交付/DevOps测试左移&右移、精准测试、测试平台开发、测试管理等内容,帮助测试工程师实现测试开发技术转型。通过优秀的学社制度(奖学金、内推返学费、行业竞赛等多种方式)来实现学员、学社及用人企业的三方共赢。
> [进入测试开发技术能力测评!](http://qrcode.testing-studio.com/f?from=httprunner&url=https://ceshiren.com/t/topic/14940)
### 开源服务赞助商Open Source Sponsor
[<img src="assets/sentry-logo-black.svg" alt="Sentry" width="150">](https://sentry.io/_/open-source/)
HttpRunner is in Sentry Sponsored plan.
## Subscribe
关注 HttpRunner 的微信公众号,第一时间获得最新资讯。
<img src="assets/qrcode.jpg" alt="HttpRunner" width="200">
如果你期望加入 HttpRunner 核心用户群,请填写[用户调研问卷][survey]并留下你的联系方式,作者将拉你进群。
[requests]: http://docs.python-requests.org/en/master/
[pytest]: https://docs.pytest.org/
[pydantic]: https://pydantic-docs.helpmanual.io/
[locust]: http://locust.io/
[jmespath]: https://jmespath.org/
[allure]: https://docs.qameta.io/allure/
[HAR]: http://httparchive.org/
[survey]: https://wj.qq.com/s2/9699514/0d19/

BIN
docs/assets/hogwarts.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

View File

@@ -1,49 +0,0 @@
# HttpRunner
[![downloads](https://pepy.tech/badge/httprunner)](https://pepy.tech/project/httprunner)
[![unittest](https://github.com/httprunner/httprunner/workflows/unittest/badge.svg
)](https://github.com/httprunner/httprunner/actions)
[![integration-test](https://github.com/httprunner/httprunner/workflows/integration_test/badge.svg
)](https://github.com/httprunner/httprunner/actions)
[![codecov](https://codecov.io/gh/httprunner/httprunner/branch/master/graph/badge.svg)](https://codecov.io/gh/httprunner/httprunner)
[![pypi version](https://img.shields.io/pypi/v/httprunner.svg)](https://pypi.python.org/pypi/httprunner)
[![pyversions](https://img.shields.io/pypi/pyversions/httprunner.svg)](https://pypi.python.org/pypi/httprunner)
[![TesterHome](https://img.shields.io/badge/TTF-TesterHome-2955C5.svg)](https://testerhome.com/github_statistics)
*HttpRunner* is a simple & elegant, yet powerful HTTP(S) testing framework. Enjoy! ✨ 🚀 ✨
> This docs site is corresponding to the latest version `3.x`, for `2.x` you can reference [`archive link`](https://v2.httprunner.org/).
## Design Philosophy
- Convention over configuration
- ROI matters
- Embrace open source, leverage [`requests`][requests], [`pytest`][pytest], [`pydantic`][pydantic], [`allure`][allure] and [`locust`][locust].
## Key Features
- Inherit all powerful features of [`requests`][requests], just have fun to handle HTTP(S) in human way.
- Define testcase in YAML or JSON format, run with [`pytest`][pytest] in concise and elegant manner.
- Record and generate testcases with [`HAR`][HAR] support.
- Supports `variables`/`extract`/`validate`/`hooks` mechanisms to create extremely complex test scenarios.
- With `debugtalk.py` plugin, any function can be used in any part of your testcase.
- With [`jmespath`][jmespath], extract and validate json response has never been easier.
- With [`pytest`][pytest], hundreds of plugins are readily available.
- With [`allure`][allure], test report can be pretty nice and powerful.
- With reuse of [`locust`][locust], you can run performance test without extra work.
- CLI command supported, perfect combination with `CI/CD`.
## Subscribe
关注 HttpRunner 的微信公众号,第一时间获得最新资讯。
![](/assets/qrcode.jpg)
[requests]: http://docs.python-requests.org/en/master/
[pytest]: https://docs.pytest.org/
[pydantic]: https://pydantic-docs.helpmanual.io/
[locust]: http://locust.io/
[jmespath]: https://jmespath.org/
[allure]: https://docs.qameta.io/allure/
[HAR]: http://httparchive.org/

View File

@@ -15,7 +15,7 @@ If you want to keep up with the latest version, you can install with github repo
$ pip3 install git+https://github.com/httprunner/httprunner.git@master
```
If you have installed `HttpRunner` before and want to upgrade to the latest version, you can use the `-U` option.
If you have installed `HttpRunner` before and want to upgrade to the latest version, you can use the `-U` option.
```bash
$ pip3 install -U httprunner

View File

@@ -4,11 +4,11 @@
## 金牌赞助商Gold Sponsor
[<img src="https://docs.httprunner.org/assets/hogwarts.png" alt="霍格沃兹测试学院" width="400">](https://ceshiren.com/)
[<img src="https://raw.githubusercontent.com/httprunner/httprunner/master/docs/assets/hogwarts.jpeg" alt="霍格沃兹测试开发学社" width="400">](https://ceshiren.com/)
> [霍格沃兹测试学院](https://ceshiren.com/) 是业界领先的测试开发技术高端教育品牌,隶属于测吧(北京)科技有限公司。学院课程均由 BAT 一线测试大咖执教,提供实战驱动的接口自动化测试、移动自动化测试、性能测试、持续集成与 DevOps 等技术培训,以及测试开发优秀人才内推服务。[点击学习!](https://ke.qq.com/course/254956?flowToken=1014690)
> [霍格沃兹测试开发学社](http://qrcode.testing-studio.com/f?from=httprunner&url=https://ceshiren.com)是业界领先的测试开发技术高端教育品牌,隶属于[测吧(北京)科技有限公司](http://qrcode.testing-studio.com/f?from=httprunner&url=https://www.testing-studio.com) 。学院课程由一线大厂测试经理与资深测试开发专家参与研发,实战驱动。课程涵盖 web/app 自动化测试、接口测试、性能测试、安全测试、持续集成/持续交付/DevOps测试左移&右移、精准测试、测试平台开发、测试管理等内容,帮助测试工程师实现测试开发技术转型。通过优秀的学社制度(奖学金、内推返学费、行业竞赛等多种方式)来实现学员、学社及用人企业的三方共赢。
[霍格沃兹测试学院](https://ceshiren.com/) 是 HttpRunner 的首家金牌赞助商。
> [进入测试开发技术能力测评!](http://qrcode.testing-studio.com/f?from=httprunner&url=https://ceshiren.com/t/topic/14940)
### 开源服务赞助商Open Source Sponsor
@@ -22,5 +22,5 @@ HttpRunner is in Sentry Sponsored plan.
| 等级 | 金牌赞助商<br/>Gold Sponsor | 银牌赞助商<br/>Silver Sponsor| 个人赞赏 |
|:---:|:---:|:---:|:---:|
| 金额 | ¥10000/年 | ¥5000/年 | 任意 |
| 权益 | 公司 logo和链接展示在 README.md<br/>150 字的宣传文案 | 公司 logo和链接展示在 README.md<br/>50 字的宣传文案| 个人 ID 和链接展示在 sponsors.md |
| 金额 | ¥20000/年 | ¥8000/年 | 任意 |
| 权益 | 公司 logo和链接展示在 README.md<br/>200 字的宣传文案 | 公司 logo和链接展示在 README.md<br/>80 字的宣传文案| 个人 ID 和链接展示在 sponsors.md |

View File

@@ -1,4 +1,4 @@
# NOTE: Generated By HttpRunner v3.1.4
# NOTE: Generated By HttpRunner v3.1.7
# FROM: basic.yml

View File

@@ -1,4 +1,4 @@
# NOTE: Generated By HttpRunner v3.1.4
# NOTE: Generated By HttpRunner v3.1.7
# FROM: hooks.yml

View File

@@ -1,4 +1,4 @@
# NOTE: Generated By HttpRunner v3.1.4
# NOTE: Generated By HttpRunner v3.1.7
# FROM: load_image.yml

View File

@@ -1,4 +1,4 @@
# NOTE: Generated By HttpRunner v3.1.4
# NOTE: Generated By HttpRunner v3.1.7
# FROM: upload.yml

View File

@@ -1,4 +1,4 @@
# NOTE: Generated By HttpRunner v3.1.4
# NOTE: Generated By HttpRunner v3.1.7
# FROM: validate.yml

View File

@@ -53,7 +53,7 @@ def session_fixture(request):
testcase_summary_json["records"] = testcase_summary_json.pop("step_datas")
summary["details"].append(testcase_summary_json)
summary_path = "/Users/debugtalk/MyProjects/HttpRunner-dev/HttpRunner/examples/postman_echo/logs/request_methods/hardcode.summary.json"
summary_path = r"/Users/debugtalk/MyProjects/HttpRunner-dev/httprunner/examples/postman_echo/logs/request_methods/hardcode.summary.json"
summary_dir = os.path.dirname(summary_path)
os.makedirs(summary_dir, exist_ok=True)

View File

@@ -0,0 +1 @@
# NOTICE: Generated By HttpRunner. DO NOT EDIT!

View File

@@ -2,7 +2,7 @@ config:
name: "set & delete cookies."
base_url: "https://postman-echo.com"
verify: False
export: ["cookie_foo1", "cookie_foo3"]
export: ["cookie_foo1"]
teststeps:
-
@@ -16,10 +16,11 @@ teststeps:
headers:
User-Agent: HttpRunner/${get_httprunner_version()}
extract:
cookie_foo1: $.cookies.foo1
cookie_foo1: body.cookies.foo1
validate:
- eq: ["status_code", 200]
- eq: ["cookies.foo1", "bar1"]
- eq: ["body.cookies.foo1", "bar1"]
- eq: ["body.cookies.foo2", "bar2"]
-
name: delete cookie foo2
request:
@@ -29,6 +30,5 @@ teststeps:
User-Agent: HttpRunner/${get_httprunner_version()}
validate:
- eq: ["status_code", 200]
- ne: ["$.cookies.foo1", "$foo1"]
- eq: ["$.cookies.foo1", "$cookie_foo1"]
- eq: ["$.cookies.foo3", "$cookie_foo3"]
- eq: ["body.cookies.foo1", "bar1"]
- eq: ["body.cookies.foo2", null]

View File

@@ -0,0 +1,43 @@
# NOTE: Generated By HttpRunner v3.1.7
# FROM: cookie_manipulation/hardcode.yml
from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
class TestCaseHardcode(HttpRunner):
config = (
Config("set & delete cookies.")
.base_url("https://postman-echo.com")
.verify(False)
.export(*["cookie_foo1"])
)
teststeps = [
Step(
RunRequest("set cookie foo1 & foo2 & foo3")
.get("/cookies/set")
.with_params(**{"foo1": "bar1", "foo2": "bar2"})
.with_headers(**{"User-Agent": "HttpRunner/${get_httprunner_version()}"})
.extract()
.with_jmespath("body.cookies.foo1", "cookie_foo1")
.validate()
.assert_equal("status_code", 200)
.assert_equal("body.cookies.foo1", "bar1")
.assert_equal("body.cookies.foo2", "bar2")
),
Step(
RunRequest("delete cookie foo2")
.get("/cookies/delete?foo2")
.with_headers(**{"User-Agent": "HttpRunner/${get_httprunner_version()}"})
.validate()
.assert_equal("status_code", 200)
.assert_equal("body.cookies.foo1", "bar1")
.assert_equal("body.cookies.foo2", None)
),
]
if __name__ == "__main__":
TestCaseHardcode().test_start()

View File

@@ -0,0 +1,46 @@
# NOTE: Generated By HttpRunner v3.1.7
# FROM: cookie_manipulation/set_delete_cookies.yml
from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
class TestCaseSetDeleteCookies(HttpRunner):
config = (
Config("set & delete cookies.")
.variables(**{"foo1": "bar1", "foo2": "bar2"})
.base_url("https://postman-echo.com")
.verify(False)
.export(*["cookie_foo1", "cookie_foo3"])
)
teststeps = [
Step(
RunRequest("set cookie foo1 & foo2 & foo3")
.with_variables(**{"foo3": "bar3"})
.get("/cookies/set")
.with_params(**{"foo1": "bar111", "foo2": "$foo2", "foo3": "$foo3"})
.with_headers(**{"User-Agent": "HttpRunner/${get_httprunner_version()}"})
.extract()
.with_jmespath("$.cookies.foo1", "cookie_foo1")
.with_jmespath("$.cookies.foo3", "cookie_foo3")
.validate()
.assert_equal("status_code", 200)
.assert_not_equal("$.cookies.foo3", "$foo3")
),
Step(
RunRequest("delete cookie foo2")
.get("/cookies/delete?foo2")
.with_headers(**{"User-Agent": "HttpRunner/${get_httprunner_version()}"})
.validate()
.assert_equal("status_code", 200)
.assert_not_equal("$.cookies.foo1", "$foo1")
.assert_equal("$.cookies.foo1", "$cookie_foo1")
.assert_equal("$.cookies.foo3", "$cookie_foo3")
),
]
if __name__ == "__main__":
TestCaseSetDeleteCookies().test_start()

View File

@@ -1,4 +1,4 @@
# NOTE: Generated By HttpRunner v3.1.4
# NOTE: Generated By HttpRunner v3.1.7
# FROM: request_methods/request_with_functions.yml

View File

@@ -1,4 +1,4 @@
# NOTE: Generated By HttpRunner v3.1.4
# NOTE: Generated By HttpRunner v3.1.7
# FROM: request_methods/request_with_testcase_reference.yml

View File

@@ -1,4 +1,4 @@
# NOTE: Generated By HttpRunner v3.1.4
# NOTE: Generated By HttpRunner v3.1.7
# FROM: request_methods/hardcode.yml

View File

@@ -1,4 +1,4 @@
# NOTE: Generated By HttpRunner v3.1.4
# NOTE: Generated By HttpRunner v3.1.7
# FROM: request_methods/request_with_functions.yml

View File

@@ -1,4 +1,4 @@
# NOTE: Generated By HttpRunner v3.1.4
# NOTE: Generated By HttpRunner v3.1.7
# FROM: request_methods/request_with_parameters.yml

View File

@@ -1,4 +1,4 @@
# NOTE: Generated By HttpRunner v3.1.4
# NOTE: Generated By HttpRunner v3.1.7
# FROM: request_methods/request_with_testcase_reference.yml

View File

@@ -1,4 +1,4 @@
# NOTE: Generated By HttpRunner v3.1.4
# NOTE: Generated By HttpRunner v3.1.7
# FROM: request_methods/request_with_variables.yml

View File

@@ -1,4 +1,4 @@
# NOTE: Generated By HttpRunner v3.1.4
# NOTE: Generated By HttpRunner v3.1.7
# FROM: request_methods/validate_with_functions.yml

View File

@@ -1,4 +1,4 @@
# NOTE: Generated By HttpRunner v3.1.4
# NOTE: Generated By HttpRunner v3.1.7
# FROM: request_methods/validate_with_variables.yml

View File

@@ -1,4 +1,4 @@
__version__ = "3.1.6"
__version__ = "3.1.8-beta"
__description__ = "One-stop solution for HTTP(S) testing."
# import firstly for monkey patch if needed

View File

@@ -5,14 +5,13 @@ import sys
import pytest
from loguru import logger
from sentry_sdk import capture_message
from httprunner import __description__, __version__
from httprunner.compat import ensure_cli_args
from httprunner.ext.har2case import init_har2case_parser, main_har2case
from httprunner.make import init_make_parser, main_make
from httprunner.scaffold import init_parser_scaffold, main_scaffold
from httprunner.utils import init_sentry_sdk
from httprunner.utils import init_sentry_sdk, ga_client
init_sentry_sdk()
@@ -25,7 +24,7 @@ def init_parser_run(subparsers):
def main_run(extra_args) -> enum.IntEnum:
capture_message("start to run")
ga_client.track_event("RunAPITests", "hrun")
# keep compatibility with v2
extra_args = ensure_cli_args(extra_args)

View File

@@ -181,19 +181,19 @@ class HttpSession(requests.Session):
try:
client_ip, client_port = response.raw.connection.sock.getsockname()
self.data.address.client_ip = client_ip
self.data.address.client_port = client_port
logger.debug(f"client IP: {client_ip}, Port: {client_port}")
except AttributeError as ex:
logger.warning(f"failed to get client address info: {ex}")
except AttributeError:
client_ip, client_port = response.raw.connection.sock.socket.getsockname()
self.data.address.client_ip = client_ip
self.data.address.client_port = client_port
logger.debug(f"client IP: {client_ip}, Port: {client_port}")
try:
server_ip, server_port = response.raw.connection.sock.getpeername()
self.data.address.server_ip = server_ip
self.data.address.server_port = server_port
logger.debug(f"server IP: {server_ip}, Port: {server_port}")
except AttributeError as ex:
logger.warning(f"failed to get server address info: {ex}")
except AttributeError:
server_ip, server_port = response.raw.connection.sock.socket.getpeername()
self.data.address.server_ip = server_ip
self.data.address.server_port = server_port
logger.debug(f"server IP: {server_ip}, Port: {server_port}")
# get length of the response content
content_size = int(dict(response.headers).get("content-length") or 0)

View File

@@ -10,7 +10,7 @@ Usage:
"""
from httprunner.ext.har2case.core import HarParser
from sentry_sdk import capture_message
from httprunner.utils import ga_client
def init_har2case_parser(subparsers):
@@ -64,7 +64,7 @@ def main_har2case(args):
else:
output_file_type = "pytest"
capture_message(f"har2case {output_file_type}")
ga_client.track_event("ConvertTests", f"har2case {output_file_type}")
HarParser(har_source_file, args.filter, args.exclude, args.profile).gen_testcase(output_file_type)
return 0

View File

@@ -70,11 +70,8 @@ def prepare_locust_tests() -> List:
def main_locusts():
""" locusts entrance
"""
from httprunner.utils import init_sentry_sdk
from sentry_sdk import capture_message
init_sentry_sdk()
capture_message("start to run locusts")
from httprunner.utils import ga_client
ga_client.track_event("RunLoadTests", "locust")
# avoid print too much log details in console
logger.remove()

View File

@@ -4,23 +4,14 @@ import json
import os
import sys
import types
from typing import Tuple, Dict, Union, Text, List, Callable
from typing import Callable, Dict, List, Text, Tuple, Union
import yaml
from loguru import logger
from pydantic import ValidationError
from httprunner import builtin, utils
from httprunner import exceptions
from httprunner.models import TestCase, ProjectMeta, TestSuite
try:
# PyYAML version >= 5.1
# ref: https://github.com/yaml/pyyaml/wiki/PyYAML-yaml.load(input)-Deprecation
yaml.warnings({"YAMLLoadWarning": False})
except AttributeError:
pass
from httprunner import builtin, exceptions, utils
from httprunner.models import ProjectMeta, TestCase, TestSuite
project_meta: Union[ProjectMeta, None] = None
@@ -30,7 +21,7 @@ def _load_yaml_file(yaml_file: Text) -> Dict:
"""
with open(yaml_file, mode="rb") as stream:
try:
yaml_content = yaml.load(stream)
yaml_content = yaml.load(stream, Loader=yaml.FullLoader)
except yaml.YAMLError as ex:
err_msg = f"YAMLError:\nfile: {yaml_file}\nerror: {ex}"
logger.error(err_msg)
@@ -130,6 +121,9 @@ def load_dot_env_file(dot_env_path: Text) -> Dict:
with open(dot_env_path, mode="rb") as fp:
for line in fp:
# maxsplit=1
line = line.strip()
if not len(line) or line.startswith(b"#"):
continue
if b"=" in line:
variable, value = line.split(b"=", 1)
elif b":" in line:
@@ -450,4 +444,4 @@ def convert_relative_project_root_dir(abs_path: Text) -> Text:
f"project_meta.RootDir: {_project_meta.RootDir}"
)
return abs_path[len(_project_meta.RootDir) + 1 :]
return abs_path[len(_project_meta.RootDir) + 1:]

View File

@@ -2,29 +2,21 @@ import os
import string
import subprocess
import sys
from typing import Text, List, Tuple, Dict, Set, NoReturn
from typing import Dict, List, NoReturn, Set, Text, Tuple
import jinja2
from loguru import logger
from sentry_sdk import capture_exception
from httprunner import exceptions, __version__
from httprunner.compat import (
ensure_testcase_v3_api,
ensure_testcase_v3,
convert_variables,
ensure_path_sep,
)
from httprunner.loader import (
load_folder_files,
load_test_file,
load_testcase,
load_testsuite,
load_project_meta,
convert_relative_project_root_dir,
)
from httprunner import __version__, exceptions
from httprunner.compat import (convert_variables, ensure_path_sep,
ensure_testcase_v3, ensure_testcase_v3_api)
from httprunner.loader import (convert_relative_project_root_dir,
load_folder_files, load_project_meta,
load_test_file, load_testcase, load_testsuite)
from httprunner.response import uniform_validator
from httprunner.utils import merge_variables, is_support_multiprocessing
from httprunner.utils import (ga_client, is_support_multiprocessing,
merge_variables)
""" cache converted pytest files, avoid duplicate making
"""
@@ -80,10 +72,10 @@ if __name__ == "__main__":
def __ensure_absolute(path: Text) -> Text:
if path.startswith("./"):
# Linux/Darwin, hrun ./test.yml
path = path[len("./") :]
path = path[len("./"):]
elif path.startswith(".\\"):
# Windows, hrun .\\test.yml
path = path[len(".\\") :]
path = path[len(".\\"):]
path = ensure_path_sep(path)
project_meta = load_project_meta(path)
@@ -173,7 +165,7 @@ def format_pytest_with_black(*python_paths: Text) -> NoReturn:
subprocess.run(["black", *python_paths])
else:
logger.warning(
f"this system does not support multiprocessing well, format files one by one ..."
"this system does not support multiprocessing well, format files one by one ..."
)
[subprocess.run(["black", path]) for path in python_paths]
except subprocess.CalledProcessError as ex:
@@ -590,6 +582,8 @@ def main_make(tests_paths: List[Text]) -> List[Text]:
if not tests_paths:
return []
ga_client.track_event("ConvertTests", "hmake")
for tests_path in tests_paths:
tests_path = ensure_path_sep(tests_path)
if not os.path.isabs(tests_path):

View File

@@ -3,7 +3,8 @@ import subprocess
import sys
from loguru import logger
from sentry_sdk import capture_message
from httprunner.utils import ga_client
def init_parser_scaffold(subparsers):
@@ -199,5 +200,5 @@ def sleep(n_secs):
def main_scaffold(args):
capture_message("startproject with scaffold")
ga_client.track_event("Scaffold", "startproject")
sys.exit(create_scaffold(args.project_name))

View File

@@ -1,18 +1,18 @@
import collections
import copy
import itertools
import json
import os.path
import platform
import uuid
from multiprocessing import Queue
import itertools
from typing import Dict, List, Any, Union, Text
from typing import Any, Dict, List, Text
import requests
import sentry_sdk
from loguru import logger
from httprunner import __version__
from httprunner import exceptions
from httprunner import __version__, exceptions
from httprunner.models import VariablesMapping
@@ -25,6 +25,48 @@ def init_sentry_sdk():
scope.set_user({"id": uuid.getnode()})
class GAClient(object):
version = '1' # GA API Version
report_url = 'https://www.google-analytics.com/collect'
report_debug_url = 'https://www.google-analytics.com/debug/collect' # used for debug
def __init__(self, tracking_id: Text):
self.http_client = requests.Session()
self.label = str(__version__)
self.common_params = {
'v': self.version,
'tid': tracking_id, # Tracking ID / Property ID, XX-XXXXXXX-X
'cid': uuid.getnode(), # Anonymous Client ID
'ua': f'HttpRunner/{__version__}',
}
def track_event(self, category: Text, action: Text, value: int = 0):
data = {
't': 'event', # Event hit type = event
'ec': category, # Required. Event Category.
'ea': action, # Required. Event Action.
'el': self.label, # Optional. Event label, used as version.
'ev': value, # Optional. Event value, must be non-negative integer
}
data.update(self.common_params)
self.http_client.post(self.report_url, data=data)
def track_user_timing(self, category: Text, variable: Text, duration: int):
data = {
't': 'timing', # Event hit type = timing
'utc': category, # Required. user timing category. e.g. jsonLoader
'utv': variable, # Required. timing variable. e.g. load
'utt': duration, # Required. time took duration.
'utl': self.label, # Optional. user timing label, used as version.
}
data.update(self.common_params)
self.http_client.post(self.report_url, data=data)
ga_client = GAClient("UA-114587036-1")
def set_os_environ(variables_mapping):
""" set variables mapping to os.environ
"""

View File

@@ -1,6 +1,9 @@
# install mkdocs
# $ pip install mkdocs # 1.1.2
# $ pip install mkdocs-material # 5.2.2
# install mkdocs and material design
# $ pip install mkdocs-material
# usage
# $ mkdocs serve # build docs and preview
# $ mkdocs gh-deploy # Deploy your documentation to GitHub Pages
# Project information
site_name: HttpRunner V3.x Docs
@@ -13,7 +16,7 @@ repo_url: https://github.com/httprunner/httprunner
edit_uri: ""
# Copyright
copyright: 'Copyright &copy; 2017 - 2020 debugtalk'
copyright: 'Copyright &copy; 2017 - 2021 debugtalk'
# Configuration
theme:
@@ -26,11 +29,6 @@ theme:
text: 'Roboto'
code: 'Roboto Mono'
# Google Analytics
google_analytics:
- 'UA-114587036-3'
- 'auto'
# Extensions
markdown_extensions:
- admonition
@@ -38,6 +36,9 @@ markdown_extensions:
guess_lang: false
- toc:
permalink: true
- def_list
- pymdownx.tasklist:
custom_checkbox: true
# extra
extra:
@@ -48,10 +49,13 @@ extra:
link: https://debugtalk.com
- icon: fontawesome/brands/github-alt
link: 'https://github.com/httprunner'
analytics:
provider: google # Google Analytics
property: UA-114587036-3
# index pages
nav:
- Introduction: index.md
- README: README.md
- Installation: installation.md
- User Guide:
- Concepts: user/concepts.md

1869
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
[tool.poetry]
name = "httprunner"
version = "3.1.6"
version = "3.1.8-beta"
description = "One-stop solution for HTTP(S) testing."
license = "Apache-2.0"
readme = "README.md"
readme = "docs/README.md"
authors = ["debugtalk <debugtalk@gmail.com>"]
homepage = "https://github.com/httprunner/httprunner"
@@ -20,30 +20,31 @@ classifiers = [
"Operating System :: MacOS",
"Operating System :: POSIX :: Linux",
"Operating System :: Microsoft :: Windows",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8"
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10"
]
include = ["docs/CHANGELOG.md"]
[tool.poetry.dependencies]
python = "^3.6"
python = "^3.7"
requests = "^2.22.0"
pyyaml = "^5.1.2"
jinja2 = "^2.10.3"
pydantic = "^1.4"
pyyaml = "^5.4.1"
pydantic = "~1.8" # >=1.8.0 <1.9.0
loguru = "^0.4.1"
jmespath = "^0.9.5"
black = "^19.10b0"
pytest = "^5.4.2"
pytest-html = "^2.1.1"
pytest = "^7.1.1"
pytest-html = "^3.1.1"
sentry-sdk = "^0.14.4"
allure-pytest = {version = "^2.8.16", optional = true}
requests-toolbelt = {version = "^0.9.1", optional = true}
filetype = {version = "^1.0.7", optional = true}
locust = {version = "^1.0.3", optional = true}
Brotli = "^1.0.9"
jinja2 = "^3.0.3"
[tool.poetry.extras]
allure = ["allure-pytest"] # pip install "httprunner[allure]", poetry install -E allure
@@ -52,8 +53,8 @@ locust = ["locust"] # pip install "httprunner[locust]",
[tool.poetry.dev-dependencies]
coverage = "^4.5.4"
uvicorn = "^0.11.3"
fastapi = "^0.49.0"
fastapi = "^0.70.0"
uvicorn = "^0.17.6"
[tool.poetry.scripts]
httprunner = "httprunner.cli:main"
@@ -65,3 +66,7 @@ locusts = "httprunner.ext.locust:main_locusts"
[build-system]
requires = ["poetry>=1.0.0"]
build-backend = "poetry.masonry.api"
[[tool.poetry.source]]
name = "tsinghua"
url = "https://pypi.tuna.tsinghua.edu.cn/simple/"

View File

@@ -107,8 +107,8 @@ from request_methods.request_with_functions_test import (
)
loader.project_meta = None
self.assertEqual(
ensure_file_abs_path_valid(os.path.join(os.getcwd(), "README.md")),
os.path.join(os.getcwd(), "README.md"),
ensure_file_abs_path_valid(os.path.join(os.getcwd(), "pyproject.toml")),
os.path.join(os.getcwd(), "pyproject.toml"),
)
loader.project_meta = None
self.assertEqual(

View File

@@ -19,7 +19,7 @@ class TestScaffold(unittest.TestCase):
# run demo testcases
try:
if platform.system() is "Windows":
if platform.system() == "Windows":
subprocess.check_call(["hrun", project_name], shell=True)
else:
subprocess.check_call(["hrun", project_name])