From 6c7f12dd1b8fd7514d07f05f48e29266685c5ee9 Mon Sep 17 00:00:00 2001 From: t-bug Date: Fri, 6 Dec 2019 10:36:28 +0800 Subject: [PATCH 1/2] fix: several hooks in the test will be rearranged in the alphabetical order when parsing yaml(json) which will cause the test to be failed. fix: several hooks in the test will be rearranged in the alphabetical order when parsing yaml(json) which may cause the test to be failed. --- httprunner/parser.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/httprunner/parser.py b/httprunner/parser.py index 29b0a666..1b6b4d17 100644 --- a/httprunner/parser.py +++ b/httprunner/parser.py @@ -815,13 +815,17 @@ def _extend_with_api(test_dict, api_def_dict): # merge & override setup_hooks def_setup_hooks = api_def_dict.pop("setup_hooks", []) ref_setup_hooks = test_dict.get("setup_hooks", []) - extended_setup_hooks = list(set(def_setup_hooks + ref_setup_hooks)) + extended_setup_hooks_tmp = def_setup_hooks + ref_setup_hooks + extended_setup_hooks = list(set(extended_setup_hooks_tmp)) + extended_setup_hooks.sort(key=extended_setup_hooks_tmp.index) if extended_setup_hooks: test_dict["setup_hooks"] = extended_setup_hooks # merge & override teardown_hooks def_teardown_hooks = api_def_dict.pop("teardown_hooks", []) ref_teardown_hooks = test_dict.get("teardown_hooks", []) - extended_teardown_hooks = list(set(def_teardown_hooks + ref_teardown_hooks)) + extended_teardown_hooks_tmp = def_teardown_hooks + ref_teardown_hooks + extended_teardown_hooks = list(set(extended_teardown_hooks_tmp)) + extended_teardown_hooks.sort(key=extended_teardown_hooks_tmp.index) if extended_teardown_hooks: test_dict["teardown_hooks"] = extended_teardown_hooks From 0a397897d88c7eeb112990a16bca11ffe08ca44c Mon Sep 17 00:00:00 2001 From: Long Date: Wed, 11 Dec 2019 15:19:57 +0800 Subject: [PATCH 2/2] Add example --- docs/examples/test_klook/README.md | 22 +++++++++++++++++++ docs/examples/test_klook/__init__.py | 0 .../test_klook/api/find_place_api.yml | 19 ++++++++++++++++ .../test_klook/api/get_area_groups_api.yml | 11 ++++++++++ .../test_klook/api/place_detail_api.yml | 17 ++++++++++++++ .../api/search_area_by_name_api.yml | 11 ++++++++++ .../examples/test_klook/data/place_detail.csv | 3 +++ docs/examples/test_klook/debugtalk.py | 11 ++++++++++ .../testcases/find_place_testcase.yml | 19 ++++++++++++++++ .../testcases/get_area_groups_testcase.yml | 13 +++++++++++ .../testcases/just_request_testcase.yml | 9 ++++++++ .../testcases/place_detail_testcase.yml | 19 ++++++++++++++++ .../search_area_by_name_api_testcase.yml | 14 ++++++++++++ .../testsuites/area_manage_testsuite.yml | 16 ++++++++++++++ .../testsuites/place_detail_testsuite.yml | 22 +++++++++++++++++++ docs/examples/test_klook/utils/__init__.py | 0 docs/examples/test_klook/utils/setup_hooks.py | 0 .../test_klook/utils/teardown_hooks.py | 6 +++++ .../utils/validators/validators_of_area.py | 18 +++++++++++++++ .../utils/validators/validators_of_common.py | 3 +++ 20 files changed, 233 insertions(+) create mode 100644 docs/examples/test_klook/README.md create mode 100644 docs/examples/test_klook/__init__.py create mode 100644 docs/examples/test_klook/api/find_place_api.yml create mode 100644 docs/examples/test_klook/api/get_area_groups_api.yml create mode 100644 docs/examples/test_klook/api/place_detail_api.yml create mode 100644 docs/examples/test_klook/api/search_area_by_name_api.yml create mode 100644 docs/examples/test_klook/data/place_detail.csv create mode 100644 docs/examples/test_klook/debugtalk.py create mode 100644 docs/examples/test_klook/testcases/find_place_testcase.yml create mode 100644 docs/examples/test_klook/testcases/get_area_groups_testcase.yml create mode 100644 docs/examples/test_klook/testcases/just_request_testcase.yml create mode 100644 docs/examples/test_klook/testcases/place_detail_testcase.yml create mode 100644 docs/examples/test_klook/testcases/search_area_by_name_api_testcase.yml create mode 100644 docs/examples/test_klook/testsuites/area_manage_testsuite.yml create mode 100644 docs/examples/test_klook/testsuites/place_detail_testsuite.yml create mode 100644 docs/examples/test_klook/utils/__init__.py create mode 100644 docs/examples/test_klook/utils/setup_hooks.py create mode 100644 docs/examples/test_klook/utils/teardown_hooks.py create mode 100644 docs/examples/test_klook/utils/validators/validators_of_area.py create mode 100644 docs/examples/test_klook/utils/validators/validators_of_common.py diff --git a/docs/examples/test_klook/README.md b/docs/examples/test_klook/README.md new file mode 100644 index 00000000..80c07e3a --- /dev/null +++ b/docs/examples/test_klook/README.md @@ -0,0 +1,22 @@ +## 案例介绍 +我们团队在调研接口测试框架的时候选了httprunner,[让我](https://github.com/readyou)来负责给大家做一次分享,于是有了这里的示例。 + +## 注意事项 +1. 本例子中有些地方用到了`localhost:8085`作为base_url,这些接口是不能访问的,仅仅作为示例学习怎样组织测试用例。 +2. `https://maps.googleapis.com`是可以用的,自己申请一个key,替换掉文件中的`your_google_map_key`即可。 + +## 相关文件说明 +模块 | 文件 | 用途 | 备注 +---|----|------|------ +google map 接口测试 | api/find_place_api.yml | google map根据名称搜索地址的api | 比较全面地使用了api可以使用的关键字:name, base_url, request, variables, validate, extract +google map 接口测试 | testcases/find_place_testcase.yml | google map根据名称搜索地址的testcase | 使用了testcase标准的写法:testcase由teststep组成,teststep中引用api(just_request_testcase.yml中演示了直接使用request而不是引用api的方式)。teststep中还使用了variables。 +google map 接口测试 | testcases/place_detail_testcase.yml | google map获取地址详情的testcase | config中使用variables +google map 接口测试 | testsuites/place_detail_testsuite.yml | google map接口测试的testsuite包含上面两个testcase | 使用了多种方式来做数据驱动测试 + | | +klook地理位置搜索接口测试 | api/search_area_by_name_api.yml | 根据名字查询区域(支持多语言)——api | +klook地理位置搜索接口测试 | api/search_area_by_name_testcase.yml | 根据名字查询区域(支持多语言)——testcase | +klook地理位置搜索接口测试 | api/get_area_groups_api.yml | 查询地理位置下面的组——api | +klook地理位置搜索接口测试 | api/get_area_groups_testcase.yml | 查询地理位置下面的组——testcase | +klook地理位置搜索接口测试 | api/area_manage_testsuite.yml | 区域管理——testsuite | + | | +baidu首页demo | testcases/just_request_testcase.yml | 提取百度首页title的demo | 演示了直接使用request而不是引用api的方式,使用了teardown_hooks的使用 \ No newline at end of file diff --git a/docs/examples/test_klook/__init__.py b/docs/examples/test_klook/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/docs/examples/test_klook/api/find_place_api.yml b/docs/examples/test_klook/api/find_place_api.yml new file mode 100644 index 00000000..394def72 --- /dev/null +++ b/docs/examples/test_klook/api/find_place_api.yml @@ -0,0 +1,19 @@ +name: find place from text +base_url: https://maps.googleapis.com +request: + method: GET + url: /maps/api/place/findplacefromtext/json + params: + key: $key + inputtype: textquery + input: $input + fields: 'formatted_address,geometry,name,permanently_closed,place_id,plus_code,types' + language: zh_CN +variables: + input: 宝安 + key: your_google_map_key +validate: + - eq: [status_code, 200] + - eq: [content.status, OK] +extract: + - place_id: content.candidates.0.place_id diff --git a/docs/examples/test_klook/api/get_area_groups_api.yml b/docs/examples/test_klook/api/get_area_groups_api.yml new file mode 100644 index 00000000..44b66ef5 --- /dev/null +++ b/docs/examples/test_klook/api/get_area_groups_api.yml @@ -0,0 +1,11 @@ +name: get_groups +base_url: http://localhost:8085 +request: + url: /v1/transferairportadminsrv/area/getGroups + method: POST + headers: + Content-Type: application/x-www-form-urlencoded + Accept-language: zh_CN + cookie: $admin_cookie + data: + parentAreaId: 7037 # 广东省 diff --git a/docs/examples/test_klook/api/place_detail_api.yml b/docs/examples/test_klook/api/place_detail_api.yml new file mode 100644 index 00000000..158a867b --- /dev/null +++ b/docs/examples/test_klook/api/place_detail_api.yml @@ -0,0 +1,17 @@ +name: get place detail +request: + method: GET + url: https://maps.googleapis.com/maps/api/place/details/json + params: + key: $key + placeid: $place_id + fields: 'address_component,formatted_address,geometry' + language: zh-CN +variables: + key: your_google_map_key + place_id: ChIJzyoujG6SAzQRRD3Jr26PFfM +validate: + - eq: [status_code, 200] + - eq: [content.status, OK] +extract: + - place_name: content.result.formatted_address diff --git a/docs/examples/test_klook/api/search_area_by_name_api.yml b/docs/examples/test_klook/api/search_area_by_name_api.yml new file mode 100644 index 00000000..fe04bb06 --- /dev/null +++ b/docs/examples/test_klook/api/search_area_by_name_api.yml @@ -0,0 +1,11 @@ +name: search_area_by_name +base_url: http://localhost:8085 +request: + url: /v1/transferairportadminsrv/area/search_area_by_name + method: GET + headers: + Content-Type: application/x-www-form-urlencoded + Accept-language: zh_CN + cookie: $admin_cookie + params: + areaName: $in diff --git a/docs/examples/test_klook/data/place_detail.csv b/docs/examples/test_klook/data/place_detail.csv new file mode 100644 index 00000000..863c196c --- /dev/null +++ b/docs/examples/test_klook/data/place_detail.csv @@ -0,0 +1,3 @@ +input,formatted_address,address_components_len +娄底,中国湖南省娄底市,3 +新化,中国湖南省娄底市新化县,4 \ No newline at end of file diff --git a/docs/examples/test_klook/debugtalk.py b/docs/examples/test_klook/debugtalk.py new file mode 100644 index 00000000..7c2e552a --- /dev/null +++ b/docs/examples/test_klook/debugtalk.py @@ -0,0 +1,11 @@ +from utils.validators.validators_of_area import * +from utils.validators.validators_of_common import * +from utils.setup_hooks import * +from utils.teardown_hooks import * + +__all__ = [ + klook_len_eq, + check_search_area_result, + exists_default_group, + teardown_hook_set_encoding +] diff --git a/docs/examples/test_klook/testcases/find_place_testcase.yml b/docs/examples/test_klook/testcases/find_place_testcase.yml new file mode 100644 index 00000000..339cc90b --- /dev/null +++ b/docs/examples/test_klook/testcases/find_place_testcase.yml @@ -0,0 +1,19 @@ +name: find place from text testcase +config: + base_url: https://maps.googleapis.com + # config 这里的variables优先级更高 + # 如果本testcase被其他testcase引用,variables无法覆盖这里配置的值 + # variables: + # input: 福田 + # formatted_address: 中国广东省深圳市福田区 +teststeps: + - name: find place + api: api/find_place_api.yml + # 如果config上面配置了,这里的同名变量会被覆盖 + variables: + input: 深圳 + formatted_address: 中国广东省深圳市 + validate: + - eq: [content.candidates.0.formatted_address, $formatted_address] + extract: + - formatted_address: formatted_address"\s?:\s?"(.*)" \ No newline at end of file diff --git a/docs/examples/test_klook/testcases/get_area_groups_testcase.yml b/docs/examples/test_klook/testcases/get_area_groups_testcase.yml new file mode 100644 index 00000000..43e414ca --- /dev/null +++ b/docs/examples/test_klook/testcases/get_area_groups_testcase.yml @@ -0,0 +1,13 @@ +config: + base_url: http://127.0.0.1:8085 + variables: + admin_cookie: 'cookies' + +teststeps: + - name: get group by parent area id + api: api/get_area_groups_api.yml + validate: + - eq: [status_code, 200] + - eq: [headers.Content-Type, application/json] + - eq: [content.success, true] + - exists_default_group: [content.result, ''] diff --git a/docs/examples/test_klook/testcases/just_request_testcase.yml b/docs/examples/test_klook/testcases/just_request_testcase.yml new file mode 100644 index 00000000..98a5ec85 --- /dev/null +++ b/docs/examples/test_klook/testcases/just_request_testcase.yml @@ -0,0 +1,9 @@ +teststeps: + - name: extract title + request: + method: GET + url: http://www.baidu.com + extract: + - title: (.*) + teardown_hooks: + - ${teardown_hook_set_encoding($response, utf-8)} \ No newline at end of file diff --git a/docs/examples/test_klook/testcases/place_detail_testcase.yml b/docs/examples/test_klook/testcases/place_detail_testcase.yml new file mode 100644 index 00000000..01eb1e27 --- /dev/null +++ b/docs/examples/test_klook/testcases/place_detail_testcase.yml @@ -0,0 +1,19 @@ +name: get place detail +config: + base_url: https://maps.googleapis.com + variables: + input: 娄底 + formatted_address: 中国湖南省娄底市 + address_components_len: 3 +teststeps: + # 文档里面说这里可以使用testcase,测试了一下,这种方式还有问题,使用testcase时,api里面的变量无法正常覆盖 + # 所以:teststep中最好不要使用testcase引用 + - name: find place + api: api/find_place_api.yml + validate: + - eq: [content.candidates.0.formatted_address, $formatted_address] + - name: get place detail + api: api/place_detail_api.yml + validate: + - eq: [content.result.formatted_address, $formatted_address] + - klook_len_eq: [content.result.address_components, $address_components_len] diff --git a/docs/examples/test_klook/testcases/search_area_by_name_api_testcase.yml b/docs/examples/test_klook/testcases/search_area_by_name_api_testcase.yml new file mode 100644 index 00000000..f16554d6 --- /dev/null +++ b/docs/examples/test_klook/testcases/search_area_by_name_api_testcase.yml @@ -0,0 +1,14 @@ +config: + base_url: http://localhost:8085 + variables: + admin_cookie: 'cookies' + +teststeps: + - name: search area by name + api: api/search_area_by_name_api.yml + variables: + in: 北京 + out: 中国北京市 + validate: + - eq: [content.success, true] + - check_search_area_result: [content.result, $out] diff --git a/docs/examples/test_klook/testsuites/area_manage_testsuite.yml b/docs/examples/test_klook/testsuites/area_manage_testsuite.yml new file mode 100644 index 00000000..10fc016c --- /dev/null +++ b/docs/examples/test_klook/testsuites/area_manage_testsuite.yml @@ -0,0 +1,16 @@ +config: + name: area manage testsuite + variables: + admin_cookie: 'cookies' + base_url: http://127.0.0.1:8085 + verify: False + +testcases: + - name: search area by name + testcase: testcases/search_area_by_name_api_testcase.yml + parameters: + in-out: + - ['北京', '中国, 北京市'] + - ['广东', '中国, 广东省'] + - ['shenzhen', '中国, 广东省, 深圳市'] + - ['서울', '韩国, 首尔'] diff --git a/docs/examples/test_klook/testsuites/place_detail_testsuite.yml b/docs/examples/test_klook/testsuites/place_detail_testsuite.yml new file mode 100644 index 00000000..e7f0afe3 --- /dev/null +++ b/docs/examples/test_klook/testsuites/place_detail_testsuite.yml @@ -0,0 +1,22 @@ +name: get place detail testsuites +config: + base_url: https://maps.googleapis.com +testcases: + - name: find place from text + testcase: testcases/find_place_testcase.yml + parameters: + input-formatted_address: + - [娄底, 中国湖南省娄底市] + - [新化, 中国湖南省娄底市新化县] + - ['北京', '中国北京市'] + - ['广东', '中国广东省'] + - ['shenzhen', '中国广东省深圳市'] + - ['서울', '韩国汉城'] + + - name: get place detail + testcase: testcases/place_detail_testcase.yml + parameters: + input-formatted_address-address_components_len: ${P(data/place_detail.csv)} + # input-formatted_address-address_components_len: + # - [娄底, 中国湖南省娄底市, 3] + # - [新化, 中国湖南省娄底市新化县, 4] \ No newline at end of file diff --git a/docs/examples/test_klook/utils/__init__.py b/docs/examples/test_klook/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/docs/examples/test_klook/utils/setup_hooks.py b/docs/examples/test_klook/utils/setup_hooks.py new file mode 100644 index 00000000..e69de29b diff --git a/docs/examples/test_klook/utils/teardown_hooks.py b/docs/examples/test_klook/utils/teardown_hooks.py new file mode 100644 index 00000000..83443829 --- /dev/null +++ b/docs/examples/test_klook/utils/teardown_hooks.py @@ -0,0 +1,6 @@ +def teardown_hook_set_encoding(response, encoding): + """ + Set encoding of response. + """ + response.resp_obj.encoding = encoding + return response diff --git a/docs/examples/test_klook/utils/validators/validators_of_area.py b/docs/examples/test_klook/utils/validators/validators_of_area.py new file mode 100644 index 00000000..d91d75b7 --- /dev/null +++ b/docs/examples/test_klook/utils/validators/validators_of_area.py @@ -0,0 +1,18 @@ +def check_search_area_result(content, expect_name): + print(content, expect_name) + found = False + for item in content: + if item['fullName'] == expect_name: + found = True + break + assert found + + +def exists_default_group(content, expect): + found = False + for item in content: + if item['defaultGroup']: + print('defaultGroup found, id={}, parentAreaId={}'.format(item['id'], item['parentAreaId'])) + found = True + break + assert found diff --git a/docs/examples/test_klook/utils/validators/validators_of_common.py b/docs/examples/test_klook/utils/validators/validators_of_common.py new file mode 100644 index 00000000..86c88da3 --- /dev/null +++ b/docs/examples/test_klook/utils/validators/validators_of_common.py @@ -0,0 +1,3 @@ +def klook_len_eq(check_value, expect_value): + # 校验列表、字典、字符串等长度是否相等 + assert len(check_value) == int(expect_value)