mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-11 18:11:21 +08:00
Merge branch 'master' into master
This commit is contained in:
32
.github/workflows/integration_test.yml
vendored
32
.github/workflows/integration_test.yml
vendored
@@ -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
|
||||
|
||||
13
.github/workflows/unittest.yml
vendored
13
.github/workflows/unittest.yml
vendored
@@ -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
|
||||
|
||||
67
README.md
67
README.md
@@ -1,67 +0,0 @@
|
||||
|
||||
# HttpRunner
|
||||
|
||||
[](https://pepy.tech/project/httprunner)
|
||||
[](https://github.com/httprunner/httprunner/actions)
|
||||
[](https://github.com/httprunner/httprunner/actions)
|
||||
[](https://codecov.io/gh/httprunner/httprunner)
|
||||
[](https://pypi.python.org/pypi/httprunner)
|
||||
[](https://pypi.python.org/pypi/httprunner)
|
||||
[](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 的微信公众号,第一时间获得最新资讯。
|
||||
|
||||

|
||||
|
||||
[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/
|
||||
|
||||
|
||||
@@ -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
70
docs/README.md
Normal file
@@ -0,0 +1,70 @@
|
||||
|
||||
# HttpRunner
|
||||
|
||||
[](https://pepy.tech/project/httprunner)
|
||||
[](https://github.com/httprunner/httprunner/actions)
|
||||
[](https://github.com/httprunner/httprunner/actions)
|
||||
[](https://codecov.io/gh/httprunner/httprunner)
|
||||
[](https://pypi.python.org/pypi/httprunner)
|
||||
[](https://pypi.python.org/pypi/httprunner)
|
||||
[](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
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 |
@@ -1,49 +0,0 @@
|
||||
|
||||
# HttpRunner
|
||||
|
||||
[](https://pepy.tech/project/httprunner)
|
||||
[](https://github.com/httprunner/httprunner/actions)
|
||||
[](https://github.com/httprunner/httprunner/actions)
|
||||
[](https://codecov.io/gh/httprunner/httprunner)
|
||||
[](https://pypi.python.org/pypi/httprunner)
|
||||
[](https://pypi.python.org/pypi/httprunner)
|
||||
[](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 的微信公众号,第一时间获得最新资讯。
|
||||
|
||||

|
||||
|
||||
[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/
|
||||
@@ -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
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# NOTE: Generated By HttpRunner v3.1.4
|
||||
# NOTE: Generated By HttpRunner v3.1.7
|
||||
# FROM: basic.yml
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# NOTE: Generated By HttpRunner v3.1.4
|
||||
# NOTE: Generated By HttpRunner v3.1.7
|
||||
# FROM: hooks.yml
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# NOTE: Generated By HttpRunner v3.1.4
|
||||
# NOTE: Generated By HttpRunner v3.1.7
|
||||
# FROM: load_image.yml
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# NOTE: Generated By HttpRunner v3.1.4
|
||||
# NOTE: Generated By HttpRunner v3.1.7
|
||||
# FROM: upload.yml
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# NOTE: Generated By HttpRunner v3.1.4
|
||||
# NOTE: Generated By HttpRunner v3.1.7
|
||||
# FROM: validate.yml
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
1
examples/postman_echo/cookie_manipulation/__init__.py
Normal file
1
examples/postman_echo/cookie_manipulation/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# NOTICE: Generated By HttpRunner. DO NOT EDIT!
|
||||
@@ -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]
|
||||
|
||||
43
examples/postman_echo/cookie_manipulation/hardcode_test.py
Normal file
43
examples/postman_echo/cookie_manipulation/hardcode_test.py
Normal 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()
|
||||
@@ -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()
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# NOTE: Generated By HttpRunner v3.1.4
|
||||
# NOTE: Generated By HttpRunner v3.1.7
|
||||
# FROM: request_methods/hardcode.yml
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:]
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
"""
|
||||
|
||||
24
mkdocs.yml
24
mkdocs.yml
@@ -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 © 2017 - 2020 debugtalk'
|
||||
copyright: 'Copyright © 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
1869
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -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/"
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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])
|
||||
|
||||
Reference in New Issue
Block a user