├── comm
├── script
│ ├── __init__.py
│ ├── writeLogs.py
│ └── writeCase.py
├── unit
│ ├── __init__.py
│ ├── readRelevance.py
│ ├── queryDatabase.py
│ ├── initializePremise.py
│ ├── apiSend.py
│ └── replaceRelevance.py
├── __init__.py
├── utils
│ ├── __init__.py
│ ├── readJson.py
│ ├── readYaml.py
│ ├── readConf.py
│ └── randomly.py
└── db
│ ├── __init__.py
│ ├── queryRedis.py
│ ├── queryHBase.py
│ ├── querySolr.py
│ ├── queryMysql.py
│ └── queryES.py
├── logs
├── 2021-02-04_error.log
└── 2021-02-04.log
├── .gitignore
├── PyDemo
├── report
│ ├── html
│ │ ├── widgets
│ │ │ ├── launch.json
│ │ │ ├── environment.json
│ │ │ ├── executors.json
│ │ │ ├── duration-trend.json
│ │ │ ├── categories-trend.json
│ │ │ ├── retry-trend.json
│ │ │ ├── history-trend.json
│ │ │ ├── behaviors.json
│ │ │ ├── categories.json
│ │ │ ├── suites.json
│ │ │ ├── summary.json
│ │ │ ├── duration.json
│ │ │ ├── severity.json
│ │ │ └── status-chart.json
│ │ ├── data
│ │ │ ├── attachments
│ │ │ │ ├── a10e5441521817af.attach
│ │ │ │ ├── a142325f6ec7dd97.attach
│ │ │ │ ├── a404884c53f9a95e.attach
│ │ │ │ ├── b5dbaecb2dacdb90.attach
│ │ │ │ ├── d57f284c2a250050.attach
│ │ │ │ ├── e5cdc98bcb63fce1.attach
│ │ │ │ ├── e645f31e66475871.attach
│ │ │ │ ├── f658b4378482d4a.attach
│ │ │ │ ├── de7b006637c1f824.attach
│ │ │ │ ├── 64929705a353786a.attach
│ │ │ │ ├── d4cfa82e3954b068.attach
│ │ │ │ ├── 3f3d3b675f8b38f0.attach
│ │ │ │ ├── aa3749b1bd00dd8e.attach
│ │ │ │ ├── 6d6990d6bc7da779.attach
│ │ │ │ ├── 47e7333bf43a045.attach
│ │ │ │ ├── ea0ced6a1ef79518.attach
│ │ │ │ ├── 436a2d6b50675cb6.attach
│ │ │ │ ├── 4ac290f03a0b29ab.attach
│ │ │ │ ├── 10ea6ae95941448c.attach
│ │ │ │ ├── 45bb27deeb34ae52.attach
│ │ │ │ ├── 48d8349a567cd920.attach
│ │ │ │ ├── 7f88a98d6e750e3c.attach
│ │ │ │ ├── d8d657fe62f789ca.attach
│ │ │ │ ├── 9c97dfe6f36b3570.attach
│ │ │ │ ├── 5627e81e1f308560.attach
│ │ │ │ ├── a2493f73f5b55797.attach
│ │ │ │ ├── 7a7457e66b250a1f.attach
│ │ │ │ ├── 640913aa912828ba.attach
│ │ │ │ ├── b2611d9bc9f7e7f2.attach
│ │ │ │ ├── bdc87a179c292ab3.attach
│ │ │ │ ├── d7e1801c64f284ab.attach
│ │ │ │ ├── 64a95aad22c4bff3.txt
│ │ │ │ ├── 1dd259f7ca780bf0.attach
│ │ │ │ ├── 4874af030f961a0.attach
│ │ │ │ └── e100c861d9156d57.attach
│ │ │ ├── categories.csv
│ │ │ ├── behaviors.csv
│ │ │ ├── suites.csv
│ │ │ ├── categories.json
│ │ │ ├── timeline.json
│ │ │ ├── behaviors.json
│ │ │ ├── packages.json
│ │ │ ├── suites.json
│ │ │ └── test-cases
│ │ │ │ ├── aa8dfcaa510813c2.json
│ │ │ │ ├── 10d4bd6301177f6.json
│ │ │ │ └── 7d4ed4f7a18b20d4.json
│ │ ├── favicon.ico
│ │ ├── history
│ │ │ ├── duration-trend.json
│ │ │ ├── categories-trend.json
│ │ │ ├── retry-trend.json
│ │ │ ├── history-trend.json
│ │ │ └── history.json
│ │ ├── export
│ │ │ ├── mail.html
│ │ │ ├── prometheusData.txt
│ │ │ └── influxDbData.txt
│ │ ├── plugins
│ │ │ ├── screen-diff
│ │ │ │ ├── styles.css
│ │ │ │ └── index.js
│ │ │ ├── packages
│ │ │ │ └── index.js
│ │ │ └── behaviors
│ │ │ │ └── index.js
│ │ └── index.html
│ └── xml
│ │ ├── 13581612-dbff-44e2-b614-28aeaf763e53-attachment.attach
│ │ ├── 15a5ed09-71be-4302-8da3-f1a3833890c3-attachment.attach
│ │ ├── 2d3cbb34-52fb-4b35-80e8-179d043a1226-attachment.attach
│ │ ├── 30403406-d497-4fa4-8a90-e52a5f1723aa-attachment.attach
│ │ ├── 33849d22-c42b-4fd4-b486-acfe3922e91a-attachment.attach
│ │ ├── a925524d-3c79-42dc-a506-ac9353b81a89-attachment.attach
│ │ ├── c5f832b3-c5da-4106-8a5d-8bc617600550-attachment.attach
│ │ ├── eb8ba490-0f39-42ba-9a1c-44e5ee2a0636-attachment.attach
│ │ ├── 9487b1b8-64e5-49d0-a0ea-f2254a0a983f-attachment.attach
│ │ ├── 8a751566-67d8-4a28-943a-a0c8cecc3a9f-attachment.attach
│ │ ├── b6a76b88-e182-454b-ba36-1e34a5c19222-attachment.attach
│ │ ├── da39ce35-693c-4f48-92cd-7795dd783e88-attachment.attach
│ │ ├── f1dc7f0e-4445-425a-b4b7-f4b073d49233-attachment.attach
│ │ ├── d354f47a-3693-4b7b-86df-cd34ace4ac9c-attachment.attach
│ │ ├── 194b21ff-bc74-4712-9e00-2d4d10c529f3-attachment.attach
│ │ ├── a6f8bf5f-a42a-4c47-a026-243375a5685d-attachment.attach
│ │ ├── 848e4b5e-7e91-4f72-874b-659053c3e48d-attachment.attach
│ │ ├── e9a38fd0-5f1b-4739-a472-7606737e0911-attachment.attach
│ │ ├── 067d3035-4727-4009-af05-75776743f64e-attachment.attach
│ │ ├── 4f67b9c3-4ae0-4945-9697-c30b6dbbcbf0-attachment.attach
│ │ ├── 7c22884c-0191-4937-b2d2-12214a869f4c-attachment.attach
│ │ ├── d3f438ee-fde7-483c-9a1b-87ce48d23359-attachment.attach
│ │ ├── f8618d25-7423-4d9f-a777-b1bc37ee3fd5-attachment.attach
│ │ ├── 5f34e443-5ec3-41cf-9002-dd92ec056d54-attachment.attach
│ │ ├── 6bc3acef-572c-47fe-9093-56a69faa51ed-attachment.attach
│ │ ├── bc8c8933-6042-4cfe-a825-a19018c34101-attachment.attach
│ │ ├── aa05cb30-25c4-4485-b7f9-1aa4fd98e692-attachment.attach
│ │ ├── 0d998249-b346-4cb4-a883-985eb7fbd7a1-attachment.attach
│ │ ├── 31d021db-66cf-4b6c-ae71-15a2e9953294-attachment.attach
│ │ ├── b3aaf70f-749f-450d-841f-18feaa49b10d-attachment.attach
│ │ ├── 0e77bd92-752b-4668-8685-730d4b4ba05e-container.json
│ │ ├── 43aa29f7-e92a-473a-9685-6493d9d40c73-container.json
│ │ ├── 5e3fe95f-3c33-4fda-a519-023a25d338d0-container.json
│ │ ├── 73339d77-d5f7-4597-8f86-0c8d4816a64e-container.json
│ │ ├── ae13f7d4-0fd7-42fd-b524-ac0e2af5718a-attachment.attach
│ │ ├── d1e7014d-1938-42c6-a229-2aa35065f3f6-attachment.txt
│ │ ├── 21ed8173-cd5d-4d38-95f1-29ba7ef35c26-result.json
│ │ ├── 63c03902-4149-4b77-8334-25a617516bde-result.json
│ │ ├── dae24e92-696a-4d8a-a4a1-d453299da76d-result.json
│ │ ├── 11f08016-1abb-461e-9e6d-fe83310ea63b-attachment.attach
│ │ ├── dfe15ef8-3724-4710-b687-fd5f753f0ef0-result.json
│ │ ├── a8105e8d-2465-4d01-9dca-cec2937a0cfd-attachment.attach
│ │ └── c56c0537-21bd-4b7d-b0d8-6235c48804d2-attachment.attach
├── page
│ ├── register
│ │ ├── test_initCanSelInfo.yaml
│ │ ├── test_addOrUpCurBact.yaml
│ │ ├── test_getAdultCurbactList.yaml
│ │ ├── test_findParam.yaml
│ │ ├── initCanSelInfo_request.json
│ │ └── addOrUpCurBact_request.json
│ └── perRelated
│ │ ├── addAudltCard_request.json
│ │ ├── test_addAudltCard.yaml
│ │ └── addAudltCard_response.json
├── testcase
│ ├── register
│ │ ├── test_findParam.py
│ │ ├── test_addOrUpCurBact.py
│ │ ├── test_initCanSelInfo.py
│ │ └── test_getAdultCurbactList.py
│ └── perRelated
│ │ └── test_addAudltCard.py
└── data
│ ├── findParam.chlsj
│ ├── addOrUpCurBact.chlsj
│ ├── addAudltCard.chlsj
│ └── getAdultCurbactList.chlsj
├── doc
├── ApiTesting-框架流程图.vsdx
└── ApiTesting-项目架构.xmind
├── config
├── apiConfig.yml
├── dbConfig.yml
├── runConfig.yml
├── __init__.py
└── test_template.py
├── requirements.txt
├── README.md
└── startup.py
/comm/script/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/comm/unit/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/logs/2021-02-04_error.log:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | *.xml
3 | *.pyc
4 |
--------------------------------------------------------------------------------
/PyDemo/report/html/widgets/launch.json:
--------------------------------------------------------------------------------
1 | [ ]
--------------------------------------------------------------------------------
/PyDemo/report/html/widgets/environment.json:
--------------------------------------------------------------------------------
1 | [ ]
--------------------------------------------------------------------------------
/PyDemo/report/html/widgets/executors.json:
--------------------------------------------------------------------------------
1 | [ ]
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/a10e5441521817af.attach:
--------------------------------------------------------------------------------
1 | 200
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/a142325f6ec7dd97.attach:
--------------------------------------------------------------------------------
1 | 200
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/a404884c53f9a95e.attach:
--------------------------------------------------------------------------------
1 | 200
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/b5dbaecb2dacdb90.attach:
--------------------------------------------------------------------------------
1 | 200
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/d57f284c2a250050.attach:
--------------------------------------------------------------------------------
1 | 200
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/e5cdc98bcb63fce1.attach:
--------------------------------------------------------------------------------
1 | 200
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/e645f31e66475871.attach:
--------------------------------------------------------------------------------
1 | 200
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/f658b4378482d4a.attach:
--------------------------------------------------------------------------------
1 | 200
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/de7b006637c1f824.attach:
--------------------------------------------------------------------------------
1 | findParam
--------------------------------------------------------------------------------
/comm/__init__.py:
--------------------------------------------------------------------------------
1 | # import phoenixdb
2 | # import phoenixdb.cursor
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/64929705a353786a.attach:
--------------------------------------------------------------------------------
1 | addOrUpCurBact
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/d4cfa82e3954b068.attach:
--------------------------------------------------------------------------------
1 | initCanSelInfo
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/3f3d3b675f8b38f0.attach:
--------------------------------------------------------------------------------
1 | getAdultCurbactList
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/aa3749b1bd00dd8e.attach:
--------------------------------------------------------------------------------
1 | getAdultCurbactList
--------------------------------------------------------------------------------
/PyDemo/report/xml/13581612-dbff-44e2-b614-28aeaf763e53-attachment.attach:
--------------------------------------------------------------------------------
1 | 200
--------------------------------------------------------------------------------
/PyDemo/report/xml/15a5ed09-71be-4302-8da3-f1a3833890c3-attachment.attach:
--------------------------------------------------------------------------------
1 | 200
--------------------------------------------------------------------------------
/PyDemo/report/xml/2d3cbb34-52fb-4b35-80e8-179d043a1226-attachment.attach:
--------------------------------------------------------------------------------
1 | 200
--------------------------------------------------------------------------------
/PyDemo/report/xml/30403406-d497-4fa4-8a90-e52a5f1723aa-attachment.attach:
--------------------------------------------------------------------------------
1 | 200
--------------------------------------------------------------------------------
/PyDemo/report/xml/33849d22-c42b-4fd4-b486-acfe3922e91a-attachment.attach:
--------------------------------------------------------------------------------
1 | 200
--------------------------------------------------------------------------------
/PyDemo/report/xml/a925524d-3c79-42dc-a506-ac9353b81a89-attachment.attach:
--------------------------------------------------------------------------------
1 | 200
--------------------------------------------------------------------------------
/PyDemo/report/xml/c5f832b3-c5da-4106-8a5d-8bc617600550-attachment.attach:
--------------------------------------------------------------------------------
1 | 200
--------------------------------------------------------------------------------
/PyDemo/report/xml/eb8ba490-0f39-42ba-9a1c-44e5ee2a0636-attachment.attach:
--------------------------------------------------------------------------------
1 | 200
--------------------------------------------------------------------------------
/PyDemo/report/xml/9487b1b8-64e5-49d0-a0ea-f2254a0a983f-attachment.attach:
--------------------------------------------------------------------------------
1 | findParam
--------------------------------------------------------------------------------
/PyDemo/report/html/favicon.ico:
--------------------------------------------------------------------------------
1 | module.exports = __webpack_public_path__ + "favicon.ico";
--------------------------------------------------------------------------------
/PyDemo/report/xml/8a751566-67d8-4a28-943a-a0c8cecc3a9f-attachment.attach:
--------------------------------------------------------------------------------
1 | addOrUpCurBact
--------------------------------------------------------------------------------
/PyDemo/report/xml/b6a76b88-e182-454b-ba36-1e34a5c19222-attachment.attach:
--------------------------------------------------------------------------------
1 | initCanSelInfo
--------------------------------------------------------------------------------
/PyDemo/report/xml/da39ce35-693c-4f48-92cd-7795dd783e88-attachment.attach:
--------------------------------------------------------------------------------
1 | getAdultCurbactList
--------------------------------------------------------------------------------
/PyDemo/report/xml/f1dc7f0e-4445-425a-b4b7-f4b073d49233-attachment.attach:
--------------------------------------------------------------------------------
1 | getAdultCurbactList
--------------------------------------------------------------------------------
/logs/2021-02-04.log:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leozhanggg/ApiTesting/HEAD/logs/2021-02-04.log
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/6d6990d6bc7da779.attach:
--------------------------------------------------------------------------------
1 | http://10.88.88.141:20037/api/register/findParam
--------------------------------------------------------------------------------
/PyDemo/report/html/history/duration-trend.json:
--------------------------------------------------------------------------------
1 | [ {
2 | "data" : {
3 | "duration" : 5271
4 | }
5 | } ]
--------------------------------------------------------------------------------
/PyDemo/report/html/widgets/duration-trend.json:
--------------------------------------------------------------------------------
1 | [ {
2 | "data" : {
3 | "duration" : 5271
4 | }
5 | } ]
--------------------------------------------------------------------------------
/doc/ApiTesting-框架流程图.vsdx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leozhanggg/ApiTesting/HEAD/doc/ApiTesting-框架流程图.vsdx
--------------------------------------------------------------------------------
/doc/ApiTesting-项目架构.xmind:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Leozhanggg/ApiTesting/HEAD/doc/ApiTesting-项目架构.xmind
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/47e7333bf43a045.attach:
--------------------------------------------------------------------------------
1 | http://10.88.88.141:20037/api/register/addOrUpCurBact
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/ea0ced6a1ef79518.attach:
--------------------------------------------------------------------------------
1 | http://10.88.88.141:20037/api/register/initCanSelInfo
--------------------------------------------------------------------------------
/PyDemo/report/html/history/categories-trend.json:
--------------------------------------------------------------------------------
1 | [ {
2 | "data" : {
3 | "Test defects" : 1
4 | }
5 | } ]
--------------------------------------------------------------------------------
/PyDemo/report/html/widgets/categories-trend.json:
--------------------------------------------------------------------------------
1 | [ {
2 | "data" : {
3 | "Test defects" : 1
4 | }
5 | } ]
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/436a2d6b50675cb6.attach:
--------------------------------------------------------------------------------
1 | http://10.88.88.141:20037/api/register/getAdultCurbactList
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/4ac290f03a0b29ab.attach:
--------------------------------------------------------------------------------
1 | http://10.88.88.141:20037/api/register/getAdultCurbactList
--------------------------------------------------------------------------------
/PyDemo/report/html/history/retry-trend.json:
--------------------------------------------------------------------------------
1 | [ {
2 | "data" : {
3 | "run" : 4,
4 | "retry" : 0
5 | }
6 | } ]
--------------------------------------------------------------------------------
/PyDemo/report/html/widgets/retry-trend.json:
--------------------------------------------------------------------------------
1 | [ {
2 | "data" : {
3 | "run" : 4,
4 | "retry" : 0
5 | }
6 | } ]
--------------------------------------------------------------------------------
/PyDemo/report/xml/d354f47a-3693-4b7b-86df-cd34ace4ac9c-attachment.attach:
--------------------------------------------------------------------------------
1 | http://10.88.88.141:20037/api/register/findParam
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/10ea6ae95941448c.attach:
--------------------------------------------------------------------------------
1 | {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/45bb27deeb34ae52.attach:
--------------------------------------------------------------------------------
1 | {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/48d8349a567cd920.attach:
--------------------------------------------------------------------------------
1 | {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/7f88a98d6e750e3c.attach:
--------------------------------------------------------------------------------
1 | {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/d8d657fe62f789ca.attach:
--------------------------------------------------------------------------------
1 | {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
--------------------------------------------------------------------------------
/PyDemo/report/xml/194b21ff-bc74-4712-9e00-2d4d10c529f3-attachment.attach:
--------------------------------------------------------------------------------
1 | http://10.88.88.141:20037/api/register/initCanSelInfo
--------------------------------------------------------------------------------
/PyDemo/report/xml/a6f8bf5f-a42a-4c47-a026-243375a5685d-attachment.attach:
--------------------------------------------------------------------------------
1 | http://10.88.88.141:20037/api/register/addOrUpCurBact
--------------------------------------------------------------------------------
/PyDemo/report/xml/848e4b5e-7e91-4f72-874b-659053c3e48d-attachment.attach:
--------------------------------------------------------------------------------
1 | http://10.88.88.141:20037/api/register/getAdultCurbactList
--------------------------------------------------------------------------------
/PyDemo/report/xml/e9a38fd0-5f1b-4739-a472-7606737e0911-attachment.attach:
--------------------------------------------------------------------------------
1 | http://10.88.88.141:20037/api/register/getAdultCurbactList
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/9c97dfe6f36b3570.attach:
--------------------------------------------------------------------------------
1 | {'success': True, 'code': None, 'msg': '返回成功', 'data': None, 'callTime': None}
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/5627e81e1f308560.attach:
--------------------------------------------------------------------------------
1 | {'success': True, 'code': None, 'msg': '返回成功', 'data': ['1', '1'], 'callTime': None}
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/a2493f73f5b55797.attach:
--------------------------------------------------------------------------------
1 | {'success': True, 'code': None, 'msg': '返回成功', 'data': ['1', '1'], 'callTime': None}
--------------------------------------------------------------------------------
/PyDemo/report/html/data/categories.csv:
--------------------------------------------------------------------------------
1 | "Category","FAILED","BROKEN","PASSED","SKIPPED","UNKNOWN"
2 | "Test defects","0","1","0","0","0"
3 |
--------------------------------------------------------------------------------
/PyDemo/report/xml/067d3035-4727-4009-af05-75776743f64e-attachment.attach:
--------------------------------------------------------------------------------
1 | {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
--------------------------------------------------------------------------------
/PyDemo/report/xml/4f67b9c3-4ae0-4945-9697-c30b6dbbcbf0-attachment.attach:
--------------------------------------------------------------------------------
1 | {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
--------------------------------------------------------------------------------
/PyDemo/report/xml/7c22884c-0191-4937-b2d2-12214a869f4c-attachment.attach:
--------------------------------------------------------------------------------
1 | {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
--------------------------------------------------------------------------------
/PyDemo/report/xml/d3f438ee-fde7-483c-9a1b-87ce48d23359-attachment.attach:
--------------------------------------------------------------------------------
1 | {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
--------------------------------------------------------------------------------
/PyDemo/report/xml/f8618d25-7423-4d9f-a777-b1bc37ee3fd5-attachment.attach:
--------------------------------------------------------------------------------
1 | {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/7a7457e66b250a1f.attach:
--------------------------------------------------------------------------------
1 | {'success': None, 'code': 1, 'msg': '已有该批次的疫苗,请直接修改库存!', 'data': None, 'callTime': None}
--------------------------------------------------------------------------------
/PyDemo/report/xml/5f34e443-5ec3-41cf-9002-dd92ec056d54-attachment.attach:
--------------------------------------------------------------------------------
1 | {'success': True, 'code': None, 'msg': '返回成功', 'data': None, 'callTime': None}
--------------------------------------------------------------------------------
/PyDemo/report/xml/6bc3acef-572c-47fe-9093-56a69faa51ed-attachment.attach:
--------------------------------------------------------------------------------
1 | {'success': True, 'code': None, 'msg': '返回成功', 'data': ['1', '1'], 'callTime': None}
--------------------------------------------------------------------------------
/PyDemo/report/xml/bc8c8933-6042-4cfe-a825-a19018c34101-attachment.attach:
--------------------------------------------------------------------------------
1 | {'success': True, 'code': None, 'msg': '返回成功', 'data': ['1', '1'], 'callTime': None}
--------------------------------------------------------------------------------
/PyDemo/report/xml/aa05cb30-25c4-4485-b7f9-1aa4fd98e692-attachment.attach:
--------------------------------------------------------------------------------
1 | {'success': None, 'code': 1, 'msg': '已有该批次的疫苗,请直接修改库存!', 'data': None, 'callTime': None}
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/640913aa912828ba.attach:
--------------------------------------------------------------------------------
1 | {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': 'xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg='}
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/b2611d9bc9f7e7f2.attach:
--------------------------------------------------------------------------------
1 | {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': 'xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg='}
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/bdc87a179c292ab3.attach:
--------------------------------------------------------------------------------
1 | {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': 'xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg='}
--------------------------------------------------------------------------------
/PyDemo/report/html/history/history-trend.json:
--------------------------------------------------------------------------------
1 | [ {
2 | "data" : {
3 | "failed" : 0,
4 | "broken" : 1,
5 | "skipped" : 0,
6 | "passed" : 3,
7 | "unknown" : 0,
8 | "total" : 4
9 | }
10 | } ]
--------------------------------------------------------------------------------
/PyDemo/report/html/widgets/history-trend.json:
--------------------------------------------------------------------------------
1 | [ {
2 | "data" : {
3 | "failed" : 0,
4 | "broken" : 1,
5 | "skipped" : 0,
6 | "passed" : 3,
7 | "unknown" : 0,
8 | "total" : 4
9 | }
10 | } ]
--------------------------------------------------------------------------------
/PyDemo/report/xml/0d998249-b346-4cb4-a883-985eb7fbd7a1-attachment.attach:
--------------------------------------------------------------------------------
1 | {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': 'xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg='}
--------------------------------------------------------------------------------
/PyDemo/report/xml/31d021db-66cf-4b6c-ae71-15a2e9953294-attachment.attach:
--------------------------------------------------------------------------------
1 | {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': 'xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg='}
--------------------------------------------------------------------------------
/PyDemo/report/xml/b3aaf70f-749f-450d-841f-18feaa49b10d-attachment.attach:
--------------------------------------------------------------------------------
1 | {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': 'xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg='}
--------------------------------------------------------------------------------
/PyDemo/report/html/export/mail.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Allure Report summary mail
6 |
7 |
8 | Mail body
9 |
10 |
11 |
--------------------------------------------------------------------------------
/PyDemo/report/xml/0e77bd92-752b-4668-8685-730d4b4ba05e-container.json:
--------------------------------------------------------------------------------
1 | {"uuid": "654cc911-8aa6-4a5c-a5a8-5b67c3f41bed", "befores": [{"name": "case_data", "status": "passed", "start": 1612427966997, "stop": 1612427966997}], "start": 1612427966997, "stop": 1612427969137}
--------------------------------------------------------------------------------
/PyDemo/report/xml/43aa29f7-e92a-473a-9685-6493d9d40c73-container.json:
--------------------------------------------------------------------------------
1 | {"uuid": "c9b9f79d-7b60-4b2a-bcf9-990cdc707bf0", "befores": [{"name": "case_data", "status": "passed", "start": 1612427969140, "stop": 1612427969140}], "start": 1612427969140, "stop": 1612427970154}
--------------------------------------------------------------------------------
/PyDemo/report/xml/5e3fe95f-3c33-4fda-a519-023a25d338d0-container.json:
--------------------------------------------------------------------------------
1 | {"uuid": "37197fb2-8342-4ac8-b8d3-ecf0dcacaaaf", "befores": [{"name": "case_data", "status": "passed", "start": 1612427970157, "stop": 1612427970157}], "start": 1612427970157, "stop": 1612427971195}
--------------------------------------------------------------------------------
/PyDemo/report/xml/73339d77-d5f7-4597-8f86-0c8d4816a64e-container.json:
--------------------------------------------------------------------------------
1 | {"uuid": "5a2cc9d7-8d30-4ac6-89f6-fe997b262d17", "befores": [{"name": "case_data", "status": "passed", "start": 1612427971197, "stop": 1612427971197}], "start": 1612427971197, "stop": 1612427972269}
--------------------------------------------------------------------------------
/config/apiConfig.yml:
--------------------------------------------------------------------------------
1 | PyDemo:
2 | # 首次会根据接口数据包生成,可自行更改或添加新配置,所有配置将用于公共关联值。
3 | timeout: 10
4 | scheme: http
5 | host: 127.0.0.1:20037
6 | headers:
7 | Content-Type: application/x-www-form-urlencoded;charset=UTF-8
8 | headtoken: xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg=
9 |
--------------------------------------------------------------------------------
/PyDemo/report/html/data/behaviors.csv:
--------------------------------------------------------------------------------
1 | "Epic","Feature","Story","FAILED","BROKEN","PASSED","SKIPPED","UNKNOWN"
2 | "","register","test_addOrUpCurBact","0","1","0","0","0"
3 | "","register","test_getAdultCurbactList","0","0","1","0","0"
4 | "","register","test_findParam","0","0","1","0","0"
5 | "","register","test_initCanSelInfo","0","0","1","0","0"
6 |
--------------------------------------------------------------------------------
/PyDemo/report/html/widgets/behaviors.json:
--------------------------------------------------------------------------------
1 | {
2 | "total" : 1,
3 | "items" : [ {
4 | "uid" : "f9614baa9d268c2fa96855398ce8a7bf",
5 | "name" : "register",
6 | "statistic" : {
7 | "failed" : 0,
8 | "broken" : 1,
9 | "skipped" : 0,
10 | "passed" : 3,
11 | "unknown" : 0,
12 | "total" : 4
13 | }
14 | } ]
15 | }
--------------------------------------------------------------------------------
/comm/utils/__init__.py:
--------------------------------------------------------------------------------
1 | import os
2 | from comm.utils.readYaml import read_yaml_data
3 |
4 |
5 | def get_case(file_path):
6 | case_yaml = file_path.replace('\\', '/').replace('/testcase/', '/page/').replace('.py', '.yaml')
7 | case_path = os.path.dirname(case_yaml)
8 | case_data = read_yaml_data(case_yaml)
9 | return case_path, case_data
10 |
--------------------------------------------------------------------------------
/PyDemo/report/html/widgets/categories.json:
--------------------------------------------------------------------------------
1 | {
2 | "total" : 1,
3 | "items" : [ {
4 | "uid" : "bdbf199525818fae7a8651db9eafe741",
5 | "name" : "Test defects",
6 | "statistic" : {
7 | "failed" : 0,
8 | "broken" : 1,
9 | "skipped" : 0,
10 | "passed" : 0,
11 | "unknown" : 0,
12 | "total" : 1
13 | }
14 | } ]
15 | }
--------------------------------------------------------------------------------
/PyDemo/report/html/widgets/suites.json:
--------------------------------------------------------------------------------
1 | {
2 | "total" : 1,
3 | "items" : [ {
4 | "uid" : "2ee94b824b159deda8131714c488ddf3",
5 | "name" : "PyDemo.testcase.register",
6 | "statistic" : {
7 | "failed" : 0,
8 | "broken" : 1,
9 | "skipped" : 0,
10 | "passed" : 3,
11 | "unknown" : 0,
12 | "total" : 4
13 | }
14 | } ]
15 | }
--------------------------------------------------------------------------------
/PyDemo/report/html/export/prometheusData.txt:
--------------------------------------------------------------------------------
1 | launch_status_failed 0
2 | launch_status_broken 1
3 | launch_status_passed 3
4 | launch_status_skipped 0
5 | launch_status_unknown 0
6 | launch_time_duration 5271
7 | launch_time_min_duration 1013
8 | launch_time_max_duration 2078
9 | launch_time_sum_duration 5200
10 | launch_problems_test_defects 1
11 | launch_retries_retries 0
12 | launch_retries_run 4
13 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pytest==6.0.2
2 | pytest-html==3.0.0
3 | pytest-xdist==2.1.0
4 | pytest-rerunfailures==9.1.1
5 | allure-pytest==2.8.18
6 | requests==2.24.0
7 | requests-toolbelt==0.9.1
8 | simplejson==3.17.2
9 | ruamel.yaml==0.16.12
10 | PyYAML==5.3.1
11 | configparser==5.0.0
12 | python-dateutil==2.8.0
13 | #elasticsearch==7.13.4
14 | #phoenixdb==1.0.1
15 | #pymysql==1.0.2
16 | #pysolr==3.8.1
17 | #redis==3.5.3
18 |
--------------------------------------------------------------------------------
/config/dbConfig.yml:
--------------------------------------------------------------------------------
1 | PyDemo:
2 | # 数据库查询超时时长(不得小于1)
3 | timeout: 3
4 | # MySQL配置信息
5 | mysql_info:
6 | address: 127.0.0.1:3160
7 | db: test
8 | user: test
9 | auth: test
10 | # HBase配置信息(需要启动phoenix查询服务)
11 | hbase_info:
12 | address: 127.0.0.1:8765
13 | db: test
14 | # ES配置信息(需要开放http查询服务)
15 | es_info:
16 | address: 127.0.0.1:9200
17 | db: test
18 | # Solr配置信息
19 | solr_info:
20 | address: 127.0.0.1:8883
21 |
--------------------------------------------------------------------------------
/PyDemo/report/html/widgets/summary.json:
--------------------------------------------------------------------------------
1 | {
2 | "reportName" : "Allure Report",
3 | "testRuns" : [ ],
4 | "statistic" : {
5 | "failed" : 0,
6 | "broken" : 1,
7 | "skipped" : 0,
8 | "passed" : 3,
9 | "unknown" : 0,
10 | "total" : 4
11 | },
12 | "time" : {
13 | "start" : 1612427966998,
14 | "stop" : 1612427972269,
15 | "duration" : 5271,
16 | "minDuration" : 1013,
17 | "maxDuration" : 2078,
18 | "sumDuration" : 5200
19 | }
20 | }
--------------------------------------------------------------------------------
/comm/db/__init__.py:
--------------------------------------------------------------------------------
1 | from config import read_yaml_data, DB_CONFIG, PROJECT_NAME
2 | DC = read_yaml_data(DB_CONFIG)[PROJECT_NAME]
3 | if 'solr_info' in DC:
4 | from .querySolr import search_solr
5 | if 'hbase_info' in DC:
6 | from .queryHBase import PhoenixServer
7 | if 'es_info' in DC:
8 | from .queryES import elastic_search
9 | if 'mysql_info' in DC:
10 | from .queryMysql import MysqlServer
11 | if 'redis_info' in DC:
12 | from .queryRedis import exec_redis
13 |
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/d7e1801c64f284ab.attach:
--------------------------------------------------------------------------------
1 | {'params': {'pageType': '', 'unitCode': '3202112002', 'bactCode': '', 'materType': '', 'coreName': '', 'corpSimpName': '', 'materName': '', 'inocCorpCode': '', 'speCodeName': '', 'vaccSpeCode': '', 'pym': '', 'price': '', 'batnmb': '', 'qty': '', 'ifUse': 1, 'dataType': 2, 'createDate': '', 'createManCode': '', 'modifyDate': '', 'modifyManCode': '', 'bactValidate': None, 'bizType': None}, 'headtoken': 'xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg='}
--------------------------------------------------------------------------------
/PyDemo/report/xml/ae13f7d4-0fd7-42fd-b524-ac0e2af5718a-attachment.attach:
--------------------------------------------------------------------------------
1 | {'params': {'pageType': '', 'unitCode': '3202112002', 'bactCode': '', 'materType': '', 'coreName': '', 'corpSimpName': '', 'materName': '', 'inocCorpCode': '', 'speCodeName': '', 'vaccSpeCode': '', 'pym': '', 'price': '', 'batnmb': '', 'qty': '', 'ifUse': 1, 'dataType': 2, 'createDate': '', 'createManCode': '', 'modifyDate': '', 'modifyManCode': '', 'bactValidate': None, 'bizType': None}, 'headtoken': 'xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg='}
--------------------------------------------------------------------------------
/PyDemo/report/html/plugins/screen-diff/styles.css:
--------------------------------------------------------------------------------
1 | .screen-diff__switchers {
2 | margin-bottom: 1em;
3 | }
4 |
5 | .screen-diff__switchers label + label {
6 | margin-left: 1em;
7 | }
8 |
9 | .screen-diff__overlay {
10 | position: relative;
11 | cursor: col-resize;
12 | }
13 |
14 | .screen-diff__container {
15 | overflow-x: auto;
16 | }
17 |
18 | .screen-diff__image-over {
19 | top: 0;
20 | left: 0;
21 | bottom: 0;
22 | background: #fff;
23 | position: absolute;
24 | overflow: hidden;
25 | box-shadow: 2px 0 1px -1px #aaa;
26 | }
27 |
--------------------------------------------------------------------------------
/PyDemo/page/register/test_initCanSelInfo.yaml:
--------------------------------------------------------------------------------
1 | test_info:
2 | title: register
3 | host: ${host}
4 | scheme: ${scheme}
5 | method: POST
6 | address: /api/register/initCanSelInfo
7 | mime_type: application/x-www-form-urlencoded
8 | headers: ${headers}
9 | timeout: ${timeout}
10 | file: false
11 | cookies: false
12 | premise: false
13 | test_case:
14 | - summary: initCanSelInfo
15 | describe: test_initCanSelInfo
16 | parameter: initCanSelInfo_request.json
17 | check_body:
18 | check_type: check_json
19 | expected_code: 200
20 | expected_result: initCanSelInfo_response.json
21 |
--------------------------------------------------------------------------------
/PyDemo/report/html/export/influxDbData.txt:
--------------------------------------------------------------------------------
1 | launch_status failed=0 1612427973000000000
2 | launch_status broken=1 1612427973000000000
3 | launch_status passed=3 1612427973000000000
4 | launch_status skipped=0 1612427973000000000
5 | launch_status unknown=0 1612427973000000000
6 | launch_time duration=5271 1612427973000000000
7 | launch_time min_duration=1013 1612427973000000000
8 | launch_time max_duration=2078 1612427973000000000
9 | launch_time sum_duration=5200 1612427973000000000
10 | launch_problems test_defects=1 1612427973000000000
11 | launch_retries retries=0 1612427973000000000
12 | launch_retries run=4 1612427973000000000
13 |
--------------------------------------------------------------------------------
/comm/utils/readJson.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2020/12/03
3 | # @Author : Leo Zhang
4 | # @File : readJson.py
5 | # ***********************
6 | import json
7 |
8 |
9 | def read_json_data(json_file):
10 | """读取json文件数据
11 |
12 | :param json_file: json文件地址
13 | :return:
14 | """
15 | with open(json_file, "r", encoding="utf-8") as fr:
16 | return json.load(fr)
17 |
18 |
19 | def write_json_file(json_file, obj):
20 | """把对象obj写入json文件
21 |
22 | :param json_file: json文件地址
23 | :param obj: 数据对象
24 | :return:
25 | """
26 | with open(json_file, "w", encoding='utf-8') as fw:
27 | json.dump(obj, fw, ensure_ascii=False, indent=4)
28 |
--------------------------------------------------------------------------------
/PyDemo/page/register/test_addOrUpCurBact.yaml:
--------------------------------------------------------------------------------
1 | test_info:
2 | title: register
3 | host: ${host}
4 | scheme: ${scheme}
5 | method: POST
6 | address: /api/register/addOrUpCurBact
7 | mime_type: application/x-www-form-urlencoded
8 | headers: ${headers}
9 | timeout: ${timeout}
10 | file: false
11 | cookies: false
12 | premise: /register/test_getAdultCurbactList.yaml
13 | test_case:
14 | - summary: addOrUpCurBact
15 | describe: test_addOrUpCurBact
16 | parameter: addOrUpCurBact_request.json
17 | check_body:
18 | check_type: check_json
19 | expected_code: 200
20 | expected_result:
21 | success: true
22 | code:
23 | msg: 返回成功
24 | data:
25 | callTime:
26 |
--------------------------------------------------------------------------------
/comm/utils/readYaml.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2020/12/03
3 | # @Author : Leo Zhang
4 | # @File : readYaml.py
5 | # ***********************
6 |
7 |
8 | def read_yaml_data(yaml_file):
9 | """读取yaml文件数据
10 |
11 | :param yaml_file: yaml文件地址
12 | :return:
13 | """
14 | import yaml
15 | with open(yaml_file, 'r', encoding="utf-8") as fr:
16 | return yaml.load(fr, Loader=yaml.SafeLoader)
17 |
18 |
19 | def write_yaml_file(yaml_file, obj):
20 | """把对象obj写入yaml文件
21 |
22 | :param yaml_file: yaml文件地址
23 | :param obj: 数据对象
24 | :return:
25 | """
26 | from ruamel import yaml
27 | with open(yaml_file, 'w', encoding='utf-8') as fw:
28 | yaml.dump(obj, fw, Dumper=yaml.RoundTripDumper, allow_unicode=True)
29 |
--------------------------------------------------------------------------------
/PyDemo/page/register/test_getAdultCurbactList.yaml:
--------------------------------------------------------------------------------
1 | test_info:
2 | title: register
3 | host: ${host}
4 | scheme: ${scheme}
5 | method: POST
6 | address: /api/register/getAdultCurbactList
7 | mime_type: application/x-www-form-urlencoded
8 | headers: ${headers}
9 | timeout: ${timeout}
10 | file: false
11 | cookies: false
12 | premise: false
13 | test_case:
14 | - summary: getAdultCurbactList
15 | describe: test_getAdultCurbactList
16 | parameter:
17 | params:
18 | unitCode: '3202112002'
19 | first: 0
20 | pym: ''
21 | pageSize: 10
22 | page: 0
23 | headtoken: ${headtoken}
24 | check_body:
25 | check_type: check_json
26 | expected_code: 200
27 | expected_result: getAdultCurbactList_response.json
28 |
--------------------------------------------------------------------------------
/PyDemo/report/html/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Allure Report
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/config/runConfig.yml:
--------------------------------------------------------------------------------
1 | # 运行项目名
2 | project_name: PyDemo
3 |
4 | # 运行模式:
5 | auto_switch: 2
6 | # 0 -不开启自动生成测试用例功能,将直接运行测试
7 | # 1 -根据手工编写用例,自动生成测试脚本,然后运行测试
8 | # 2 -根据接口抓包数据,自动生成测试用例和测试脚本,然后运行测试
9 | # 3 -根据接口抓包数据,自动生成测试用例和测试脚本,但不运行测试
10 | # 注意:目前解析仅支持(.chlsj)格式,请使用Charles工具抓包导出JSON Session File
11 |
12 | # 扫描测试用例目录(且仅当auto_switch=1时有用)
13 | scan_dir:
14 |
15 | # 使用模糊匹配测试用例(空则匹配所有)
16 | pattern:
17 |
18 | # 执行并发线程数(0表示不开启)
19 | process: 0
20 |
21 | # 失败重试次数(0表示不重试)
22 | reruns: 0
23 |
24 | # 本轮测试最大允许失败数(超出则立即结束测试)
25 | maxfail: 20
26 |
27 | # 接口调用间隔时间(s)
28 | interval: 1
29 |
30 | # 测试结果校验方式说明(共5种方式):
31 | # no_check:不做任何校验
32 | # check_code:仅校验接口返回码code
33 | # check_json:校验接口返回码code,并进行json格式比较返回结果(默认方式)
34 | # entirely_check:校验接口返回码code,并进行完整比较返回结果
35 | # regular_check:校验接口返回码code,并进行正则匹配返回结果
--------------------------------------------------------------------------------
/PyDemo/page/register/test_findParam.yaml:
--------------------------------------------------------------------------------
1 | test_info:
2 | title: register
3 | host: ${host}
4 | scheme: ${scheme}
5 | method: POST
6 | address: /api/register/findParam
7 | mime_type: application/x-www-form-urlencoded
8 | headers: ${headers}
9 | timeout: ${timeout}
10 | file: false
11 | cookies: false
12 | premise: false
13 | test_case:
14 | - summary: findParam
15 | describe: test_findParam
16 | parameter:
17 | params:
18 | unitCode: '3202112002'
19 | first: 0
20 | pym: ''
21 | pageSize: 10
22 | page: 0
23 | headtoken: ${headtoken}
24 | check_body:
25 | check_type: check_json
26 | expected_code: 200
27 | expected_result:
28 | success: true
29 | code:
30 | msg: 返回成功
31 | data:
32 | - '1'
33 | - '1'
34 | callTime:
35 |
--------------------------------------------------------------------------------
/PyDemo/report/html/data/suites.csv:
--------------------------------------------------------------------------------
1 | "Status","Start Time","Stop Time","Duration in ms","Parent Suite","Suite","Sub Suite","Test Class","Test Method","Name","Description"
2 | "broken","Thu Feb 04 16:39:26 CST 2021","Thu Feb 04 16:39:29 CST 2021","2078","PyDemo.testcase.register","test_addOrUpCurBact","TestRegister","","","test_addOrUpCurBact[case_data0]",""
3 | "passed","Thu Feb 04 16:39:30 CST 2021","Thu Feb 04 16:39:31 CST 2021","1038","PyDemo.testcase.register","test_getAdultCurbactList","TestRegister","","","test_getAdultCurbactList[case_data0]",""
4 | "passed","Thu Feb 04 16:39:29 CST 2021","Thu Feb 04 16:39:30 CST 2021","1013","PyDemo.testcase.register","test_findParam","TestRegister","","","test_findParam[case_data0]",""
5 | "passed","Thu Feb 04 16:39:31 CST 2021","Thu Feb 04 16:39:32 CST 2021","1071","PyDemo.testcase.register","test_initCanSelInfo","TestRegister","","","test_initCanSelInfo[case_data0]",""
6 |
--------------------------------------------------------------------------------
/config/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2020/12/03
3 | # @Author : Leo Zhang
4 | # @File : __init__.py
5 | # ***********************
6 | from comm.utils.readYaml import read_yaml_data
7 | import os
8 |
9 | # 获取主目录路径
10 | ROOT_DIR = str(os.path.realpath(__file__)).split('config')[0].replace('\\', '/')
11 |
12 | # 获取配置文件路径
13 | API_CONFIG = ROOT_DIR+'config/apiConfig.yml'
14 | RUN_CONFIG = ROOT_DIR+'config/runConfig.yml'
15 | DB_CONFIG = ROOT_DIR+'config/dbConfig.yml'
16 |
17 | # 获取运行配置信息
18 | RC = read_yaml_data(RUN_CONFIG)
19 | INTERVAL = RC['interval']
20 | PROJECT_NAME = RC['project_name']
21 |
22 | # 接口数据目录(.chlsj文件)
23 | DATA_DIR = ROOT_DIR+PROJECT_NAME+'/data'
24 | # 测试数据目录(test.yaml)
25 | PAGE_DIR = ROOT_DIR+PROJECT_NAME+'/page'
26 | # 测试脚本目录(test.py)
27 | TEST_DIR = ROOT_DIR+PROJECT_NAME+'/testcase'
28 | # 测试报告目录(xml|html)
29 | REPORT_DIR = ROOT_DIR+PROJECT_NAME+'/report'
30 |
31 |
--------------------------------------------------------------------------------
/config/test_template.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2021/2/2
3 | # @Author : Leo Zhang
4 | # @File : test_template.py
5 | # ****************************
6 | import os
7 | import allure
8 | import pytest
9 | from comm.utils import get_case
10 | from comm.unit.initializePremise import init_premise
11 | from comm.unit.apiSend import send_request
12 | from comm.unit.checkResult import check_result
13 | case_path, case_data = get_case(os.path.realpath(__file__))
14 |
15 |
16 | @allure.feature(case_data["test_info"]["title"])
17 | class TestTemplate:
18 |
19 | @pytest.mark.parametrize("test_case", case_data["test_case"])
20 | @allure.story("test_template")
21 | def test_template(self, test_case):
22 | # 初始化请求:执行前置接口+替换关联变量
23 | test_info, test_case = init_premise(case_data["test_info"], test_case, case_path)
24 | # 发送当前接口
25 | code, data = send_request(test_info, test_case)
26 | # 校验接口返回
27 | check_result(test_case, code, data)
28 |
--------------------------------------------------------------------------------
/PyDemo/page/register/initCanSelInfo_request.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "summary": "initCanSelInfo",
4 | "body": {
5 | "params": {
6 | "pageType": "",
7 | "unitCode": "3202112002",
8 | "bactCode": "",
9 | "materType": "",
10 | "coreName": "",
11 | "corpSimpName": "",
12 | "materName": "",
13 | "inocCorpCode": "",
14 | "speCodeName": "",
15 | "vaccSpeCode": "",
16 | "pym": "",
17 | "price": "",
18 | "batnmb": "",
19 | "qty": "",
20 | "ifUse": 1,
21 | "dataType": 2,
22 | "createDate": "",
23 | "createManCode": "",
24 | "modifyDate": "",
25 | "modifyManCode": "",
26 | "bactValidate": null,
27 | "bizType": null
28 | },
29 | "headtoken": "${headtoken}"
30 | }
31 | }
32 | ]
--------------------------------------------------------------------------------
/PyDemo/report/html/widgets/duration.json:
--------------------------------------------------------------------------------
1 | [ {
2 | "uid" : "e5c5230705b9bfbb",
3 | "name" : "test_addOrUpCurBact[case_data0]",
4 | "time" : {
5 | "start" : 1612427966998,
6 | "stop" : 1612427969076,
7 | "duration" : 2078
8 | },
9 | "status" : "broken",
10 | "severity" : "normal"
11 | }, {
12 | "uid" : "7d4ed4f7a18b20d4",
13 | "name" : "test_getAdultCurbactList[case_data0]",
14 | "time" : {
15 | "start" : 1612427970157,
16 | "stop" : 1612427971195,
17 | "duration" : 1038
18 | },
19 | "status" : "passed",
20 | "severity" : "normal"
21 | }, {
22 | "uid" : "10d4bd6301177f6",
23 | "name" : "test_findParam[case_data0]",
24 | "time" : {
25 | "start" : 1612427969141,
26 | "stop" : 1612427970154,
27 | "duration" : 1013
28 | },
29 | "status" : "passed",
30 | "severity" : "normal"
31 | }, {
32 | "uid" : "aa8dfcaa510813c2",
33 | "name" : "test_initCanSelInfo[case_data0]",
34 | "time" : {
35 | "start" : 1612427971198,
36 | "stop" : 1612427972269,
37 | "duration" : 1071
38 | },
39 | "status" : "passed",
40 | "severity" : "normal"
41 | } ]
--------------------------------------------------------------------------------
/PyDemo/report/html/widgets/severity.json:
--------------------------------------------------------------------------------
1 | [ {
2 | "uid" : "e5c5230705b9bfbb",
3 | "name" : "test_addOrUpCurBact[case_data0]",
4 | "time" : {
5 | "start" : 1612427966998,
6 | "stop" : 1612427969076,
7 | "duration" : 2078
8 | },
9 | "status" : "broken",
10 | "severity" : "normal"
11 | }, {
12 | "uid" : "10d4bd6301177f6",
13 | "name" : "test_findParam[case_data0]",
14 | "time" : {
15 | "start" : 1612427969141,
16 | "stop" : 1612427970154,
17 | "duration" : 1013
18 | },
19 | "status" : "passed",
20 | "severity" : "normal"
21 | }, {
22 | "uid" : "aa8dfcaa510813c2",
23 | "name" : "test_initCanSelInfo[case_data0]",
24 | "time" : {
25 | "start" : 1612427971198,
26 | "stop" : 1612427972269,
27 | "duration" : 1071
28 | },
29 | "status" : "passed",
30 | "severity" : "normal"
31 | }, {
32 | "uid" : "7d4ed4f7a18b20d4",
33 | "name" : "test_getAdultCurbactList[case_data0]",
34 | "time" : {
35 | "start" : 1612427970157,
36 | "stop" : 1612427971195,
37 | "duration" : 1038
38 | },
39 | "status" : "passed",
40 | "severity" : "normal"
41 | } ]
--------------------------------------------------------------------------------
/PyDemo/report/html/widgets/status-chart.json:
--------------------------------------------------------------------------------
1 | [ {
2 | "uid" : "e5c5230705b9bfbb",
3 | "name" : "test_addOrUpCurBact[case_data0]",
4 | "time" : {
5 | "start" : 1612427966998,
6 | "stop" : 1612427969076,
7 | "duration" : 2078
8 | },
9 | "status" : "broken",
10 | "severity" : "normal"
11 | }, {
12 | "uid" : "7d4ed4f7a18b20d4",
13 | "name" : "test_getAdultCurbactList[case_data0]",
14 | "time" : {
15 | "start" : 1612427970157,
16 | "stop" : 1612427971195,
17 | "duration" : 1038
18 | },
19 | "status" : "passed",
20 | "severity" : "normal"
21 | }, {
22 | "uid" : "10d4bd6301177f6",
23 | "name" : "test_findParam[case_data0]",
24 | "time" : {
25 | "start" : 1612427969141,
26 | "stop" : 1612427970154,
27 | "duration" : 1013
28 | },
29 | "status" : "passed",
30 | "severity" : "normal"
31 | }, {
32 | "uid" : "aa8dfcaa510813c2",
33 | "name" : "test_initCanSelInfo[case_data0]",
34 | "time" : {
35 | "start" : 1612427971198,
36 | "stop" : 1612427972269,
37 | "duration" : 1071
38 | },
39 | "status" : "passed",
40 | "severity" : "normal"
41 | } ]
--------------------------------------------------------------------------------
/PyDemo/report/html/data/categories.json:
--------------------------------------------------------------------------------
1 | {
2 | "uid" : "4b4757e66a1912dae1a509f688f20b0f",
3 | "name" : "categories",
4 | "children" : [ {
5 | "name" : "Test defects",
6 | "children" : [ {
7 | "name" : "Exception: JSON格式校验,关键字 success 返回结果 True 与期望结果 None 类型不符",
8 | "children" : [ {
9 | "name" : "test_addOrUpCurBact[case_data0]",
10 | "uid" : "e5c5230705b9bfbb",
11 | "parentUid" : "c54c7aeb99bc40822dbbe6fd6c068928",
12 | "status" : "broken",
13 | "time" : {
14 | "start" : 1612427966998,
15 | "stop" : 1612427969076,
16 | "duration" : 2078
17 | },
18 | "flaky" : false,
19 | "newFailed" : false,
20 | "parameters" : [ "{'summary': 'addOrUpCurBact', 'describe': 'test_addOrUpCurBact', 'parameter': 'addOrUpCurBact_request.json', 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': {'success': True, 'code': None, 'msg': '返回成功', 'data': None, 'callTime': None}}}" ]
21 | } ],
22 | "uid" : "c54c7aeb99bc40822dbbe6fd6c068928"
23 | } ],
24 | "uid" : "bdbf199525818fae7a8651db9eafe741"
25 | } ]
26 | }
--------------------------------------------------------------------------------
/PyDemo/testcase/register/test_findParam.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2021/2/2
3 | # @Author : Leo Zhang
4 | # @File : test_findParam.py
5 | # ****************************
6 | import os
7 | import allure
8 | import pytest
9 | from comm.utils.readYaml import read_yaml_data
10 | from comm.unit.initializePremise import init_premise
11 | from comm.unit.apiSend import send_request
12 | from comm.unit.checkResult import check_result
13 | file_path = os.path.realpath(__file__).replace('\\', '/')
14 | case_yaml = file_path.replace('/testcase/', '/page/').replace('.py', '.yaml')
15 | test_case = read_yaml_data(case_yaml)
16 |
17 |
18 | @allure.feature(test_case["test_info"]["title"])
19 | class TestRegister:
20 |
21 | @pytest.mark.parametrize("test_case", test_case["test_case"])
22 | @allure.story("test_findParam")
23 | def test_findParam(self, test_case):
24 | # 初始化请求:执行前置接口+替换关联变量
25 | test_info, test_case = init_premise(test_case["test_info"], test_case, case_yaml)
26 | # 发送当前接口
27 | code, data = send_request(test_info, test_case)
28 | # 校验接口返回
29 | check_result(test_case, code, data)
30 |
--------------------------------------------------------------------------------
/PyDemo/testcase/perRelated/test_addAudltCard.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2021/2/2
3 | # @Author : Leo Zhang
4 | # @File : test_addAudltCard.py
5 | # ****************************
6 | import os
7 | import allure
8 | import pytest
9 | from comm.utils.readYaml import read_yaml_data
10 | from comm.unit.initializePremise import init_premise
11 | from comm.unit.apiSend import send_request
12 | from comm.unit.checkResult import check_result
13 | file_path = os.path.realpath(__file__).replace('\\', '/')
14 | case_yaml = file_path.replace('/testcase/', '/page/').replace('.py', '.yaml')
15 | test_case = read_yaml_data(case_yaml)
16 |
17 |
18 | @allure.feature(test_case["test_info"]["title"])
19 | class TestPerrelated:
20 |
21 | @pytest.mark.parametrize("test_case", test_case["test_case"])
22 | @allure.story("test_addAudltCard")
23 | def test_addAudltCard(self, test_case):
24 | # 初始化请求:执行前置接口+替换关联变量
25 | test_info, test_case = init_premise(test_case["test_info"], test_case, case_yaml)
26 | # 发送当前接口
27 | code, data = send_request(test_info, test_case)
28 | # 校验接口返回
29 | check_result(test_case, code, data)
30 |
--------------------------------------------------------------------------------
/PyDemo/testcase/register/test_addOrUpCurBact.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2021/2/2
3 | # @Author : Leo Zhang
4 | # @File : test_addOrUpCurBact.py
5 | # ****************************
6 | import os
7 | import allure
8 | import pytest
9 | from comm.utils.readYaml import read_yaml_data
10 | from comm.unit.initializePremise import init_premise
11 | from comm.unit.apiSend import send_request
12 | from comm.unit.checkResult import check_result
13 | file_path = os.path.realpath(__file__).replace('\\', '/')
14 | case_yaml = file_path.replace('/testcase/', '/page/').replace('.py', '.yaml')
15 | case_data = read_yaml_data(case_yaml)
16 |
17 |
18 | @allure.feature(case_data["test_info"]["title"])
19 | class TestRegister:
20 |
21 | @pytest.mark.parametrize("test_case", case_data["test_case"])
22 | @allure.story("test_addOrUpCurBact")
23 | def test_addOrUpCurBact(self, test_case):
24 | # 初始化请求:执行前置接口+替换关联变量
25 | test_info, test_case = init_premise(case_data["test_info"], test_case, case_yaml)
26 | # 发送当前接口
27 | code, data = send_request(test_info, test_case)
28 | # 校验接口返回
29 | check_result(test_case, code, data)
30 |
--------------------------------------------------------------------------------
/PyDemo/testcase/register/test_initCanSelInfo.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2021/2/2
3 | # @Author : Leo Zhang
4 | # @File : test_initCanSelInfo.py
5 | # ****************************
6 | import os
7 | import allure
8 | import pytest
9 | from comm.utils.readYaml import read_yaml_data
10 | from comm.unit.initializePremise import init_premise
11 | from comm.unit.apiSend import send_request
12 | from comm.unit.checkResult import check_result
13 | file_path = os.path.realpath(__file__).replace('\\', '/')
14 | case_yaml = file_path.replace('/testcase/', '/page/').replace('.py', '.yaml')
15 | test_case = read_yaml_data(case_yaml)
16 |
17 |
18 | @allure.feature(test_case["test_info"]["title"])
19 | class TestRegister:
20 |
21 | @pytest.mark.parametrize("test_case", test_case["test_case"])
22 | @allure.story("test_initCanSelInfo")
23 | def test_initCanSelInfo(self, test_case):
24 | # 初始化请求:执行前置接口+替换关联变量
25 | test_info, test_case = init_premise(test_case["test_info"], test_case, case_yaml)
26 | # 发送当前接口
27 | code, data = send_request(test_info, test_case)
28 | # 校验接口返回
29 | check_result(test_case, code, data)
30 |
--------------------------------------------------------------------------------
/PyDemo/testcase/register/test_getAdultCurbactList.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2021/2/2
3 | # @Author : Leo Zhang
4 | # @File : test_getAdultCurbactList.py
5 | # ****************************
6 | import os
7 | import allure
8 | import pytest
9 | from comm.utils.readYaml import read_yaml_data
10 | from comm.unit.initializePremise import init_premise
11 | from comm.unit.apiSend import send_request
12 | from comm.unit.checkResult import check_result
13 | file_path = os.path.realpath(__file__).replace('\\', '/')
14 | case_yaml = file_path.replace('/testcase/', '/page/').replace('.py', '.yaml')
15 | test_case = read_yaml_data(case_yaml)
16 |
17 |
18 | @allure.feature(test_case["test_info"]["title"])
19 | class TestRegister:
20 |
21 | @pytest.mark.parametrize("test_case", test_case["test_case"])
22 | @allure.story("test_getAdultCurbactList")
23 | def test_getAdultCurbactList(self, test_case):
24 | # 初始化请求:执行前置接口+替换关联变量
25 | test_info, test_case = init_premise(test_case["test_info"], test_case, case_yaml)
26 | # 发送当前接口
27 | code, data = send_request(test_info, test_case)
28 | # 校验接口返回
29 | check_result(test_case, code, data)
30 |
--------------------------------------------------------------------------------
/PyDemo/page/register/addOrUpCurBact_request.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "summary": "addOrUpCurBact",
4 | "body": {
5 | "params": {
6 | "pageType": "0",
7 | "unitCode": "${unitCode}",
8 | "bactCode": "280101",
9 | "materType": "86901119000052",
10 | "coreName": "大连雅立峰",
11 | "corpSimpName": "大连雅立峰",
12 | "materName": "狂犬病疫苗(vero细胞)",
13 | "inocCorpCode": "50",
14 | "speCodeName": "1.0ml",
15 | "vaccSpeCode": "1002",
16 | "pym": "kqbymveroxb",
17 | "price": "0",
18 | "batnmb": "20110101",
19 | "qty": "100",
20 | "ifUse": 1,
21 | "dataType": 2,
22 | "createDate": "",
23 | "createManCode": "${createManCode}",
24 | "modifyDate": "",
25 | "modifyManCode": "${createManCode}",
26 | "bactValidate": "$GenDate(y+1)",
27 | "bizType": 1,
28 | "materTypeCode": "1"
29 | },
30 | "headtoken": "${headtoken}"
31 | }
32 | }
33 | ]
--------------------------------------------------------------------------------
/PyDemo/page/perRelated/addAudltCard_request.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "summary": "addAudltCard",
4 | "body": {
5 | "params": {
6 | "adultAddressregion": "3202000000",
7 | "adultAddressdistrict": "AUTO99",
8 | "adultCountryCode": "156",
9 | "adultNationCode": "1001",
10 | "adultNoType": "2",
11 | "adultHabiCode": "32021100",
12 | "unitCode": "3202112002",
13 | "adultAccountCode": 1002,
14 | "adultResiCode": 1,
15 | "adultNo": "$RandInt(10000000,99999999)",
16 | "adultName": "AUTO99",
17 | "adultSex": "1",
18 | "adultBirthday": "2015-03-03",
19 | "adultMobile": "19999999999",
20 | "adultHabiaddress": "AUTO99",
21 | "adultArtimove": 0,
22 | "adultIfdead": 0,
23 | "adultHereCode": 1001,
24 | "adultCreatesite": "3202112002",
25 | "adultCreatemanName": "马山山",
26 | "adultCreateman": "3202112002008",
27 | "adultCreatesiteName": "马山社区"
28 | },
29 | "headtoken": "${headtoken}"
30 | }
31 | }
32 | ]
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ApiTesting
2 | 此框架是基于Python+Pytest+Requests+Allure+Yaml+Json实现全链路接口自动化测试。
3 |
4 | 主要流程:
5 |
6 | > 解析接口数据包 ->生成接口基础配置(yml) ->生成测试用例(yaml+json) ->生成测试脚本(.py) ->运行测试(pytest) ->生成测试报告(allure)
7 |
8 | 测试流程:
9 |
10 | > 初始化请求 ->处理接口基础信息 ->读取前置接口用例 ->发送前置接口 ->处理当前接口数据 ->发送当前接口 ->检查接口返回
11 |
12 | ApiTesting全链路接口自动化测试框架 - 初版(一)
13 | > 介绍:https://www.cnblogs.com/leozhanggg/p/14373878.html
14 |
15 | ApiTesting全链路接口自动化测试框架 - 新增数据库校验(二)
16 | > 介绍:https://www.cnblogs.com/leozhanggg/p/14522084.html
17 |
18 | ApiTesting全链路接口自动化测试框架 - 实战应用
19 | > 介绍:https://www.cnblogs.com/leozhanggg/p/14519800.html
20 |
21 | 运行配置说明:
22 |
23 | > 运行项目名
24 | project_name: PyDemo
25 |
26 | > 运行模式:
27 | auto_switch: 2
28 |
29 | > 0 - 不开启自动生成测试用例功能,将直接运行测试
30 |
31 | > 1 - 根据手工编写用例,自动生成测试脚本,然后运行测试
32 |
33 | > 2 - 根据接口抓包数据,自动生成测试用例和测试脚本,然后运行测试
34 |
35 | > 3 - 根据接口抓包数据,自动生成测试用例和测试脚本,但不运行测试
36 |
37 | > 注意:目前解析仅支持(.chlsj)格式,请使用Charles工具抓包导出JSON Session File
38 |
39 | > 扫描测试用例目录(且仅当auto_switch=1时有用)
40 | scan_dir:
41 |
42 | > 使用模糊匹配测试用例(空则匹配所有)
43 | pattern:
44 |
45 | > 执行并发线程数(0表示不开启)
46 | process: 0
47 |
48 | > 失败重试次数(0表示不重试)
49 | reruns: 0
50 |
51 | > 本轮测试最大允许失败数(超出则立即结束测试)
52 | maxfail: 20
53 |
54 | > 接口调用间隔时间(s)
55 | interval: 1
56 |
57 | > 测试结果校验方式说明(共5种方式):
58 |
59 | > 1 - no_check:不做任何校验
60 |
61 | > 2 - check_code:仅校验接口返回码code
62 |
63 | > 3 - check_json:校验接口返回码code,并进行json格式比较返回结果(默认方式)
64 |
65 | > 4 - entirely_check:校验接口返回码code,并进行完整比较返回结果
66 |
67 | > 5 - regular_check:校验接口返回码code,并进行正则匹配返回结果
68 |
69 |
--------------------------------------------------------------------------------
/PyDemo/page/perRelated/test_addAudltCard.yaml:
--------------------------------------------------------------------------------
1 | test_info:
2 | title: perRelated
3 | host: ${host}
4 | scheme: ${scheme}
5 | method: POST
6 | address: /api/perRelated/addAudltCard
7 | mime_type: application/x-www-form-urlencoded
8 | headers: ${headers}
9 | timeout: ${timeout}
10 | file: false
11 | cookies: false
12 | premise: false
13 | test_case:
14 | - summary: addAudltCard
15 | describe: test_addAudltCard
16 | parameter: addAudltCard_request.json
17 | check_body:
18 | check_type: check_json
19 | expected_code: 200
20 | expected_result: addAudltCard_response.json
21 | check_db:
22 | - check_type: mysql
23 | execute_sql: select * from TD_ADULT where ADULT_CODE='${adultCode}'
24 | expected_result:
25 | - ADULT_CODE: ${adultCode}
26 | ADULT_NAME: AUTO99
27 | ADULT_SEX: 1
28 | ADULT_BIRTHDAY: 2015-03-03
29 | ADULT_MOBILE: 19999999999
30 | - check_type: es
31 | execute_sql: select * from adult where CHIL_NAME='AUTO99'
32 | expected_result:
33 | - CHIL_NAME: AUTO99
34 | CHIL_SEX: 1
35 | CHIL_MOBILE: 19999999999
36 | - CHIL_NAME: AUTO99
37 | CHIL_SEX: 1
38 | CHIL_MOBILE: 19999999999
39 | - check_type: solr
40 | execute_sql: select * from adultsolr320000 where adultName='AUTO99'
41 | expected_result:
42 | - adultName: AUTO99
43 | adultSex: 1
44 | adultMobile: 19999999999
45 | - check_type: hbase
46 | execute_sql: select * from TD_ADULT_YZ where ADULT_CODE=3202112002803000001
47 | expected_result:
48 | - ADULT_CODE: 3202112002803000001
--------------------------------------------------------------------------------
/comm/script/writeLogs.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2020/9/22
3 | # @Author : Leo Zhang
4 | # @File : writeLogs.py
5 | # ************************
6 | import logging
7 | import time
8 | import sys
9 | import os
10 |
11 |
12 | class MyLogs:
13 |
14 | def __init__(self, log_path):
15 | # 定义日志默认路径和日志名称
16 | if not os.path.exists(log_path):
17 | os.makedirs(log_path)
18 | runtime = time.strftime('%Y-%m-%d', time.localtime(time.time()))
19 | logfile = os.path.join(log_path, runtime+'.log')
20 | logfile_err = os.path.join(log_path, runtime+'_error.log')
21 |
22 | # 第一步,初始化日志对象并设置日志等级
23 | logger = logging.getLogger()
24 | logger.setLevel(logging.DEBUG)
25 | logger.handlers = []
26 |
27 | # 第二步,创建一个handler,用于写入debug日志文件
28 | fh = logging.FileHandler(logfile, mode='a+')
29 | fh.setLevel(logging.DEBUG)
30 |
31 | # 第三步,创建一个handler,用于写入error日志文件
32 | fh_err = logging.FileHandler(logfile_err, mode='a+')
33 | fh_err.setLevel(logging.ERROR)
34 |
35 | # 第四步,再创建一个handler,用于输出info日志到控制台
36 | sh = logging.StreamHandler(sys.stdout)
37 | sh.setLevel(logging.INFO)
38 |
39 | # 第五步,定义handler的输出格式
40 | formatter = logging.Formatter("%(asctime)s - %(filename)s - %(levelname)s: %(message)s")
41 | fh.setFormatter(formatter)
42 | fh_err.setFormatter(formatter)
43 | sh.setFormatter(formatter)
44 |
45 | # 第六步,将logger添加到handler里面
46 | logger.addHandler(fh)
47 | logger.addHandler(fh_err)
48 | logger.addHandler(sh)
49 |
--------------------------------------------------------------------------------
/comm/db/queryRedis.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2021/03/09
3 | # @Author : Leo Zhang
4 | # @File : queryRedis.py
5 | # **************************
6 | import logging
7 | import redis
8 |
9 |
10 | def exec_redis(address, auth, db_num, db_type, key):
11 | """获取redis数据
12 |
13 | :param address: 内存库地址(格式:ip:port)
14 | :param auth: 内存库密码
15 | :param db_num: 查询内存库号
16 | :param db_type: 数据库类型
17 | :param key: 查询key值
18 | :return:
19 | """
20 | # 初始化redis连接
21 | host, port = address.split(':')
22 | logging.debug('Redis Info: host={}, port={}, auth={}, db={}, type={}'
23 | .format(host, port, auth, db_num, db_type))
24 | conn = redis.StrictRedis(host=host, port=int(port), db=db_num,
25 | password=auth, decode_responses=True)
26 | logging.info('执行查询>>> db={}, key={}'.format(db_num, key))
27 |
28 | # 获取string类型指定key的对应值
29 | if 'string' in db_type:
30 | result = conn.get(key)
31 | # 获取hash类型指定key的所有数据
32 | elif 'hash' in db_type:
33 | result = conn.hgetall(key)
34 | # 获取zset类型指定key的前50行数据
35 | elif 'zset' in db_type:
36 | result = conn.zrange(key, 0, 50, desc=False,
37 | withscores=True, score_cast_func=int)
38 | # 获取set类型指定key的所有数据
39 | elif 'set' in db_type:
40 | result = conn.smembers(key)
41 | # 获取list类型指定key的前10个数据
42 | elif 'list' in db_type:
43 | result = conn.lrange(key, 0, 10)
44 | else:
45 | raise Exception('未知的数据类型{},请检查dbinfo配置'.format(db_type))
46 |
47 | logging.info('查询结果>>> {}'.format(result))
48 | return result
49 |
--------------------------------------------------------------------------------
/startup.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2021/2/1
3 | # @Author : Leo Zhang
4 | # @File : startup.py
5 | # ***********************
6 | import os
7 | import sys
8 | import pytest
9 | import logging
10 |
11 |
12 | if __name__ == '__main__':
13 | from comm.script import writeLogs, writeCase
14 | from config import *
15 |
16 | # 开启日志记录(默认logs目录)
17 | writeLogs.MyLogs(ROOT_DIR+'logs')
18 |
19 | # 判断运行模式
20 | if RC['auto_switch'] == 3:
21 | logging.info("根据接口抓包数据,自动生成测试用例和测试脚本,但不运行测试!")
22 | writeCase.write_case(DATA_DIR, auto_yaml=True)
23 | sys.exit(0)
24 |
25 | elif RC['auto_switch'] == 2:
26 | logging.info("根据接口抓包数据,自动生成测试用例和测试脚本,然后运行测试!")
27 | writeCase.write_case(DATA_DIR, auto_yaml=True)
28 |
29 | elif RC['auto_switch'] == 1:
30 | # 如果扫描路径为空在则取项目page目录
31 | if not RC['scan_dir']:
32 | RC['scan_dir'] = PAGE_DIR
33 | logging.info("根据手工编写用例,自动生成测试脚本,然后运行测试!")
34 | writeCase.write_case(RC['scan_dir'], auto_yaml=False)
35 |
36 | else:
37 | logging.info("不开启自动生成测试用例功能,将直接运行测试!")
38 |
39 | # 定义运行参数
40 | args_list = ['-vs', TEST_DIR,
41 | '-n', str(RC['process']),
42 | '--reruns', str(RC['reruns']),
43 | '--maxfail', str(RC['maxfail']),
44 | '--alluredir', REPORT_DIR+'/xml',
45 | '--clean-alluredir',
46 | '--disable-warnings']
47 | # 判断是否开启用例匹配
48 | if RC['pattern']:
49 | args_list += ['-k ' + str(RC['pattern'])]
50 | test_result = pytest.main(args_list)
51 |
52 | # 生成allure报告
53 | cmd = 'allure generate --clean %s -o %s ' % (REPORT_DIR+'/xml', REPORT_DIR+'/html')
54 | os.system(cmd)
55 |
--------------------------------------------------------------------------------
/comm/db/queryHBase.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2021/03/09
3 | # @Author : Leo Zhang
4 | # @File : queryHBase.py
5 | # **************************
6 | import phoenixdb
7 | import phoenixdb.cursor
8 | from comm import *
9 | import logging
10 |
11 |
12 | class PhoenixServer(object):
13 | """
14 | 封装HBase常用方法。
15 | """
16 | def __init__(self, address):
17 | url = 'http://{}/'.format(address)
18 | logging.debug('Connect HBase: {}'.format(url))
19 | try:
20 | self.conn = phoenixdb.connect(url, autocommit=True)
21 | except Exception as e:
22 | raise Exception('连接异常>>> {}'.format(e))
23 |
24 | # 增加、修改、删除命令语句
25 | def execute(self, sql):
26 | try:
27 | # 创建游标
28 | cursor = self.conn.cursor(cursor_factory=phoenixdb.cursor.Cursor)
29 | # 执行sql语句
30 | cursor.execute(sql)
31 | # 关闭游标
32 | cursor.close()
33 | except Exception as e:
34 | raise Exception('执行异常>>> {}'.format(e))
35 |
36 | # 查询所有数据,多个值
37 | def query(self, sql, is_dict):
38 | try:
39 | # 判断是否需要返回结果为字典类型
40 | if is_dict:
41 | cursor = self.conn.cursor(cursor_factory=phoenixdb.cursor.DictCursor)
42 | else:
43 | cursor = self.conn.cursor(cursor_factory=phoenixdb.cursor.Cursor)
44 | # 执行sql语句
45 | cursor.execute(sql)
46 | # 查询结果
47 | data = cursor.fetchall()
48 | # 关闭游标
49 | cursor.close()
50 | return data
51 | except Exception as e:
52 | raise Exception('查询异常>>> {}'.format(e))
53 |
54 | # 关闭数据库连接
55 | def close(self):
56 | self.conn.close()
57 |
--------------------------------------------------------------------------------
/PyDemo/report/html/plugins/packages/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | allure.api.addTranslation('en', {
4 | tab: {
5 | packages: {
6 | name: 'Packages'
7 | }
8 | }
9 | });
10 |
11 | allure.api.addTranslation('ru', {
12 | tab: {
13 | packages: {
14 | name: 'Пакеты'
15 | }
16 | }
17 | });
18 |
19 | allure.api.addTranslation('zh', {
20 | tab: {
21 | packages: {
22 | name: '包'
23 | }
24 | }
25 | });
26 |
27 | allure.api.addTranslation('de', {
28 | tab: {
29 | packages: {
30 | name: 'Pakete'
31 | }
32 | }
33 | });
34 |
35 | allure.api.addTranslation('he', {
36 | tab: {
37 | packages: {
38 | name: 'חבילות'
39 | }
40 | }
41 | });
42 |
43 | allure.api.addTranslation('br', {
44 | tab: {
45 | packages: {
46 | name: 'Pacotes'
47 | }
48 | }
49 | });
50 |
51 | allure.api.addTranslation('ja', {
52 | tab: {
53 | packages: {
54 | name: 'パッケージ'
55 | }
56 | }
57 | });
58 |
59 | allure.api.addTranslation('es', {
60 | tab: {
61 | packages: {
62 | name: 'Paquetes'
63 | }
64 | }
65 | });
66 |
67 | allure.api.addTranslation('kr', {
68 | tab: {
69 | packages: {
70 | name: '패키지'
71 | }
72 | }
73 | });
74 |
75 | allure.api.addTab('packages', {
76 | title: 'tab.packages.name', icon: 'fa fa-align-left',
77 | route: 'packages(/)(:testGroup)(/)(:testResult)(/)(:testResultTab)(/)',
78 | onEnter: (function (testGroup, testResult, testResultTab) {
79 | return new allure.components.TreeLayout({
80 | testGroup: testGroup,
81 | testResult: testResult,
82 | testResultTab: testResultTab,
83 | tabName: 'tab.packages.name',
84 | baseUrl: 'packages',
85 | url: 'data/packages.json'
86 | });
87 | })
88 | });
89 |
--------------------------------------------------------------------------------
/comm/utils/readConf.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2020/12/03
3 | # @Author : Leo Zhang
4 | # @File : readConf.py
5 | # ***********************
6 | import codecs
7 | import configparser
8 |
9 |
10 | class ReadConf:
11 |
12 | def __init__(self, cfg_path):
13 | """
14 | 配置文件初始化
15 | :param cfg_path:
16 | """
17 | fd = open(cfg_path.replace('\\', '/'), encoding='utf-8')
18 | data = fd.read()
19 | # 去除配置文件开头编码标识
20 | if data[:3] == codecs.BOM_UTF8:
21 | data = data[3:]
22 | files = codecs.open(cfg_path, "w")
23 | files.write(data)
24 | files.close()
25 | fd.close()
26 | self.cf = configparser.ConfigParser()
27 | self.cf.read(cfg_path, encoding='utf-8-sig')
28 |
29 | def get_sections(self):
30 | """
31 | 获取所有条目
32 | :return:
33 | """
34 | return self.cf.sections()
35 |
36 | def get_items(self, section):
37 | """
38 | 获取指定条目下所有键值对
39 | :param section:
40 | :return:
41 | """
42 | return self.cf.items(section)
43 |
44 | def get_options(self, section):
45 | """
46 | 获取指定条目下所有键值
47 | :param section:
48 | :return:
49 | """
50 | return self.cf.options(section)
51 |
52 | def get_value(self, section, option):
53 | """
54 | 获取指定条目指定键的值
55 | :param section:
56 | :param option:
57 | :return:
58 | """
59 | return self.cf.get(section, option)
60 |
61 | def has_section(self, section):
62 | """
63 | 返回是否存在指定条目
64 | :param section:
65 | :return:
66 | """
67 | return self.cf.has_section(section)
68 |
69 | def has_option(self, section, option):
70 | """
71 | 返回指定条目是否存在指定键
72 | :param section:
73 | :param option:
74 | :return:
75 | """
76 | return self.cf.has_option(section, option)
77 |
--------------------------------------------------------------------------------
/PyDemo/report/html/history/history.json:
--------------------------------------------------------------------------------
1 | {
2 | "fb868315583aa11e2cd2b0339b92f05a" : {
3 | "statistic" : {
4 | "failed" : 0,
5 | "broken" : 1,
6 | "skipped" : 0,
7 | "passed" : 0,
8 | "unknown" : 0,
9 | "total" : 1
10 | },
11 | "items" : [ {
12 | "uid" : "e5c5230705b9bfbb",
13 | "status" : "broken",
14 | "statusDetails" : "Exception: JSON格式校验,关键字 success 返回结果 True 与期望结果 None 类型不符",
15 | "time" : {
16 | "start" : 1612427966998,
17 | "stop" : 1612427969076,
18 | "duration" : 2078
19 | }
20 | } ]
21 | },
22 | "27801e67fb61317f40b6cdc1f8d317aa" : {
23 | "statistic" : {
24 | "failed" : 0,
25 | "broken" : 0,
26 | "skipped" : 0,
27 | "passed" : 1,
28 | "unknown" : 0,
29 | "total" : 1
30 | },
31 | "items" : [ {
32 | "uid" : "7d4ed4f7a18b20d4",
33 | "status" : "passed",
34 | "time" : {
35 | "start" : 1612427970157,
36 | "stop" : 1612427971195,
37 | "duration" : 1038
38 | }
39 | } ]
40 | },
41 | "62cffe5b54c1489b5c40af1b7f11c19b" : {
42 | "statistic" : {
43 | "failed" : 0,
44 | "broken" : 0,
45 | "skipped" : 0,
46 | "passed" : 1,
47 | "unknown" : 0,
48 | "total" : 1
49 | },
50 | "items" : [ {
51 | "uid" : "10d4bd6301177f6",
52 | "status" : "passed",
53 | "time" : {
54 | "start" : 1612427969141,
55 | "stop" : 1612427970154,
56 | "duration" : 1013
57 | }
58 | } ]
59 | },
60 | "1155f03dcf38b2069e797022e1f66d78" : {
61 | "statistic" : {
62 | "failed" : 0,
63 | "broken" : 0,
64 | "skipped" : 0,
65 | "passed" : 1,
66 | "unknown" : 0,
67 | "total" : 1
68 | },
69 | "items" : [ {
70 | "uid" : "aa8dfcaa510813c2",
71 | "status" : "passed",
72 | "time" : {
73 | "start" : 1612427971198,
74 | "stop" : 1612427972269,
75 | "duration" : 1071
76 | }
77 | } ]
78 | }
79 | }
--------------------------------------------------------------------------------
/comm/db/querySolr.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2021/03/12
3 | # @Author : Leo Zhang
4 | # @File : querySolr.py
5 | # *************************
6 | import pysolr
7 | import logging
8 | import re
9 |
10 |
11 | def search_solr(address, sql):
12 | """获取Solr数据
13 |
14 | :param address: 地址(格式:ip:port)
15 | :param sql: sql查询语句
16 | :return:
17 | """
18 | # 检索SQL语句
19 | exp = r"^select (.*?) from (.*?) where (.*?)$"
20 | res = re.findall(exp, sql.strip())
21 | fields, db, conditions = res[0]
22 |
23 | # 重新拼接查询条件
24 | query = ''
25 | for each in conditions.split(' and '):
26 | key, value = each.replace('\'', '').replace('\"', '').split('=')
27 | if query:
28 | query += '&& '
29 | query += '{}:"{}" '.format(key, value)
30 |
31 | # 初始化Solr
32 | try:
33 | base_url = 'http://{0}/solr/{1}/'.format(address, db)
34 | solr = pysolr.Solr(base_url)
35 | except Exception as e:
36 | raise Exception('连接异常>>> \n{}'.format(e))
37 |
38 | # 执行查询
39 | query_str = 'GET {0}select?q={1}'.format(base_url, query)
40 | logging.info('执行查询>>> {}'.format(query_str))
41 | try:
42 | data = solr.search(query)
43 | result = list()
44 | for each in data:
45 | result.append(each)
46 | if result:
47 | # 判断是否返回全部字段
48 | if fields == '*':
49 | return result
50 | else:
51 | # 返回指定字段
52 | result_new = list()
53 | for res in result:
54 | line = dict()
55 | for each in fields.split(','):
56 | try:
57 | line[each] = res[each]
58 | except KeyError:
59 | raise KeyError('Solr未知字段>>> {}'.format(each))
60 | result_new.append(result)
61 | return result_new
62 | except Exception as e:
63 | raise Exception('查询异常>>> \n{}'.format(e))
64 |
--------------------------------------------------------------------------------
/comm/db/queryMysql.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2021/03/09
3 | # @Author : Leo Zhang
4 | # @File : queryMysql.py
5 | # **************************
6 | import pymysql
7 | import logging
8 |
9 |
10 | class MysqlServer:
11 | """
12 | 封装MySQL常用方法。
13 | """
14 | def __init__(self, host, port, db, user, passwd, charset='utf8'):
15 | # 初始化数据库
16 | logging.debug('Connect MySQL: host={host}, port={port}, db={db}, user={user}, passwd={passwd}'
17 | .format(host=host, port=port, db=db, user=user, passwd=passwd))
18 | try:
19 | self.conn = pymysql.connect(host=host, port=port, db=db, user=user, passwd=passwd, charset=charset)
20 | except Exception as e:
21 | raise Exception('连接异常>>> {}'.format(e))
22 |
23 | # 增加、修改、删除命令语句
24 | def execute(self, sql):
25 | try:
26 | # 创建游标
27 | cur = self.conn.cursor(cursor=pymysql.cursors.Cursor)
28 | # 执行sql语句
29 | cur.execute(sql)
30 | # 提交事务
31 | self.conn.commit()
32 | # 关闭游标
33 | cur.close()
34 | except Exception as e:
35 | # 出错时回滚
36 | self.conn.rollback()
37 | raise Exception('执行异常>>> {}'.format(e))
38 |
39 | # 查询所有数据,多个值
40 | def query(self, sql, is_dict):
41 | try:
42 | # 检查当前连接是否已关闭并进行重接
43 | self.conn.ping(reconnect=True)
44 | # 判断是否需要返回结果为字典类型
45 | if is_dict:
46 | cur = self.conn.cursor(cursor=pymysql.cursors.DictCursor)
47 | else:
48 | cur = self.conn.cursor(cursor=pymysql.cursors.Cursor)
49 | # 执行sql语句
50 | cur.execute(sql)
51 | # 查询结果
52 | data = cur.fetchall()
53 | # 关闭游标
54 | cur.close()
55 | return data
56 | except Exception as e:
57 | raise Exception('查询异常>>> {}'.format(e))
58 |
59 | # 关闭数据库连接
60 | def close(self):
61 | self.conn.close()
62 |
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/64a95aad22c4bff3.txt:
--------------------------------------------------------------------------------
1 | DEBUG root:initializePremise.py:53 测试信息处理结果:{'title': 'register', 'host': '10.88.88.141:20037', 'scheme': 'http', 'method': 'POST', 'address': '/api/register/findParam', 'mime_type': 'application/x-www-form-urlencoded', 'headers': {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}, 'timeout': 10, 'file': False, 'cookies': False, 'premise': False}
2 | DEBUG root:initializePremise.py:116 请求参数处理结果:{'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': 'xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg='}
3 | DEBUG root:readRelevance.py:45 获取关联键列表:
4 | []
5 | DEBUG root:initializePremise.py:123 期望返回处理结果:{'summary': 'findParam', 'describe': 'test_findParam', 'parameter': {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': 'xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg='}, 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': {'success': True, 'code': None, 'msg': '返回成功', 'data': ['1', '1'], 'callTime': None}}}
6 | INFO root:apiSend.py:37 ======================================================================================================================================================
7 | INFO root:apiSend.py:38 请求接口:findParam
8 | INFO root:apiSend.py:39 请求地址:http://10.88.88.141:20037/api/register/findParam
9 | INFO root:apiSend.py:40 请求头: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
10 | INFO root:apiSend.py:41 请求参数: {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': 'xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg='}
11 | INFO root:apiSend.py:58 请求方法: POST
12 | DEBUG urllib3.connectionpool:connectionpool.py:206 Starting new HTTP connection (1): 10.88.88.141:20037
13 | DEBUG urllib3.connectionpool:connectionpool.py:396 http://10.88.88.141:20037 "POST /api/register/findParam HTTP/1.1" 200 82
14 | INFO root:apiSend.py:137 请求接口结果:
15 | (200, {'success': True, 'code': None, 'msg': '返回成功', 'data': ['1', '1'], 'callTime': None})
--------------------------------------------------------------------------------
/PyDemo/report/xml/d1e7014d-1938-42c6-a229-2aa35065f3f6-attachment.txt:
--------------------------------------------------------------------------------
1 | DEBUG root:initializePremise.py:53 测试信息处理结果:{'title': 'register', 'host': '10.88.88.141:20037', 'scheme': 'http', 'method': 'POST', 'address': '/api/register/findParam', 'mime_type': 'application/x-www-form-urlencoded', 'headers': {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}, 'timeout': 10, 'file': False, 'cookies': False, 'premise': False}
2 | DEBUG root:initializePremise.py:116 请求参数处理结果:{'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': 'xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg='}
3 | DEBUG root:readRelevance.py:45 获取关联键列表:
4 | []
5 | DEBUG root:initializePremise.py:123 期望返回处理结果:{'summary': 'findParam', 'describe': 'test_findParam', 'parameter': {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': 'xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg='}, 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': {'success': True, 'code': None, 'msg': '返回成功', 'data': ['1', '1'], 'callTime': None}}}
6 | INFO root:apiSend.py:37 ======================================================================================================================================================
7 | INFO root:apiSend.py:38 请求接口:findParam
8 | INFO root:apiSend.py:39 请求地址:http://10.88.88.141:20037/api/register/findParam
9 | INFO root:apiSend.py:40 请求头: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
10 | INFO root:apiSend.py:41 请求参数: {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': 'xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg='}
11 | INFO root:apiSend.py:58 请求方法: POST
12 | DEBUG urllib3.connectionpool:connectionpool.py:206 Starting new HTTP connection (1): 10.88.88.141:20037
13 | DEBUG urllib3.connectionpool:connectionpool.py:396 http://10.88.88.141:20037 "POST /api/register/findParam HTTP/1.1" 200 82
14 | INFO root:apiSend.py:137 请求接口结果:
15 | (200, {'success': True, 'code': None, 'msg': '返回成功', 'data': ['1', '1'], 'callTime': None})
--------------------------------------------------------------------------------
/PyDemo/report/xml/21ed8173-cd5d-4d38-95f1-29ba7ef35c26-result.json:
--------------------------------------------------------------------------------
1 | {"name": "test_initCanSelInfo[case_data0]", "status": "passed", "steps": [{"name": "POST请求接口", "status": "passed", "attachments": [{"name": "请求接口", "source": "b6a76b88-e182-454b-ba36-1e34a5c19222-attachment.attach"}, {"name": "请求地址", "source": "194b21ff-bc74-4712-9e00-2d4d10c529f3-attachment.attach"}, {"name": "请求头", "source": "4f67b9c3-4ae0-4945-9697-c30b6dbbcbf0-attachment.attach"}, {"name": "请求参数", "source": "ae13f7d4-0fd7-42fd-b524-ac0e2af5718a-attachment.attach"}], "start": 1612427971221, "stop": 1612427971223}, {"name": "JSON格式校验结果", "status": "passed", "attachments": [{"name": "实际code", "source": "c5f832b3-c5da-4106-8a5d-8bc617600550-attachment.attach"}, {"name": "期望code", "source": "33849d22-c42b-4fd4-b486-acfe3922e91a-attachment.attach"}, {"name": "实际data", "source": "65b6cc0f-13d5-49c6-be30-e0758d61e2ee-attachment.attach"}, {"name": "期望data", "source": "8d2bd0b1-dc2f-4ea3-ac47-0db1b631d087-attachment.attach"}], "start": 1612427972266, "stop": 1612427972269}], "attachments": [{"name": "log", "source": "f48ca424-0649-43d3-b8ba-5d91599e129a-attachment.txt", "type": "text/plain"}], "parameters": [{"name": "case_data", "value": "{'summary': 'initCanSelInfo', 'describe': 'test_initCanSelInfo', 'parameter': 'initCanSelInfo_request.json', 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': 'initCanSelInfo_response.json'}}"}], "start": 1612427971198, "stop": 1612427972269, "uuid": "6532a322-3db7-49e2-82cc-e07ece13c849", "historyId": "1155f03dcf38b2069e797022e1f66d78", "testCaseId": "98b2b28a5672b7ba7f61a8bc99cb4083", "fullName": "PyDemo.testcase.register.test_initCanSelInfo.TestRegister#test_initCanSelInfo", "labels": [{"name": "story", "value": "test_initCanSelInfo"}, {"name": "feature", "value": "register"}, {"name": "parentSuite", "value": "PyDemo.testcase.register"}, {"name": "suite", "value": "test_initCanSelInfo"}, {"name": "subSuite", "value": "TestRegister"}, {"name": "host", "value": "Leo-PC"}, {"name": "thread", "value": "1096-MainThread"}, {"name": "framework", "value": "pytest"}, {"name": "language", "value": "cpython3"}, {"name": "package", "value": "PyDemo.testcase.register.test_initCanSelInfo"}]}
--------------------------------------------------------------------------------
/comm/db/queryES.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2021/03/09
3 | # @Author : Leo Zhang
4 | # @File : queryES.py
5 | # **************************
6 | import elasticsearch
7 | import logging
8 | import re
9 |
10 |
11 | def elastic_search(address, db, sql):
12 | """获取ElasticSearch数据
13 |
14 | :param address: ES地址(格式:ip:port)
15 | :param db: 索引库名
16 | :param sql: sql查询语句
17 | :return:
18 | """
19 | # 初始化ES
20 | try:
21 | es = elasticsearch.Elasticsearch([address])
22 | except Exception as e:
23 | raise Exception('连接异常>>> \n{}'.format(e))
24 |
25 | # 检索SQL语句
26 | exp = r"^select (.*?) from (.*?) where (.*?)$"
27 | res = re.findall(exp, sql.strip())
28 | fields, table, conditions = res[0]
29 | # 重新拼接查询条件
30 | query = ''
31 | for each in conditions.split(' and '):
32 | key, value = each.replace('\'', '').replace('\"', '').split('=')
33 | if query:
34 | query += '&& '
35 | query += '{}:"{}" '.format(key, value)
36 |
37 | # 执行查询
38 | db_table = db + '@' + table
39 | # query_str = 'GET http://{0}/{1}/_search?q={2}'.format(address, db_table, query)
40 | # logging.info('执行查询>>> {}'.format(query_str))
41 | try:
42 | # 查询ES,并截取hits字段
43 | data = es.search(index=db_table, q=query)
44 | hits = data['hits']['hits']
45 | if hits:
46 | # 截取字段值_source
47 | new_hits = list()
48 | for hit in hits:
49 | new_hits.append(hit['_source'])
50 | # 判断是否返回全部字段
51 | if fields == '*':
52 | return new_hits
53 | else:
54 | # 返回指定字段
55 | source_new = list()
56 | for hit in new_hits:
57 | result = dict()
58 | for each in fields.split(','):
59 | try:
60 | result[each] = hit[each]
61 | except KeyError:
62 | raise KeyError('ES未知字段>>> {}'.format(each))
63 | source_new.append(result)
64 | return source_new
65 | except Exception as e:
66 | raise Exception('查询异常>>> \n{}'.format(e))
67 |
--------------------------------------------------------------------------------
/PyDemo/report/xml/63c03902-4149-4b77-8334-25a617516bde-result.json:
--------------------------------------------------------------------------------
1 | {"name": "test_findParam[case_data0]", "status": "passed", "steps": [{"name": "POST请求接口", "status": "passed", "attachments": [{"name": "请求接口", "source": "9487b1b8-64e5-49d0-a0ea-f2254a0a983f-attachment.attach"}, {"name": "请求地址", "source": "d354f47a-3693-4b7b-86df-cd34ace4ac9c-attachment.attach"}, {"name": "请求头", "source": "7c22884c-0191-4937-b2d2-12214a869f4c-attachment.attach"}, {"name": "请求参数", "source": "0d998249-b346-4cb4-a883-985eb7fbd7a1-attachment.attach"}], "start": 1612427969143, "stop": 1612427969144}, {"name": "JSON格式校验结果", "status": "passed", "attachments": [{"name": "实际code", "source": "30403406-d497-4fa4-8a90-e52a5f1723aa-attachment.attach"}, {"name": "期望code", "source": "a925524d-3c79-42dc-a506-ac9353b81a89-attachment.attach"}, {"name": "实际data", "source": "6bc3acef-572c-47fe-9093-56a69faa51ed-attachment.attach"}, {"name": "期望data", "source": "bc8c8933-6042-4cfe-a825-a19018c34101-attachment.attach"}], "start": 1612427970152, "stop": 1612427970154}], "attachments": [{"name": "log", "source": "d1e7014d-1938-42c6-a229-2aa35065f3f6-attachment.txt", "type": "text/plain"}], "parameters": [{"name": "case_data", "value": "{'summary': 'findParam', 'describe': 'test_findParam', 'parameter': {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': '${headtoken}'}, 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': {'success': True, 'code': None, 'msg': '返回成功', 'data': ['1', '1'], 'callTime': None}}}"}], "start": 1612427969141, "stop": 1612427970154, "uuid": "3d9d32a9-9cdb-4de9-860f-97593382fd4d", "historyId": "62cffe5b54c1489b5c40af1b7f11c19b", "testCaseId": "039a4a0201219a85366197a1924a467a", "fullName": "PyDemo.testcase.register.test_findParam.TestRegister#test_findParam", "labels": [{"name": "story", "value": "test_findParam"}, {"name": "feature", "value": "register"}, {"name": "parentSuite", "value": "PyDemo.testcase.register"}, {"name": "suite", "value": "test_findParam"}, {"name": "subSuite", "value": "TestRegister"}, {"name": "host", "value": "Leo-PC"}, {"name": "thread", "value": "1096-MainThread"}, {"name": "framework", "value": "pytest"}, {"name": "language", "value": "cpython3"}, {"name": "package", "value": "PyDemo.testcase.register.test_findParam"}]}
--------------------------------------------------------------------------------
/PyDemo/report/xml/dae24e92-696a-4d8a-a4a1-d453299da76d-result.json:
--------------------------------------------------------------------------------
1 | {"name": "test_getAdultCurbactList[case_data0]", "status": "passed", "steps": [{"name": "POST请求接口", "status": "passed", "attachments": [{"name": "请求接口", "source": "f1dc7f0e-4445-425a-b4b7-f4b073d49233-attachment.attach"}, {"name": "请求地址", "source": "848e4b5e-7e91-4f72-874b-659053c3e48d-attachment.attach"}, {"name": "请求头", "source": "067d3035-4727-4009-af05-75776743f64e-attachment.attach"}, {"name": "请求参数", "source": "b3aaf70f-749f-450d-841f-18feaa49b10d-attachment.attach"}], "start": 1612427970161, "stop": 1612427970164}, {"name": "JSON格式校验结果", "status": "passed", "attachments": [{"name": "实际code", "source": "13581612-dbff-44e2-b614-28aeaf763e53-attachment.attach"}, {"name": "期望code", "source": "2d3cbb34-52fb-4b35-80e8-179d043a1226-attachment.attach"}, {"name": "实际data", "source": "a8105e8d-2465-4d01-9dca-cec2937a0cfd-attachment.attach"}, {"name": "期望data", "source": "11f08016-1abb-461e-9e6d-fe83310ea63b-attachment.attach"}], "start": 1612427971193, "stop": 1612427971195}], "attachments": [{"name": "log", "source": "53ee1c53-95a3-4472-bbc9-be8911c154a0-attachment.txt", "type": "text/plain"}], "parameters": [{"name": "case_data", "value": "{'summary': 'getAdultCurbactList', 'describe': 'test_getAdultCurbactList', 'parameter': {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': '${headtoken}'}, 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': 'getAdultCurbactList_response.json'}}"}], "start": 1612427970157, "stop": 1612427971195, "uuid": "27c2d884-886e-42a4-b1ca-34f6631a070c", "historyId": "27801e67fb61317f40b6cdc1f8d317aa", "testCaseId": "35e417966dd957c1f01ed34ddc30f12f", "fullName": "PyDemo.testcase.register.test_getAdultCurbactList.TestRegister#test_getAdultCurbactList", "labels": [{"name": "story", "value": "test_getAdultCurbactList"}, {"name": "feature", "value": "register"}, {"name": "parentSuite", "value": "PyDemo.testcase.register"}, {"name": "suite", "value": "test_getAdultCurbactList"}, {"name": "subSuite", "value": "TestRegister"}, {"name": "host", "value": "Leo-PC"}, {"name": "thread", "value": "1096-MainThread"}, {"name": "framework", "value": "pytest"}, {"name": "language", "value": "cpython3"}, {"name": "package", "value": "PyDemo.testcase.register.test_getAdultCurbactList"}]}
--------------------------------------------------------------------------------
/PyDemo/data/findParam.chlsj:
--------------------------------------------------------------------------------
1 | [{"status":"COMPLETE","method":"POST","protocolVersion":"HTTP/1.1","scheme":"http","host":"127.0.0.1","port":20037,"actualPort":20037,"path":"/api/register/findParam","query":null,"tunnel":false,"keptAlive":false,"webSocket":false,"remoteAddress":"127.0.0.1/127.0.0.1","clientAddress":"/127.0.0.1","clientPort":59266,"times":{"start":"2021-02-04T08:35:25.301+08:00","requestBegin":"2021-02-04T08:35:25.303+08:00","requestComplete":"2021-02-04T08:35:25.303+08:00","responseBegin":"2021-02-04T08:35:25.318+08:00","end":"2021-02-04T08:35:25.319+08:00"},"durations":{"total":17,"dns":0,"connect":1,"ssl":null,"request":0,"response":1,"latency":15},"speeds":{"overall":"64294","request":"0","response":"476000"},"totalSize":"1093","request":{"sizes":{"headers":480,"body":137},"mimeType":"application/x-www-form-urlencoded","charset":"UTF-8","contentEncoding":null,"header":{"firstLine":"POST /api/register/findParam HTTP/1.1","headers":[{"name":"Host","value":"127.0.0.1:20037"},{"name":"Content-Length","value":"137"},{"name":"Accept","value":"application/json, text/plain, */*"},{"name":"User-Agent","value":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"},{"name":"Content-Type","value":"application/x-www-form-urlencoded;charset=UTF-8"},{"name":"Origin","value":"http://127.0.0.1:6006"},{"name":"Referer","value":"http://127.0.0.1:6006/"},{"name":"Accept-Encoding","value":"gzip, deflate"},{"name":"Accept-Language","value":"zh-CN,zh;q=0.9"},{"name":"Connection","value":"keep-alive"}]},"body":{"text":"{\"params\":{\"unitCode\":\"3202112002\",\"first\":0,\"pym\":\"\",\"pageSize\":10,\"page\":0},\"headtoken\":\"/8QPAj9LlNJ1MaPd9ykD9cHql4tf3Xw/fu+VnRGKtCw=\"}","charset":"UTF-8"}},"response":{"status":200,"sizes":{"headers":394,"body":82},"mimeType":"application/json","charset":"UTF-8","contentEncoding":null,"header":{"firstLine":"HTTP/1.1 200 ","headers":[{"name":"Server","value":"nginx/1.14.2"},{"name":"Date","value":"Thu, 04 Feb 2021 00:29:29 GMT"},{"name":"Content-Type","value":"application/json;charset=UTF-8"},{"name":"Content-Length","value":"82"},{"name":"Access-Control-Allow-Headers","value":"Content-Type,x-requested-with,Authorization,Access-Control-Allow-Origin"},{"name":"Access-Control-Allow-Methods","value":"POST, GET, OPTIONS"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Access-Control-Max-Age","value":"360"},{"name":"Proxy-Connection","value":"keep-alive"}]},"body":{"text":"{\"success\":true,\"code\":null,\"msg\":\"返回成功\",\"data\":[\"1\",\"1\"],\"callTime\":null}","charset":"UTF-8"}}}]
--------------------------------------------------------------------------------
/comm/script/writeCase.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2020/10/15
3 | # @Author : Leo Zhang
4 | # @File : writeCase.py
5 | # ************************
6 | import os
7 | from config import ROOT_DIR
8 | from comm.script.writeCaseYml import write_case_yaml, read_yaml_data
9 | temp_file = ROOT_DIR+'config/test_template.py'
10 |
11 |
12 | def write_case(case_path, auto_yaml=True):
13 | """
14 |
15 | :param case_path: 用例路径,当auto_yaml为True时,需要传入data目录,否则传入扫描目录
16 | :param auto_yaml: 是否自动生成yaml文件
17 | :return:
18 | """
19 | # 判断是否自动生成yaml用例
20 | if auto_yaml:
21 | yaml_list = write_case_yaml(case_path)
22 | else:
23 | yaml_list = list()
24 | file_list = os.listdir(case_path)
25 | for file in file_list:
26 | if '.yaml' in file:
27 | yaml_path = case_path+'/'+file
28 | yaml_list.append(yaml_path)
29 |
30 | # 遍历测试用例列表
31 | for yaml_file in yaml_list:
32 | test_data = read_yaml_data(yaml_file)
33 | test_script = yaml_file.replace('\\', '/').replace('/page/', '/testcase/').replace('.yaml', '.py')
34 | # case_name = os.path.basename(test_script).replace('.py', '')
35 | case_path = os.path.dirname(test_script)
36 | # 判断文件路径是否存在
37 | if not os.path.exists(case_path):
38 | os.makedirs(case_path)
39 |
40 | # 判断测试用例脚本是否存在
41 | if os.path.exists(test_script):
42 | continue
43 |
44 | # 替换模板内容
45 | file_data = ''
46 | with open(temp_file, "r", encoding="utf-8") as f:
47 | for line in f:
48 | if 'TestTemplate' in line:
49 | title = test_data['test_info']['title']
50 | line = line.replace('Template', title.title())
51 | if 'test_template' in line:
52 | if '@allure.story' in line:
53 | describe = test_data['test_case'][0]['describe']
54 | line = line.replace('test_template', describe)
55 | else:
56 | summary = test_data['test_case'][0]['summary']
57 | line = line.replace('template', summary)
58 | file_data += line
59 |
60 | # 写入新脚本
61 | with open(test_script, "w", encoding="utf-8") as f:
62 | f.write(file_data)
63 |
64 |
65 | if __name__ == '__main__':
66 | real_path = os.path.dirname(os.path.realpath(__file__)).replace('\\', '/')
67 | write_case(real_path + '/data', auto_yaml=True)
68 | # write_case(real_path+'/page/oauth', auto_yaml=False)
69 |
--------------------------------------------------------------------------------
/PyDemo/data/addOrUpCurBact.chlsj:
--------------------------------------------------------------------------------
1 | [{"status":"COMPLETE","method":"POST","protocolVersion":"HTTP/1.1","scheme":"http","host":"127.0.0.1","port":20037,"actualPort":20037,"path":"/api/register/addOrUpCurBact","query":null,"tunnel":false,"keptAlive":true,"webSocket":false,"remoteAddress":"127.0.0.1/127.0.0.1","clientAddress":"/127.0.0.1","clientPort":59267,"times":{"start":"2021-02-04T08:35:57.615+08:00","requestBegin":"2021-02-04T08:35:57.616+08:00","requestComplete":"2021-02-04T08:35:57.617+08:00","responseBegin":"2021-02-04T08:35:57.636+08:00","end":"2021-02-04T08:35:57.637+08:00"},"durations":{"total":21,"dns":null,"connect":null,"ssl":null,"request":1,"response":1,"latency":19},"speeds":{"overall":"72809","request":"1058000","response":"471000"},"totalSize":"1529","request":{"sizes":{"headers":485,"body":573},"mimeType":"application/x-www-form-urlencoded","charset":"UTF-8","contentEncoding":null,"header":{"firstLine":"POST /api/register/addOrUpCurBact HTTP/1.1","headers":[{"name":"Host","value":"127.0.0.1:20037"},{"name":"Content-Length","value":"573"},{"name":"Accept","value":"application/json, text/plain, */*"},{"name":"User-Agent","value":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"},{"name":"Content-Type","value":"application/x-www-form-urlencoded;charset=UTF-8"},{"name":"Origin","value":"http://127.0.0.1:6006"},{"name":"Referer","value":"http://127.0.0.1:6006/"},{"name":"Accept-Encoding","value":"gzip, deflate"},{"name":"Accept-Language","value":"zh-CN,zh;q=0.9"},{"name":"Connection","value":"keep-alive"}]},"body":{"text":"{\"params\":{\"pageType\":\"0\",\"unitCode\":\"3202112002\",\"bactCode\":\"280101\",\"materType\":\"86901119000052\",\"coreName\":\"大连雅立峰\",\"corpSimpName\":\"大连雅立峰\",\"materName\":\"狂犬病疫苗(vero细胞)\",\"inocCorpCode\":\"50\",\"speCodeName\":\"1.0ml\",\"vaccSpeCode\":\"1002\",\"pym\":\"kqbymveroxb\",\"price\":\"0\",\"batnmb\":\"20110101\",\"qty\":\"100\",\"ifUse\":1,\"dataType\":2,\"createDate\":\"\",\"createManCode\":\"3202112002008\",\"modifyDate\":\"\",\"modifyManCode\":\"3202112002008\",\"bactValidate\":\"2022-02-02\",\"bizType\":1,\"materTypeCode\":\"1\"},\"headtoken\":\"/8QPAj9LlNJ1MaPd9ykD9cHql4tf3Xw/fu+VnRGKtCw=\"}","charset":"UTF-8"}},"response":{"status":200,"sizes":{"headers":394,"body":77},"mimeType":"application/json","charset":"UTF-8","contentEncoding":null,"header":{"firstLine":"HTTP/1.1 200 ","headers":[{"name":"Server","value":"nginx/1.14.2"},{"name":"Date","value":"Thu, 04 Feb 2021 00:30:02 GMT"},{"name":"Content-Type","value":"application/json;charset=UTF-8"},{"name":"Content-Length","value":"77"},{"name":"Access-Control-Allow-Headers","value":"Content-Type,x-requested-with,Authorization,Access-Control-Allow-Origin"},{"name":"Access-Control-Allow-Methods","value":"POST, GET, OPTIONS"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Access-Control-Max-Age","value":"360"},{"name":"Proxy-Connection","value":"keep-alive"}]},"body":{"text":"{\"success\":true,\"code\":null,\"msg\":\"返回成功\",\"data\":null,\"callTime\":null}","charset":"UTF-8"}}}]
--------------------------------------------------------------------------------
/PyDemo/report/html/data/timeline.json:
--------------------------------------------------------------------------------
1 | {
2 | "uid" : "ab17fc5a4eb3bca4b216b548c7f9fcbc",
3 | "name" : "timeline",
4 | "children" : [ {
5 | "name" : "Leo-PC",
6 | "children" : [ {
7 | "name" : "1096-MainThread",
8 | "children" : [ {
9 | "name" : "test_findParam[case_data0]",
10 | "uid" : "10d4bd6301177f6",
11 | "parentUid" : "0d5737b7c8f0eaf73ed6906fe9699a8a",
12 | "status" : "passed",
13 | "time" : {
14 | "start" : 1612427969141,
15 | "stop" : 1612427970154,
16 | "duration" : 1013
17 | },
18 | "flaky" : false,
19 | "newFailed" : false,
20 | "parameters" : [ "{'summary': 'findParam', 'describe': 'test_findParam', 'parameter': {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': '${headtoken}'}, 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': {'success': True, 'code': None, 'msg': '返回成功', 'data': ['1', '1'], 'callTime': None}}}" ]
21 | }, {
22 | "name" : "test_getAdultCurbactList[case_data0]",
23 | "uid" : "7d4ed4f7a18b20d4",
24 | "parentUid" : "0d5737b7c8f0eaf73ed6906fe9699a8a",
25 | "status" : "passed",
26 | "time" : {
27 | "start" : 1612427970157,
28 | "stop" : 1612427971195,
29 | "duration" : 1038
30 | },
31 | "flaky" : false,
32 | "newFailed" : false,
33 | "parameters" : [ "{'summary': 'getAdultCurbactList', 'describe': 'test_getAdultCurbactList', 'parameter': {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': '${headtoken}'}, 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': 'getAdultCurbactList_response.json'}}" ]
34 | }, {
35 | "name" : "test_addOrUpCurBact[case_data0]",
36 | "uid" : "e5c5230705b9bfbb",
37 | "parentUid" : "0d5737b7c8f0eaf73ed6906fe9699a8a",
38 | "status" : "broken",
39 | "time" : {
40 | "start" : 1612427966998,
41 | "stop" : 1612427969076,
42 | "duration" : 2078
43 | },
44 | "flaky" : false,
45 | "newFailed" : false,
46 | "parameters" : [ "{'summary': 'addOrUpCurBact', 'describe': 'test_addOrUpCurBact', 'parameter': 'addOrUpCurBact_request.json', 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': {'success': True, 'code': None, 'msg': '返回成功', 'data': None, 'callTime': None}}}" ]
47 | }, {
48 | "name" : "test_initCanSelInfo[case_data0]",
49 | "uid" : "aa8dfcaa510813c2",
50 | "parentUid" : "0d5737b7c8f0eaf73ed6906fe9699a8a",
51 | "status" : "passed",
52 | "time" : {
53 | "start" : 1612427971198,
54 | "stop" : 1612427972269,
55 | "duration" : 1071
56 | },
57 | "flaky" : false,
58 | "newFailed" : false,
59 | "parameters" : [ "{'summary': 'initCanSelInfo', 'describe': 'test_initCanSelInfo', 'parameter': 'initCanSelInfo_request.json', 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': 'initCanSelInfo_response.json'}}" ]
60 | } ],
61 | "uid" : "0d5737b7c8f0eaf73ed6906fe9699a8a"
62 | } ],
63 | "uid" : "29b2e37a8b2066a33626759906f3f57f"
64 | } ]
65 | }
--------------------------------------------------------------------------------
/comm/unit/readRelevance.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2021/1/8
3 | # @Author : Leo Zhang
4 | # @File : readRelevance.py
5 | # ****************************
6 | import logging
7 | import re
8 |
9 | # __relevance = ""
10 | __relevance = []
11 |
12 |
13 | def get_value(data, value):
14 | """获取数据中的值
15 |
16 | :param data:
17 | :param value:
18 | :return:
19 | """
20 | global __relevance
21 | if isinstance(data, dict):
22 | # if value in data:
23 | # __relevance = data[value]
24 | # else:
25 | # for key in data:
26 | # __relevance = get_value(data[key], value)
27 | for key in data:
28 | if isinstance(data[key], dict):
29 | get_value(data[key], value)
30 | elif isinstance(data[key], list):
31 | for each in data[key]:
32 | if isinstance(each, dict):
33 | get_value(each, value)
34 | # for each in data[key]:
35 | # if isinstance(each, dict):
36 | # break
37 | else:
38 | if key == value:
39 | __relevance.append(data[key])
40 | else:
41 | if key == value:
42 | __relevance.append(data[key])
43 | elif isinstance(data, list):
44 | for key in data:
45 | if isinstance(key, dict):
46 | # __relevance = get_value(key, value)
47 | # break
48 | get_value(key, value)
49 | return __relevance
50 |
51 |
52 | def get_relevance(data, relevance_list, relevance=None):
53 | """获取关联键值对
54 |
55 | :param data:
56 | :param relevance_list:
57 | :param relevance:
58 | :return:
59 | """
60 | global __relevance
61 | # 获取关联键列表
62 | relevance_list = re.findall(r"\${(.*?)}", str(relevance_list))
63 |
64 | # 去除参数[n]标识
65 | for index, value in enumerate(relevance_list):
66 | mark = re.findall(r"\[\-?[0-9]*\]", value)
67 | # if mark:
68 | # relevance_list[index] = value.strip(mark[0])
69 | for m in mark:
70 | value = value.replace(m, '')
71 | relevance_list[index] = value
72 |
73 | # 去除重复参数
74 | relevance_list = list(set(relevance_list))
75 | logging.debug("获取关联键列表:\n%s" % relevance_list)
76 |
77 | # 判断关联键和源数据是否有值
78 | if (not data) or (not relevance_list):
79 | return relevance
80 |
81 | # 判断是否存在其他关联键对象
82 | if not relevance:
83 | relevance = dict()
84 |
85 | # 遍历关联键
86 | for each in relevance_list:
87 | # 只考虑一个关联键一个值
88 | # if each in relevance:
89 | # pass
90 | # else:
91 | # # 从结果中提取关联键的值
92 | # relevance[each] = get_value(data, each)
93 |
94 | # 考虑到一个关联键多个值
95 | relevance_value = get_value(data, each)
96 | if relevance_value:
97 | if each in relevance:
98 | tmp = relevance[each]
99 | if isinstance(tmp, list):
100 | tmp += relevance_value
101 | relevance[each] = tmp
102 | else:
103 | tmp2 = relevance_value.insert(0, tmp)
104 | relevance[each] = tmp2
105 | else:
106 | relevance[each] = relevance_value
107 | __relevance = []
108 | logging.debug("提取关联键对象:\n%s" % relevance)
109 | return relevance
110 |
--------------------------------------------------------------------------------
/comm/unit/queryDatabase.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2021/03/09
3 | # @Author : Leo Zhang
4 | # @File : queryDatabase.py
5 | # **************************
6 | from comm.utils.readYaml import read_yaml_data
7 | from config import DB_CONFIG, PROJECT_NAME
8 | from comm.db import *
9 | import logging
10 | import time
11 | import re
12 |
13 | dbcfg = read_yaml_data(DB_CONFIG)[PROJECT_NAME]
14 |
15 |
16 | def query_mysql(sql):
17 | """查询MySQL数据
18 |
19 | :param sql: sql查询语句
20 | :return:
21 | """
22 | # 获取配置信息
23 | timeout = dbcfg['timeout']
24 | address = dbcfg['mysql_info']['address']
25 | user = dbcfg['mysql_info']['user']
26 | auth = dbcfg['mysql_info']['auth']
27 | db = dbcfg['mysql_info']['db']
28 | # 初始化MySQL
29 | host, port = address.split(':')
30 | mysql = MysqlServer(host, int(port), db, user, auth)
31 | logging.info('执行查询>>> {}'.format(sql))
32 | # 循环查询
33 | for i in range(int(timeout)):
34 | try:
35 | result = mysql.query(sql, is_dict=True)
36 | mysql.close()
37 | if result:
38 | return result
39 | else:
40 | time.sleep(1)
41 | except Exception as e:
42 | raise Exception('查询异常>>> {}'.format(e))
43 | else:
44 | return []
45 |
46 |
47 | def query_hbase(sql):
48 | """查询HBase数据
49 |
50 | :param sql: sql查询语句
51 | :return:
52 | """
53 | # 获取配置信息
54 | timeout = dbcfg['timeout']
55 | address = dbcfg['hbase_info']['address']
56 | db = dbcfg['hbase_info']['db']
57 | # 检索SQL语句
58 | exp = r"^select .*? from (.*?) where .*?$"
59 | table = re.findall(exp, sql.strip())[0]
60 | # 添加数据库
61 | if '.' not in table:
62 | sql = sql.strip().replace(table, db+'.'+table)
63 | # 初始化HBase
64 | hbase = PhoenixServer(address)
65 | logging.info('执行查询>>> {}'.format(sql))
66 | # 循环查询
67 | for i in range(int(timeout)):
68 | try:
69 | result = hbase.query(sql, is_dict=True)
70 | if result:
71 | return result
72 | else:
73 | time.sleep(1)
74 | except Exception as e:
75 | raise Exception('查询异常>>> {}'.format(e))
76 | else:
77 | return []
78 |
79 |
80 | def query_es(sql):
81 | """查询ES数据
82 |
83 | :param sql: sql查询语句
84 | :return:
85 | """
86 | # 获取配置信息
87 | timeout = dbcfg['timeout']
88 | address = dbcfg['es_info']['address']
89 | db = dbcfg['es_info']['db']
90 | logging.info('执行查询>>> {}'.format(sql))
91 | # 循环查询
92 | for i in range(int(timeout)):
93 | try:
94 | result = elastic_search(address, db, sql)
95 | if result:
96 | return result
97 | else:
98 | time.sleep(1)
99 | except Exception as e:
100 | raise Exception('查询异常>>> {}'.format(e))
101 | else:
102 | return []
103 |
104 |
105 | def query_solr(sql):
106 | """查询solr数据
107 |
108 | :param sql: sql查询语句
109 | :return:
110 | """
111 | # 获取配置信息
112 | timeout = dbcfg['timeout']
113 | address = dbcfg['solr_info']['address']
114 | logging.info('执行查询>>> {}'.format(sql))
115 | # 循环查询
116 | for i in range(int(timeout)):
117 | try:
118 | result = search_solr(address, sql)
119 | if result:
120 | return result
121 | else:
122 | time.sleep(1)
123 | except Exception as e:
124 | raise Exception('查询异常>>> {}'.format(e))
125 | else:
126 | return []
127 |
--------------------------------------------------------------------------------
/PyDemo/report/html/data/behaviors.json:
--------------------------------------------------------------------------------
1 | {
2 | "uid" : "b1a8273437954620fa374b796ffaacdd",
3 | "name" : "behaviors",
4 | "children" : [ {
5 | "name" : "register",
6 | "children" : [ {
7 | "name" : "test_addOrUpCurBact",
8 | "children" : [ {
9 | "name" : "test_addOrUpCurBact[case_data0]",
10 | "uid" : "e5c5230705b9bfbb",
11 | "parentUid" : "d566fe8071743e379fe2d541eff0a459",
12 | "status" : "broken",
13 | "time" : {
14 | "start" : 1612427966998,
15 | "stop" : 1612427969076,
16 | "duration" : 2078
17 | },
18 | "flaky" : false,
19 | "newFailed" : false,
20 | "parameters" : [ "{'summary': 'addOrUpCurBact', 'describe': 'test_addOrUpCurBact', 'parameter': 'addOrUpCurBact_request.json', 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': {'success': True, 'code': None, 'msg': '返回成功', 'data': None, 'callTime': None}}}" ]
21 | } ],
22 | "uid" : "d566fe8071743e379fe2d541eff0a459"
23 | }, {
24 | "name" : "test_findParam",
25 | "children" : [ {
26 | "name" : "test_findParam[case_data0]",
27 | "uid" : "10d4bd6301177f6",
28 | "parentUid" : "6499da8712dcd7b54b556fa696d8c606",
29 | "status" : "passed",
30 | "time" : {
31 | "start" : 1612427969141,
32 | "stop" : 1612427970154,
33 | "duration" : 1013
34 | },
35 | "flaky" : false,
36 | "newFailed" : false,
37 | "parameters" : [ "{'summary': 'findParam', 'describe': 'test_findParam', 'parameter': {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': '${headtoken}'}, 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': {'success': True, 'code': None, 'msg': '返回成功', 'data': ['1', '1'], 'callTime': None}}}" ]
38 | } ],
39 | "uid" : "6499da8712dcd7b54b556fa696d8c606"
40 | }, {
41 | "name" : "test_getAdultCurbactList",
42 | "children" : [ {
43 | "name" : "test_getAdultCurbactList[case_data0]",
44 | "uid" : "7d4ed4f7a18b20d4",
45 | "parentUid" : "ec5dd644558c5ede81175da3d69997c9",
46 | "status" : "passed",
47 | "time" : {
48 | "start" : 1612427970157,
49 | "stop" : 1612427971195,
50 | "duration" : 1038
51 | },
52 | "flaky" : false,
53 | "newFailed" : false,
54 | "parameters" : [ "{'summary': 'getAdultCurbactList', 'describe': 'test_getAdultCurbactList', 'parameter': {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': '${headtoken}'}, 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': 'getAdultCurbactList_response.json'}}" ]
55 | } ],
56 | "uid" : "ec5dd644558c5ede81175da3d69997c9"
57 | }, {
58 | "name" : "test_initCanSelInfo",
59 | "children" : [ {
60 | "name" : "test_initCanSelInfo[case_data0]",
61 | "uid" : "aa8dfcaa510813c2",
62 | "parentUid" : "d2c6018092b62680c13e6aea19af3982",
63 | "status" : "passed",
64 | "time" : {
65 | "start" : 1612427971198,
66 | "stop" : 1612427972269,
67 | "duration" : 1071
68 | },
69 | "flaky" : false,
70 | "newFailed" : false,
71 | "parameters" : [ "{'summary': 'initCanSelInfo', 'describe': 'test_initCanSelInfo', 'parameter': 'initCanSelInfo_request.json', 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': 'initCanSelInfo_response.json'}}" ]
72 | } ],
73 | "uid" : "d2c6018092b62680c13e6aea19af3982"
74 | } ],
75 | "uid" : "f9614baa9d268c2fa96855398ce8a7bf"
76 | } ]
77 | }
--------------------------------------------------------------------------------
/PyDemo/report/html/data/packages.json:
--------------------------------------------------------------------------------
1 | {
2 | "uid" : "83edc06c07f9ae9e47eb6dd1b683e4e2",
3 | "name" : "packages",
4 | "children" : [ {
5 | "name" : "PyDemo.testcase.register",
6 | "children" : [ {
7 | "name" : "test_addOrUpCurBact",
8 | "children" : [ {
9 | "name" : "test_addOrUpCurBact[case_data0]",
10 | "uid" : "e5c5230705b9bfbb",
11 | "parentUid" : "f153e80a6e9389222095044a1da3521a",
12 | "status" : "broken",
13 | "time" : {
14 | "start" : 1612427966998,
15 | "stop" : 1612427969076,
16 | "duration" : 2078
17 | },
18 | "flaky" : false,
19 | "newFailed" : false,
20 | "parameters" : [ "{'summary': 'addOrUpCurBact', 'describe': 'test_addOrUpCurBact', 'parameter': 'addOrUpCurBact_request.json', 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': {'success': True, 'code': None, 'msg': '返回成功', 'data': None, 'callTime': None}}}" ]
21 | } ],
22 | "uid" : "f153e80a6e9389222095044a1da3521a"
23 | }, {
24 | "name" : "test_findParam",
25 | "children" : [ {
26 | "name" : "test_findParam[case_data0]",
27 | "uid" : "10d4bd6301177f6",
28 | "parentUid" : "f5cbb0f92dea3d0ffa74221d10e6ba6e",
29 | "status" : "passed",
30 | "time" : {
31 | "start" : 1612427969141,
32 | "stop" : 1612427970154,
33 | "duration" : 1013
34 | },
35 | "flaky" : false,
36 | "newFailed" : false,
37 | "parameters" : [ "{'summary': 'findParam', 'describe': 'test_findParam', 'parameter': {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': '${headtoken}'}, 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': {'success': True, 'code': None, 'msg': '返回成功', 'data': ['1', '1'], 'callTime': None}}}" ]
38 | } ],
39 | "uid" : "f5cbb0f92dea3d0ffa74221d10e6ba6e"
40 | }, {
41 | "name" : "test_getAdultCurbactList",
42 | "children" : [ {
43 | "name" : "test_getAdultCurbactList[case_data0]",
44 | "uid" : "7d4ed4f7a18b20d4",
45 | "parentUid" : "b3d10c61a910c159702189dc22cdc1ff",
46 | "status" : "passed",
47 | "time" : {
48 | "start" : 1612427970157,
49 | "stop" : 1612427971195,
50 | "duration" : 1038
51 | },
52 | "flaky" : false,
53 | "newFailed" : false,
54 | "parameters" : [ "{'summary': 'getAdultCurbactList', 'describe': 'test_getAdultCurbactList', 'parameter': {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': '${headtoken}'}, 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': 'getAdultCurbactList_response.json'}}" ]
55 | } ],
56 | "uid" : "b3d10c61a910c159702189dc22cdc1ff"
57 | }, {
58 | "name" : "test_initCanSelInfo",
59 | "children" : [ {
60 | "name" : "test_initCanSelInfo[case_data0]",
61 | "uid" : "aa8dfcaa510813c2",
62 | "parentUid" : "b77503932ded1905a43d0db61688ff42",
63 | "status" : "passed",
64 | "time" : {
65 | "start" : 1612427971198,
66 | "stop" : 1612427972269,
67 | "duration" : 1071
68 | },
69 | "flaky" : false,
70 | "newFailed" : false,
71 | "parameters" : [ "{'summary': 'initCanSelInfo', 'describe': 'test_initCanSelInfo', 'parameter': 'initCanSelInfo_request.json', 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': 'initCanSelInfo_response.json'}}" ]
72 | } ],
73 | "uid" : "b77503932ded1905a43d0db61688ff42"
74 | } ],
75 | "uid" : "PyDemo.testcase.register"
76 | } ]
77 | }
--------------------------------------------------------------------------------
/PyDemo/report/html/plugins/behaviors/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | allure.api.addTranslation('en', {
4 | tab: {
5 | behaviors: {
6 | name: 'Behaviors'
7 | }
8 | },
9 | widget: {
10 | behaviors: {
11 | name: 'Features by stories',
12 | showAll: 'show all'
13 | }
14 | }
15 | });
16 |
17 | allure.api.addTranslation('ru', {
18 | tab: {
19 | behaviors: {
20 | name: 'Функциональность'
21 | }
22 | },
23 | widget: {
24 | behaviors: {
25 | name: 'Функциональность',
26 | showAll: 'показать все'
27 | }
28 | }
29 | });
30 |
31 | allure.api.addTranslation('zh', {
32 | tab: {
33 | behaviors: {
34 | name: '功能'
35 | }
36 | },
37 | widget: {
38 | behaviors: {
39 | name: '特性场景',
40 | showAll: '显示所有'
41 | }
42 | }
43 | });
44 |
45 | allure.api.addTranslation('de', {
46 | tab: {
47 | behaviors: {
48 | name: 'Verhalten'
49 | }
50 | },
51 | widget: {
52 | behaviors: {
53 | name: 'Features nach Stories',
54 | showAll: 'Zeige alle'
55 | }
56 | }
57 | });
58 |
59 | allure.api.addTranslation('he', {
60 | tab: {
61 | behaviors: {
62 | name: 'התנהגויות'
63 | }
64 | },
65 | widget: {
66 | behaviors: {
67 | name: 'תכונות לפי סיפורי משתמש',
68 | showAll: 'הצג הכול'
69 | }
70 | }
71 | });
72 |
73 | allure.api.addTranslation('br', {
74 | tab: {
75 | behaviors: {
76 | name: 'Comportamentos'
77 | }
78 | },
79 | widget: {
80 | behaviors: {
81 | name: 'Funcionalidades por história',
82 | showAll: 'Mostrar tudo'
83 | }
84 | }
85 | });
86 |
87 | allure.api.addTranslation('ja', {
88 | tab: {
89 | behaviors: {
90 | name: '振る舞い'
91 | }
92 | },
93 | widget: {
94 | behaviors: {
95 | name: 'ストーリー別の機能',
96 | showAll: '全て表示'
97 | }
98 | }
99 | });
100 |
101 | allure.api.addTranslation('es', {
102 | tab: {
103 | behaviors: {
104 | name: 'Funcionalidades'
105 | }
106 | },
107 | widget: {
108 | behaviors: {
109 | name: 'Funcionalidades por Historias de Usuario',
110 | showAll: 'mostrar todo'
111 | }
112 | }
113 | });
114 |
115 | allure.api.addTranslation('kr', {
116 | tab: {
117 | behaviors: {
118 | name: '동작'
119 | }
120 | },
121 | widget: {
122 | behaviors: {
123 | name: '스토리별 기능',
124 | showAll: '전체 보기'
125 | }
126 | }
127 | });
128 |
129 | allure.api.addTab('behaviors', {
130 | title: 'tab.behaviors.name', icon: 'fa fa-list',
131 | route: 'behaviors(/)(:testGroup)(/)(:testResult)(/)(:testResultTab)(/)',
132 | onEnter: (function (testGroup, testResult, testResultTab) {
133 | return new allure.components.TreeLayout({
134 | testGroup: testGroup,
135 | testResult: testResult,
136 | testResultTab: testResultTab,
137 | tabName: 'tab.behaviors.name',
138 | baseUrl: 'behaviors',
139 | url: 'data/behaviors.json',
140 | csvUrl: 'data/behaviors.csv'
141 | });
142 | })
143 | });
144 |
145 | allure.api.addWidget('widgets', 'behaviors', allure.components.WidgetStatusView.extend({
146 | rowTag: 'a',
147 | title: 'widget.behaviors.name',
148 | baseUrl: 'behaviors',
149 | showLinks: true
150 | }));
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/1dd259f7ca780bf0.attach:
--------------------------------------------------------------------------------
1 | {'success': True, 'code': None, 'msg': '返回成功', 'data': {'totalPage': 4, 'list': [{'bactCode': None, 'bactValidate': '2022-02-02 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '20220202', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-01-28 15:31:48', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': 'CC0EF5CA-4EC0-D100-25EB-DAD3F6E5F6E0', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-01-28 15:32:36', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 9999, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-02 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '20220202', 'bizType': 1, 'coreName': '辽宁成大', 'corpSimpName': '辽宁成大', 'createDate': '2021-01-28 15:31:49', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': '3E8725A8-D8FE-0F8F-0F60-0D7844F02A5F', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '冻干狂犬病疫苗Vero', 'materType': '86901202000020', 'materTypeCode': '1', 'modifyDate': '2021-01-28 15:32:40', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒4支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbym', 'qty': 9999, 'speCode': None, 'speCodeName': '0.5ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1001'}, {'bactCode': None, 'bactValidate': '2022-02-02 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '20220202', 'bizType': 1, 'coreName': '武汉生物', 'corpSimpName': '武汉生物', 'createDate': '2021-01-28 15:31:50', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': 'D4D5743D-9FAB-5CEE-1750-4AC1D4835028', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬球蛋白', 'materType': '86901960000553', 'materTypeCode': '2', 'modifyDate': '2021-01-28 15:32:43', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒1支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqqdb', 'qty': 9999, 'speCode': None, 'speCodeName': '200IU', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1020'}, {'bactCode': None, 'bactValidate': '2022-02-02 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '20220202', 'bizType': 2, 'coreName': '成都欧林', 'corpSimpName': '成都欧林', 'createDate': '2021-01-28 15:31:51', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': '7EE9316A-5125-D09B-6127-C994616CA011', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '破伤风疫苗', 'materType': '86981089000016', 'materTypeCode': '1', 'modifyDate': '2021-01-28 15:31:51', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒1支', 'pageSize': None, 'pageType': None, 'price': 20, 'priceEditMode': None, 'pym': 'psfym', 'qty': 0, 'speCode': None, 'speCodeName': '0.5ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1001'}]}, 'callTime': None}
--------------------------------------------------------------------------------
/PyDemo/report/xml/11f08016-1abb-461e-9e6d-fe83310ea63b-attachment.attach:
--------------------------------------------------------------------------------
1 | {'success': True, 'code': None, 'msg': '返回成功', 'data': {'totalPage': 4, 'list': [{'bactCode': None, 'bactValidate': '2022-02-02 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '20220202', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-01-28 15:31:48', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': 'CC0EF5CA-4EC0-D100-25EB-DAD3F6E5F6E0', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-01-28 15:32:36', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 9999, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-02 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '20220202', 'bizType': 1, 'coreName': '辽宁成大', 'corpSimpName': '辽宁成大', 'createDate': '2021-01-28 15:31:49', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': '3E8725A8-D8FE-0F8F-0F60-0D7844F02A5F', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '冻干狂犬病疫苗Vero', 'materType': '86901202000020', 'materTypeCode': '1', 'modifyDate': '2021-01-28 15:32:40', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒4支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbym', 'qty': 9999, 'speCode': None, 'speCodeName': '0.5ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1001'}, {'bactCode': None, 'bactValidate': '2022-02-02 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '20220202', 'bizType': 1, 'coreName': '武汉生物', 'corpSimpName': '武汉生物', 'createDate': '2021-01-28 15:31:50', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': 'D4D5743D-9FAB-5CEE-1750-4AC1D4835028', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬球蛋白', 'materType': '86901960000553', 'materTypeCode': '2', 'modifyDate': '2021-01-28 15:32:43', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒1支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqqdb', 'qty': 9999, 'speCode': None, 'speCodeName': '200IU', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1020'}, {'bactCode': None, 'bactValidate': '2022-02-02 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '20220202', 'bizType': 2, 'coreName': '成都欧林', 'corpSimpName': '成都欧林', 'createDate': '2021-01-28 15:31:51', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': '7EE9316A-5125-D09B-6127-C994616CA011', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '破伤风疫苗', 'materType': '86981089000016', 'materTypeCode': '1', 'modifyDate': '2021-01-28 15:31:51', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒1支', 'pageSize': None, 'pageType': None, 'price': 20, 'priceEditMode': None, 'pym': 'psfym', 'qty': 0, 'speCode': None, 'speCodeName': '0.5ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1001'}]}, 'callTime': None}
--------------------------------------------------------------------------------
/PyDemo/report/html/plugins/screen-diff/index.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | var settings = allure.getPluginSettings('screen-diff', {diffType: 'diff'});
3 |
4 | function renderImage(src) {
5 | return '' +
6 | '

' +
7 | '
';
8 | }
9 |
10 | function renderDiffContent(type, data) {
11 | function findImage(name) {
12 | if (data.testStage && data.testStage.attachments) {
13 | return data.testStage.attachments.filter(function (attachment) {
14 | return attachment.name === name;
15 | })[0];
16 | }
17 | return null;
18 | }
19 |
20 | var diffImage = findImage('diff');
21 | var actualImage = findImage('actual');
22 | var expectedImage = findImage('expected');
23 |
24 | if (!diffImage && !actualImage && !expectedImage) {
25 | return 'Diff, actual and expected image have not been provided.';
26 | }
27 |
28 | if (type === 'diff') {
29 | if (!diffImage) {
30 | return renderImage(actualImage.source);
31 | }
32 | return renderImage(diffImage.source);
33 | }
34 | if (type === 'overlay') {
35 | return '' +
36 | '

' +
37 | '
' +
38 | '

' +
39 | '
' +
40 | '
';
41 | }
42 | }
43 |
44 | var ScreenDiffView = Backbone.Marionette.View.extend({
45 | className: 'pane__section',
46 | events: {
47 | 'click [name="screen-diff-type"]': 'onDiffTypeChange',
48 | 'mousemove .screen-diff__overlay': 'onOverlayMove'
49 | },
50 | templateContext: function () {
51 | return {
52 | diffType: settings.get('diffType')
53 | }
54 | },
55 | template: function (data) {
56 | var testType = data.labels.filter(function (label) {
57 | return label.name === 'testType'
58 | })[0];
59 |
60 | if (!testType || testType.value !== 'screenshotDiff') {
61 | return '';
62 | }
63 |
64 | return 'Screen Diff
' +
65 | '';
72 | },
73 | adjustImageSize: function (event) {
74 | var overImage = this.$(event.target);
75 | overImage.width(overImage.width());
76 | },
77 | onRender: function () {
78 | const diffType = settings.get('diffType');
79 | this.$('[name="screen-diff-type"][value="' + diffType + '"]').prop('checked', true);
80 | if (diffType === 'overlay') {
81 | this.$('.screen-diff__image-over img').on('load', this.adjustImageSize.bind(this));
82 | }
83 | },
84 | onOverlayMove: function (event) {
85 | var pageX = event.pageX;
86 | var containerScroll = this.$('.screen-diff__container').scrollLeft();
87 | var elementX = event.currentTarget.getBoundingClientRect().left;
88 | var delta = pageX - elementX + containerScroll;
89 | this.$('.screen-diff__image-over').width(delta);
90 | },
91 | onDiffTypeChange: function (event) {
92 | settings.save('diffType', event.target.value);
93 | this.render();
94 | }
95 | });
96 | allure.api.addTestResultBlock(ScreenDiffView, {position: 'before'});
97 | })();
98 |
--------------------------------------------------------------------------------
/PyDemo/report/html/data/suites.json:
--------------------------------------------------------------------------------
1 | {
2 | "uid" : "98d3104e051c652961429bf95fa0b5d6",
3 | "name" : "suites",
4 | "children" : [ {
5 | "name" : "PyDemo.testcase.register",
6 | "children" : [ {
7 | "name" : "test_addOrUpCurBact",
8 | "children" : [ {
9 | "name" : "TestRegister",
10 | "children" : [ {
11 | "name" : "test_addOrUpCurBact[case_data0]",
12 | "uid" : "e5c5230705b9bfbb",
13 | "parentUid" : "96cf3c8a2ca39e22e5b7f098e19443e6",
14 | "status" : "broken",
15 | "time" : {
16 | "start" : 1612427966998,
17 | "stop" : 1612427969076,
18 | "duration" : 2078
19 | },
20 | "flaky" : false,
21 | "newFailed" : false,
22 | "parameters" : [ "{'summary': 'addOrUpCurBact', 'describe': 'test_addOrUpCurBact', 'parameter': 'addOrUpCurBact_request.json', 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': {'success': True, 'code': None, 'msg': '返回成功', 'data': None, 'callTime': None}}}" ]
23 | } ],
24 | "uid" : "96cf3c8a2ca39e22e5b7f098e19443e6"
25 | } ],
26 | "uid" : "30d905cbf9519c502aab8f10d2f6663f"
27 | }, {
28 | "name" : "test_findParam",
29 | "children" : [ {
30 | "name" : "TestRegister",
31 | "children" : [ {
32 | "name" : "test_findParam[case_data0]",
33 | "uid" : "10d4bd6301177f6",
34 | "parentUid" : "3e11f0c9e3a57152e27e3c6d7c2d9a03",
35 | "status" : "passed",
36 | "time" : {
37 | "start" : 1612427969141,
38 | "stop" : 1612427970154,
39 | "duration" : 1013
40 | },
41 | "flaky" : false,
42 | "newFailed" : false,
43 | "parameters" : [ "{'summary': 'findParam', 'describe': 'test_findParam', 'parameter': {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': '${headtoken}'}, 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': {'success': True, 'code': None, 'msg': '返回成功', 'data': ['1', '1'], 'callTime': None}}}" ]
44 | } ],
45 | "uid" : "3e11f0c9e3a57152e27e3c6d7c2d9a03"
46 | } ],
47 | "uid" : "4ba21b42dff4a05b71ecb42a7c5fada5"
48 | }, {
49 | "name" : "test_getAdultCurbactList",
50 | "children" : [ {
51 | "name" : "TestRegister",
52 | "children" : [ {
53 | "name" : "test_getAdultCurbactList[case_data0]",
54 | "uid" : "7d4ed4f7a18b20d4",
55 | "parentUid" : "993ed7e734c76ba1ee0cb4ddf1948c32",
56 | "status" : "passed",
57 | "time" : {
58 | "start" : 1612427970157,
59 | "stop" : 1612427971195,
60 | "duration" : 1038
61 | },
62 | "flaky" : false,
63 | "newFailed" : false,
64 | "parameters" : [ "{'summary': 'getAdultCurbactList', 'describe': 'test_getAdultCurbactList', 'parameter': {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': '${headtoken}'}, 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': 'getAdultCurbactList_response.json'}}" ]
65 | } ],
66 | "uid" : "993ed7e734c76ba1ee0cb4ddf1948c32"
67 | } ],
68 | "uid" : "dcc4595687c7e6954f35d1fbad0beeea"
69 | }, {
70 | "name" : "test_initCanSelInfo",
71 | "children" : [ {
72 | "name" : "TestRegister",
73 | "children" : [ {
74 | "name" : "test_initCanSelInfo[case_data0]",
75 | "uid" : "aa8dfcaa510813c2",
76 | "parentUid" : "322bc911d056a6689fb9c025a5b284a3",
77 | "status" : "passed",
78 | "time" : {
79 | "start" : 1612427971198,
80 | "stop" : 1612427972269,
81 | "duration" : 1071
82 | },
83 | "flaky" : false,
84 | "newFailed" : false,
85 | "parameters" : [ "{'summary': 'initCanSelInfo', 'describe': 'test_initCanSelInfo', 'parameter': 'initCanSelInfo_request.json', 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': 'initCanSelInfo_response.json'}}" ]
86 | } ],
87 | "uid" : "322bc911d056a6689fb9c025a5b284a3"
88 | } ],
89 | "uid" : "6baf0d71cf820ff083fdfcd7ca841456"
90 | } ],
91 | "uid" : "2ee94b824b159deda8131714c488ddf3"
92 | } ]
93 | }
--------------------------------------------------------------------------------
/PyDemo/page/perRelated/addAudltCard_response.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "summary": "addAudltCard",
4 | "body": {
5 | "callTime": "2021-03-12 10:05:01",
6 | "code": null,
7 | "data": {
8 | "adultInforms": [],
9 | "adultInquireBean": null,
10 | "inocStationList": [],
11 | "refuseinocList": [],
12 | "tdAdult": {
13 | "accountName": "本县",
14 | "adultAccountCode": 1002,
15 | "adultAccountStr": null,
16 | "adultAddressdistrict": "AUTO99",
17 | "adultAddressregion": "3202000000",
18 | "adultAparetel": null,
19 | "adultApptime": null,
20 | "adultArtimove": 0,
21 | "adultBirthday": "2015-03-03 00:00:00",
22 | "adultBirthdaystr": null,
23 | "adultCode": "3202112002815000002",
24 | "adultCodeStr": null,
25 | "adultCountryCode": "156",
26 | "adultCreatedate": "2021-03-12 10:05:01",
27 | "adultCreateman": "3202112002008",
28 | "adultCreatemanName": "马山山",
29 | "adultCreatemanNo": null,
30 | "adultCreatesite": "3202112002",
31 | "adultCreatesiteName": "马山社区",
32 | "adultCurdepartment": "3202112002",
33 | "adultCurdepartmentName": "马山社区",
34 | "adultDeaddate": null,
35 | "adultDelmark": 0,
36 | "adultDeltime": null,
37 | "adultEduCode": null,
38 | "adultEwmCard": null,
39 | "adultFatherno": null,
40 | "adultFathernoType": null,
41 | "adultGuard": null,
42 | "adultHabiCode": "32021100",
43 | "adultHabiStr": null,
44 | "adultHabiaddress": "AUTO99",
45 | "adultHereCode": 1001,
46 | "adultHereStr": null,
47 | "adultIfapp": 0,
48 | "adultIfdead": 0,
49 | "adultIfwxin": 0,
50 | "adultJkdaCode": null,
51 | "adultJobCode": null,
52 | "adultLeavedate": "2021-03-12 10:05:01",
53 | "adultLock": 0,
54 | "adultMarry": null,
55 | "adultMobile": "19999999999",
56 | "adultMotherno": null,
57 | "adultMothernoType": null,
58 | "adultName": "AUTO99",
59 | "adultNationCode": "1001",
60 | "adultNo": "9999999999999",
61 | "adultNoType": "2",
62 | "adultRelCode": null,
63 | "adultRemark": null,
64 | "adultResiCode": 1,
65 | "adultResiStr": null,
66 | "adultSchCode": null,
67 | "adultSchName": null,
68 | "adultSex": "1",
69 | "adultTypeCode": null,
70 | "adultWxintime": null,
71 | "age": 6,
72 | "createDate": "2021-03-12 10:05:01",
73 | "createManCode": "3202112002008",
74 | "empCode": null,
75 | "habiName": "滨湖区",
76 | "hasRefInoc": 0,
77 | "hereName": "在册",
78 | "ifInform": null,
79 | "ifInquire": null,
80 | "isqr": 0,
81 | "modifyDate": "2021-03-12 10:05:01",
82 | "modifyManCode": "3202112002008",
83 | "modifyUnitCode": "3202112002",
84 | "moveDate": null,
85 | "photoUrl": null,
86 | "resiName": "常住",
87 | "showPhotoUrl": null,
88 | "sysEditDate": null,
89 | "type": null,
90 | "unitCode": null,
91 | "unitSimpname": null
92 | },
93 | "tdAdultInoculation": [],
94 | "varIndex": []
95 | },
96 | "msg": "返回成功",
97 | "success": true
98 | }
99 | }
100 | ]
--------------------------------------------------------------------------------
/PyDemo/report/xml/dfe15ef8-3724-4710-b687-fd5f753f0ef0-result.json:
--------------------------------------------------------------------------------
1 | {"name": "test_addOrUpCurBact[case_data0]", "status": "broken", "statusDetails": {"message": "Exception: JSON格式校验,关键字 success 返回结果 True 与期望结果 None 类型不符", "trace": "self = \ncase_data = {'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': {'callTime': None, 'code': None, 'data...tCode': '280101', 'bactValidate': '2022-02-04', 'batnmb': '20110101', 'bizType': 1, ...}}, 'summary': 'addOrUpCurBact'}\n\n @pytest.mark.parametrize(\"case_data\", case_dict[\"test_case\"])\n @allure.story(\"test_addOrUpCurBact\")\n def test_addOrUpCurBact(self, case_data):\n # 初始化请求:执行前置接口+替换关联变量\n test_info, case_data = init_premise(case_dict[\"test_info\"], case_data, case_path)\n # 发送当前接口\n code, data = send_request(test_info, case_data)\n # 校验接口返回\n> check_result(case_data, code, data)\n\nPyDemo\\testcase\\register\\test_addOrUpCurBact.py:29: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _\ncomm\\unit\\checkResult.py:72: in check_result\n check_json(expected_result, data)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _\n\nsrc_data = {'callTime': None, 'code': None, 'data': None, 'msg': '返回成功', ...}\ndst_data = {'callTime': None, 'code': 1, 'data': None, 'msg': '已有该批次的疫苗,请直接修改库存!', ...}\n\n def check_json(src_data, dst_data):\n \"\"\"\n 校验的json\n :param src_data: 检验内容\n :param dst_data: 接口返回的数据\n :return:\n \"\"\"\n if isinstance(src_data, dict):\n for key in src_data:\n if key not in dst_data:\n raise Exception(\"JSON格式校验,关键字 %s 不在返回结果 %s 中!\" % (key, dst_data))\n else:\n this_key = key\n if isinstance(src_data[this_key], dict) and isinstance(dst_data[this_key], dict):\n check_json(src_data[this_key], dst_data[this_key])\n elif not isinstance(src_data[this_key], type(dst_data[this_key])):\n raise Exception(\"JSON格式校验,关键字 %s 返回结果 %s 与期望结果 %s 类型不符\"\n> % (this_key, src_data[this_key], dst_data[this_key]))\nE Exception: JSON格式校验,关键字 success 返回结果 True 与期望结果 None 类型不符\n\ncomm\\unit\\checkResult.py:28: Exception"}, "steps": [{"name": "POST请求接口", "status": "passed", "attachments": [{"name": "请求接口", "source": "da39ce35-693c-4f48-92cd-7795dd783e88-attachment.attach"}, {"name": "请求地址", "source": "e9a38fd0-5f1b-4739-a472-7606737e0911-attachment.attach"}, {"name": "请求头", "source": "d3f438ee-fde7-483c-9a1b-87ce48d23359-attachment.attach"}, {"name": "请求参数", "source": "31d021db-66cf-4b6c-ae71-15a2e9953294-attachment.attach"}], "start": 1612427967004, "stop": 1612427967006}, {"name": "POST请求接口", "status": "passed", "attachments": [{"name": "请求接口", "source": "8a751566-67d8-4a28-943a-a0c8cecc3a9f-attachment.attach"}, {"name": "请求地址", "source": "a6f8bf5f-a42a-4c47-a026-243375a5685d-attachment.attach"}, {"name": "请求头", "source": "f8618d25-7423-4d9f-a777-b1bc37ee3fd5-attachment.attach"}, {"name": "请求参数", "source": "c56c0537-21bd-4b7d-b0d8-6235c48804d2-attachment.attach"}], "start": 1612427968055, "stop": 1612427968057}, {"name": "JSON格式校验结果", "status": "passed", "attachments": [{"name": "实际code", "source": "15a5ed09-71be-4302-8da3-f1a3833890c3-attachment.attach"}, {"name": "期望code", "source": "eb8ba490-0f39-42ba-9a1c-44e5ee2a0636-attachment.attach"}, {"name": "实际data", "source": "aa05cb30-25c4-4485-b7f9-1aa4fd98e692-attachment.attach"}, {"name": "期望data", "source": "5f34e443-5ec3-41cf-9002-dd92ec056d54-attachment.attach"}], "start": 1612427969074, "stop": 1612427969075}], "attachments": [{"name": "log", "source": "b996b821-aa01-4bf4-a300-a3426ab66574-attachment.txt", "type": "text/plain"}], "parameters": [{"name": "case_data", "value": "{'summary': 'addOrUpCurBact', 'describe': 'test_addOrUpCurBact', 'parameter': 'addOrUpCurBact_request.json', 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': {'success': True, 'code': None, 'msg': '返回成功', 'data': None, 'callTime': None}}}"}], "start": 1612427966998, "stop": 1612427969076, "uuid": "7632a432-2edf-4bed-9879-5a6e506f0688", "historyId": "fb868315583aa11e2cd2b0339b92f05a", "testCaseId": "c47b844e0cc323f4955b7105ea349bb7", "fullName": "PyDemo.testcase.register.test_addOrUpCurBact.TestRegister#test_addOrUpCurBact", "labels": [{"name": "story", "value": "test_addOrUpCurBact"}, {"name": "feature", "value": "register"}, {"name": "parentSuite", "value": "PyDemo.testcase.register"}, {"name": "suite", "value": "test_addOrUpCurBact"}, {"name": "subSuite", "value": "TestRegister"}, {"name": "host", "value": "Leo-PC"}, {"name": "thread", "value": "1096-MainThread"}, {"name": "framework", "value": "pytest"}, {"name": "language", "value": "cpython3"}, {"name": "package", "value": "PyDemo.testcase.register.test_addOrUpCurBact"}]}
--------------------------------------------------------------------------------
/PyDemo/data/addAudltCard.chlsj:
--------------------------------------------------------------------------------
1 | [{"status":"COMPLETE","method":"POST","protocolVersion":"HTTP/1.1","scheme":"http","host":"127.0.0.1","port":30131,"actualPort":30131,"path":"/api/perRelated/addAudltCard","query":null,"tunnel":false,"keptAlive":true,"webSocket":false,"remoteAddress":"127.0.0.1/127.0.0.1","clientAddress":"/127.0.0.1","clientPort":58438,"times":{"start":"2021-03-12T10:07:03.305+08:00","requestBegin":"2021-03-12T10:07:03.305+08:00","requestComplete":"2021-03-12T10:07:03.305+08:00","responseBegin":"2021-03-12T10:07:03.497+08:00","end":"2021-03-12T10:07:03.497+08:00"},"durations":{"total":192,"dns":null,"connect":null,"ssl":null,"request":0,"response":0,"latency":192},"speeds":{"overall":"12427","request":"0","response":"0"},"totalSize":"2386","request":{"sizes":{"headers":486,"body":634},"mimeType":"application/x-www-form-urlencoded","charset":"UTF-8","contentEncoding":null,"header":{"firstLine":"POST /api/perRelated/addAudltCard HTTP/1.1","headers":[{"name":"Host","value":"127.0.0.1:30131"},{"name":"Content-Length","value":"634"},{"name":"Accept","value":"application/json, text/plain, */*"},{"name":"User-Agent","value":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36"},{"name":"Content-Type","value":"application/x-www-form-urlencoded;charset=UTF-8"},{"name":"Origin","value":"http://127.0.0.1:6006"},{"name":"Referer","value":"http://127.0.0.1:6006/"},{"name":"Accept-Encoding","value":"gzip, deflate"},{"name":"Accept-Language","value":"zh-CN,zh;q=0.9"},{"name":"Connection","value":"keep-alive"}]},"body":{"text":"{\"params\":{\"adultAddressregion\":\"3202000000\",\"adultAddressdistrict\":\"测试\",\"adultCountryCode\":\"156\",\"adultNationCode\":\"1001\",\"adultNoType\":\"2\",\"adultHabiCode\":\"32021100\",\"unitCode\":\"3202112002\",\"adultAccountCode\":1002,\"adultResiCode\":1,\"adultNo\":\"9999999999999\",\"adultName\":\"测试\",\"adultSex\":\"1\",\"adultBirthday\":\"2015-03-03\",\"adultMobile\":\"19999999999\",\"adultHabiaddress\":\"测试\",\"adultArtimove\":0,\"adultIfdead\":0,\"adultHereCode\":1001,\"adultCreatesite\":\"3202112002\",\"adultCreatemanName\":\"马山山\",\"adultCreateman\":\"3202112002008\",\"adultCreatesiteName\":\"马山社区\"},\"headtoken\":\"ci3fxE80WQ7XyurO4/IKRcHql4tf3Xw/fu+VnRGKtCw=\"}","charset":"UTF-8"}},"response":{"status":200,"sizes":{"headers":427,"body":839},"mimeType":"text/plain","charset":"UTF-8","contentEncoding":"gzip","header":{"firstLine":"HTTP/1.1 200 OK","headers":[{"name":"Server","value":"nginx"},{"name":"Date","value":"Fri, 12 Mar 2021 01:59:45 GMT"},{"name":"Content-Type","value":"text/plain; charset=UTF-8"},{"name":"Transfer-Encoding","value":"chunked"},{"name":"access-control-allow-origin","value":"*"},{"name":"access-control-allow-headers","value":"Origin, X-Requested-With, Content-Type, Accept,Access-Control-Allow-Origin"},{"name":"access-control-allow-methods","value":"GET, POST,OPTIONS"},{"name":"Content-Encoding","value":"gzip"},{"name":"Proxy-Connection","value":"keep-alive"}]},"body":{"text":"{\"callTime\":\"2021-03-12 10:05:01\",\"code\":null,\"data\":{\"adultInforms\":[],\"adultInquireBean\":null,\"inocStationList\":[],\"refuseinocList\":[],\"tdAdult\":{\"accountName\":\"本县\",\"adultAccountCode\":1002,\"adultAccountStr\":null,\"adultAddressdistrict\":\"测试\",\"adultAddressregion\":\"3202000000\",\"adultAparetel\":null,\"adultApptime\":null,\"adultArtimove\":0,\"adultBirthday\":\"2015-03-03 00:00:00\",\"adultBirthdaystr\":null,\"adultCode\":\"3202112002815000002\",\"adultCodeStr\":null,\"adultCountryCode\":\"156\",\"adultCreatedate\":\"2021-03-12 10:05:01\",\"adultCreateman\":\"3202112002008\",\"adultCreatemanName\":\"马山山\",\"adultCreatemanNo\":null,\"adultCreatesite\":\"3202112002\",\"adultCreatesiteName\":\"马山社区\",\"adultCurdepartment\":\"3202112002\",\"adultCurdepartmentName\":\"马山社区\",\"adultDeaddate\":null,\"adultDelmark\":0,\"adultDeltime\":null,\"adultEduCode\":null,\"adultEwmCard\":null,\"adultFatherno\":null,\"adultFathernoType\":null,\"adultGuard\":null,\"adultHabiCode\":\"32021100\",\"adultHabiStr\":null,\"adultHabiaddress\":\"测试\",\"adultHereCode\":1001,\"adultHereStr\":null,\"adultIfapp\":0,\"adultIfdead\":0,\"adultIfwxin\":0,\"adultJkdaCode\":null,\"adultJobCode\":null,\"adultLeavedate\":\"2021-03-12 10:05:01\",\"adultLock\":0,\"adultMarry\":null,\"adultMobile\":\"19999999999\",\"adultMotherno\":null,\"adultMothernoType\":null,\"adultName\":\"测试\",\"adultNationCode\":\"1001\",\"adultNo\":\"9999999999999\",\"adultNoType\":\"2\",\"adultRelCode\":null,\"adultRemark\":null,\"adultResiCode\":1,\"adultResiStr\":null,\"adultSchCode\":null,\"adultSchName\":null,\"adultSex\":\"1\",\"adultTypeCode\":null,\"adultWxintime\":null,\"age\":6,\"createDate\":\"2021-03-12 10:05:01\",\"createManCode\":\"3202112002008\",\"empCode\":null,\"habiName\":\"滨湖区\",\"hasRefInoc\":0,\"hereName\":\"在册\",\"ifInform\":null,\"ifInquire\":null,\"isqr\":0,\"modifyDate\":\"2021-03-12 10:05:01\",\"modifyManCode\":\"3202112002008\",\"modifyUnitCode\":\"3202112002\",\"moveDate\":null,\"photoUrl\":null,\"resiName\":\"常住\",\"showPhotoUrl\":null,\"sysEditDate\":null,\"type\":null,\"unitCode\":null,\"unitSimpname\":null},\"tdAdultInoculation\":[],\"varIndex\":[]},\"msg\":\"返回成功\",\"success\":true}","charset":"UTF-8","decoded":true}}}]
--------------------------------------------------------------------------------
/PyDemo/report/html/data/test-cases/aa8dfcaa510813c2.json:
--------------------------------------------------------------------------------
1 | {
2 | "uid" : "aa8dfcaa510813c2",
3 | "name" : "test_initCanSelInfo[case_data0]",
4 | "fullName" : "PyDemo.testcase.register.test_initCanSelInfo.TestRegister#test_initCanSelInfo",
5 | "historyId" : "1155f03dcf38b2069e797022e1f66d78",
6 | "time" : {
7 | "start" : 1612427971198,
8 | "stop" : 1612427972269,
9 | "duration" : 1071
10 | },
11 | "status" : "passed",
12 | "flaky" : false,
13 | "newFailed" : false,
14 | "beforeStages" : [ ],
15 | "testStage" : {
16 | "status" : "passed",
17 | "steps" : [ {
18 | "name" : "POST请求接口",
19 | "time" : {
20 | "start" : 1612427971221,
21 | "stop" : 1612427971223,
22 | "duration" : 2
23 | },
24 | "status" : "passed",
25 | "steps" : [ ],
26 | "attachments" : [ {
27 | "uid" : "d4cfa82e3954b068",
28 | "name" : "请求接口",
29 | "source" : "d4cfa82e3954b068.attach",
30 | "type" : "text/plain",
31 | "size" : 14
32 | }, {
33 | "uid" : "ea0ced6a1ef79518",
34 | "name" : "请求地址",
35 | "source" : "ea0ced6a1ef79518.attach",
36 | "type" : "text/plain",
37 | "size" : 53
38 | }, {
39 | "uid" : "7f88a98d6e750e3c",
40 | "name" : "请求头",
41 | "source" : "7f88a98d6e750e3c.attach",
42 | "type" : "text/plain",
43 | "size" : 67
44 | }, {
45 | "uid" : "d7e1801c64f284ab",
46 | "name" : "请求参数",
47 | "source" : "d7e1801c64f284ab.attach",
48 | "type" : "text/plain",
49 | "size" : 452
50 | } ],
51 | "parameters" : [ ],
52 | "stepsCount" : 0,
53 | "hasContent" : true,
54 | "attachmentsCount" : 4,
55 | "shouldDisplayMessage" : false
56 | }, {
57 | "name" : "JSON格式校验结果",
58 | "time" : {
59 | "start" : 1612427972266,
60 | "stop" : 1612427972269,
61 | "duration" : 3
62 | },
63 | "status" : "passed",
64 | "steps" : [ ],
65 | "attachments" : [ {
66 | "uid" : "a142325f6ec7dd97",
67 | "name" : "实际code",
68 | "source" : "a142325f6ec7dd97.attach",
69 | "type" : "text/plain",
70 | "size" : 3
71 | }, {
72 | "uid" : "d57f284c2a250050",
73 | "name" : "期望code",
74 | "source" : "d57f284c2a250050.attach",
75 | "type" : "text/plain",
76 | "size" : 3
77 | }, {
78 | "uid" : "1c85ce2c08ae706f",
79 | "name" : "实际data",
80 | "source" : "1c85ce2c08ae706f.attach",
81 | "type" : "text/plain",
82 | "size" : 49289
83 | }, {
84 | "uid" : "12f1d79c71da9096",
85 | "name" : "期望data",
86 | "source" : "12f1d79c71da9096.attach",
87 | "type" : "text/plain",
88 | "size" : 49289
89 | } ],
90 | "parameters" : [ ],
91 | "stepsCount" : 0,
92 | "hasContent" : true,
93 | "attachmentsCount" : 4,
94 | "shouldDisplayMessage" : false
95 | } ],
96 | "attachments" : [ {
97 | "uid" : "6493cdb7851bdbc9",
98 | "name" : "log",
99 | "source" : "6493cdb7851bdbc9.txt",
100 | "type" : "text/plain",
101 | "size" : 101512
102 | } ],
103 | "parameters" : [ ],
104 | "stepsCount" : 2,
105 | "hasContent" : true,
106 | "attachmentsCount" : 9,
107 | "shouldDisplayMessage" : false
108 | },
109 | "afterStages" : [ ],
110 | "labels" : [ {
111 | "name" : "story",
112 | "value" : "test_initCanSelInfo"
113 | }, {
114 | "name" : "feature",
115 | "value" : "register"
116 | }, {
117 | "name" : "parentSuite",
118 | "value" : "PyDemo.testcase.register"
119 | }, {
120 | "name" : "suite",
121 | "value" : "test_initCanSelInfo"
122 | }, {
123 | "name" : "subSuite",
124 | "value" : "TestRegister"
125 | }, {
126 | "name" : "host",
127 | "value" : "Leo-PC"
128 | }, {
129 | "name" : "thread",
130 | "value" : "1096-MainThread"
131 | }, {
132 | "name" : "framework",
133 | "value" : "pytest"
134 | }, {
135 | "name" : "language",
136 | "value" : "cpython3"
137 | }, {
138 | "name" : "package",
139 | "value" : "PyDemo.testcase.register.test_initCanSelInfo"
140 | }, {
141 | "name" : "resultFormat",
142 | "value" : "allure2"
143 | } ],
144 | "parameters" : [ {
145 | "name" : "case_data",
146 | "value" : "{'summary': 'initCanSelInfo', 'describe': 'test_initCanSelInfo', 'parameter': 'initCanSelInfo_request.json', 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': 'initCanSelInfo_response.json'}}"
147 | } ],
148 | "links" : [ ],
149 | "hidden" : false,
150 | "retry" : false,
151 | "extra" : {
152 | "severity" : "normal",
153 | "retries" : [ ],
154 | "categories" : [ ],
155 | "tags" : [ ]
156 | },
157 | "source" : "aa8dfcaa510813c2.json",
158 | "parameterValues" : [ "{'summary': 'initCanSelInfo', 'describe': 'test_initCanSelInfo', 'parameter': 'initCanSelInfo_request.json', 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': 'initCanSelInfo_response.json'}}" ]
159 | }
--------------------------------------------------------------------------------
/comm/utils/randomly.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2020/12/10
3 | # @Author : Leo Zhang
4 | # @File : randomly.py
5 | # *************************
6 | import string
7 | import random
8 | import datetime
9 | from dateutil.relativedelta import relativedelta
10 |
11 |
12 | def random_str(str_len):
13 | """从a-zA-Z0-9生成制定数量的随机字符
14 |
15 | :param str_len: 字符串长度
16 | :return:
17 | """
18 | try:
19 | str_len = int(str_len)
20 | except ValueError:
21 | raise Exception("调用随机字符失败,[ %s ]长度参数有误!" % str_len)
22 | strings = ''.join(random.sample(string.hexdigits, +str_len))
23 | return strings
24 |
25 |
26 | def random_int(scope):
27 | """获取随机整型数据
28 |
29 | :param scope: 数据范围
30 | :return:
31 | """
32 | try:
33 | start_num, end_num = scope.split(",")
34 | start_num = int(start_num)
35 | end_num = int(end_num)
36 | except ValueError:
37 | raise Exception("调用随机整数失败,[ %s ]范围参数有误!" % str(scope))
38 | if start_num <= end_num:
39 | number = random.randint(start_num, end_num)
40 | else:
41 | number = random.randint(end_num, start_num)
42 | return number
43 |
44 |
45 | def random_float(data):
46 | """获取随机浮点数据
47 |
48 | :param data: 数组
49 | :return:
50 | """
51 | try:
52 | start_num, end_num, accuracy = data.split(",")
53 | start_num = int(start_num)
54 | end_num = int(end_num)
55 | accuracy = int(accuracy)
56 | except ValueError:
57 | raise Exception("调用随机浮点数失败,[ %s ]范围参数或精度有误!" % data)
58 |
59 | if start_num <= end_num:
60 | number = random.uniform(start_num, end_num)
61 | else:
62 | number = random.uniform(end_num, start_num)
63 | number = round(number, accuracy)
64 | return number
65 |
66 |
67 | def random_choice(data):
68 | """获取数组随机值
69 |
70 | :param data: 数组
71 | :return:
72 | """
73 | _list = data.split(",")
74 | each = random.choice(_list)
75 | return each
76 |
77 |
78 | def get_date_mark(now, mark, num):
79 | if 'y' == mark:
80 | return now + relativedelta(years=num)
81 | elif 'm' == mark:
82 | return now + relativedelta(months=num)
83 | elif 'd' == mark:
84 | return now + relativedelta(days=num)
85 | elif 'h' == mark:
86 | return now + relativedelta(hours=num)
87 | elif 'M' == mark:
88 | return now + relativedelta(minutes=num)
89 | elif 's' == mark:
90 | return now + relativedelta(seconds=num)
91 | else:
92 | raise Exception("日期字段标识[ %s ]错误, 请使用[年y,月m,日d,时h,分M,秒s]标识!" % mark)
93 |
94 |
95 | def generate_date(expr=''):
96 | """生成日期对象(不含时分秒)
97 |
98 | :param expr: 日期表达式,如"d-1"代表日期减1
99 | :return:
100 | """
101 | today = datetime.date.today()
102 | if expr:
103 | try:
104 | mark = expr[:1]
105 | num = int(expr[1:])
106 | except (TypeError, NameError):
107 | raise Exception("调用生成日期失败,日期表达式[ %s ]有误!" % expr)
108 | return get_date_mark(today, mark, num)
109 | else:
110 | return today
111 |
112 |
113 | def generate_datetime(expr=''):
114 | """生成日期时间对象(含时分秒)
115 |
116 | :param expr: 日期表达式,如"d-1"代表日期减1
117 | :return:
118 | """
119 | now = datetime.datetime.now().replace(microsecond=0)
120 | if expr:
121 | try:
122 | mark = expr[:1]
123 | num = int(expr[1:])
124 | except (TypeError, NameError):
125 | raise Exception("调用生成日期失败,日期表达式[ %s ]有误!" % expr)
126 | return get_date_mark(now, mark, num)
127 | else:
128 | return now
129 |
130 |
131 | def generate_timestamp(expr=''):
132 | """生成时间戳(13位)
133 |
134 | :param expr: 日期表达式,如"d-1"代表日期减1
135 | :return:
136 | """
137 | datetime_obj = generate_datetime(expr)
138 | return int(datetime.datetime.timestamp(datetime_obj)) * 1000
139 |
140 |
141 | def generate_guid():
142 | """基于MAC地址+时间戳+随机数来生成GUID
143 |
144 | :param:
145 | :return:
146 | """
147 | import uuid
148 | return str(uuid.uuid1()).upper()
149 |
150 |
151 | def generate_wxid():
152 | """基于AUTO标识+26位英文字母大小写+数字生成伪微信ID
153 |
154 | :param:
155 | :return:
156 | """
157 | return 'AUTO' + ''.join(random.sample(string.ascii_letters + string.digits, 24))
158 |
159 |
160 | def generate_noid(expr=''):
161 | """基于6位随机数字+出生日期+4位随机数生成伪身份证
162 |
163 | :param expr: 日期表达式,如"d-1"代表日期减1
164 | :return:
165 | """
166 | birthday = generate_date(expr)
167 | birthday = str(birthday).replace('-', '')
168 | return int(str(random.randint(100000, 999999)) + birthday + str(random.randint(1000, 9999)))
169 |
170 |
171 | def generate_phone():
172 | """基于三大运营商号段+随机数生成伪手机号
173 |
174 | :param:
175 | :return:
176 | """
177 | ctcc = [133,153,173,177,180,181,189,191,193,199]
178 | cucc = [130,131,132,155,156,166,175,176,185,186,166]
179 | cmcc = [134,135,136,137,138,139,147,150,151,152,157,158,159,172,178,182,183,184,187,188,198]
180 | begin = 10 ** 7
181 | end = 10 ** 8 - 1
182 | prefix = random.choice(ctcc+cucc+cmcc)
183 | return str(prefix) + str(random.randint(begin, end))
184 |
185 |
186 | if __name__ == '__main__':
187 | # 简单随机数据
188 | print(random_str(16))
189 | print(random_int("100,200"))
190 | print(random_float("200,100,5"))
191 | print(random_choice("aaa,bbb,ccc"))
192 |
193 | # 生成日期数据
194 | print(generate_date())
195 | print(generate_datetime())
196 | print(generate_date('m+1'))
197 | print(generate_datetime('d+1'))
198 | print(generate_timestamp('s+100'))
199 | print(generate_noid('y-18'))
200 |
201 | # 生成常用数据
202 | print(generate_guid())
203 | print(generate_wxid())
204 | print(generate_noid())
205 | print(generate_phone())
--------------------------------------------------------------------------------
/PyDemo/report/html/data/test-cases/10d4bd6301177f6.json:
--------------------------------------------------------------------------------
1 | {
2 | "uid" : "10d4bd6301177f6",
3 | "name" : "test_findParam[case_data0]",
4 | "fullName" : "PyDemo.testcase.register.test_findParam.TestRegister#test_findParam",
5 | "historyId" : "62cffe5b54c1489b5c40af1b7f11c19b",
6 | "time" : {
7 | "start" : 1612427969141,
8 | "stop" : 1612427970154,
9 | "duration" : 1013
10 | },
11 | "status" : "passed",
12 | "flaky" : false,
13 | "newFailed" : false,
14 | "beforeStages" : [ ],
15 | "testStage" : {
16 | "status" : "passed",
17 | "steps" : [ {
18 | "name" : "POST请求接口",
19 | "time" : {
20 | "start" : 1612427969143,
21 | "stop" : 1612427969144,
22 | "duration" : 1
23 | },
24 | "status" : "passed",
25 | "steps" : [ ],
26 | "attachments" : [ {
27 | "uid" : "de7b006637c1f824",
28 | "name" : "请求接口",
29 | "source" : "de7b006637c1f824.attach",
30 | "type" : "text/plain",
31 | "size" : 9
32 | }, {
33 | "uid" : "6d6990d6bc7da779",
34 | "name" : "请求地址",
35 | "source" : "6d6990d6bc7da779.attach",
36 | "type" : "text/plain",
37 | "size" : 48
38 | }, {
39 | "uid" : "48d8349a567cd920",
40 | "name" : "请求头",
41 | "source" : "48d8349a567cd920.attach",
42 | "type" : "text/plain",
43 | "size" : 67
44 | }, {
45 | "uid" : "b2611d9bc9f7e7f2",
46 | "name" : "请求参数",
47 | "source" : "b2611d9bc9f7e7f2.attach",
48 | "type" : "text/plain",
49 | "size" : 149
50 | } ],
51 | "parameters" : [ ],
52 | "stepsCount" : 0,
53 | "hasContent" : true,
54 | "attachmentsCount" : 4,
55 | "shouldDisplayMessage" : false
56 | }, {
57 | "name" : "JSON格式校验结果",
58 | "time" : {
59 | "start" : 1612427970152,
60 | "stop" : 1612427970154,
61 | "duration" : 2
62 | },
63 | "status" : "passed",
64 | "steps" : [ ],
65 | "attachments" : [ {
66 | "uid" : "b5dbaecb2dacdb90",
67 | "name" : "实际code",
68 | "source" : "b5dbaecb2dacdb90.attach",
69 | "type" : "text/plain",
70 | "size" : 3
71 | }, {
72 | "uid" : "a10e5441521817af",
73 | "name" : "期望code",
74 | "source" : "a10e5441521817af.attach",
75 | "type" : "text/plain",
76 | "size" : 3
77 | }, {
78 | "uid" : "5627e81e1f308560",
79 | "name" : "实际data",
80 | "source" : "5627e81e1f308560.attach",
81 | "type" : "text/plain",
82 | "size" : 92
83 | }, {
84 | "uid" : "a2493f73f5b55797",
85 | "name" : "期望data",
86 | "source" : "a2493f73f5b55797.attach",
87 | "type" : "text/plain",
88 | "size" : 92
89 | } ],
90 | "parameters" : [ ],
91 | "stepsCount" : 0,
92 | "hasContent" : true,
93 | "attachmentsCount" : 4,
94 | "shouldDisplayMessage" : false
95 | } ],
96 | "attachments" : [ {
97 | "uid" : "64a95aad22c4bff3",
98 | "name" : "log",
99 | "source" : "64a95aad22c4bff3.txt",
100 | "type" : "text/plain",
101 | "size" : 2177
102 | } ],
103 | "parameters" : [ ],
104 | "stepsCount" : 2,
105 | "hasContent" : true,
106 | "attachmentsCount" : 9,
107 | "shouldDisplayMessage" : false
108 | },
109 | "afterStages" : [ ],
110 | "labels" : [ {
111 | "name" : "story",
112 | "value" : "test_findParam"
113 | }, {
114 | "name" : "feature",
115 | "value" : "register"
116 | }, {
117 | "name" : "parentSuite",
118 | "value" : "PyDemo.testcase.register"
119 | }, {
120 | "name" : "suite",
121 | "value" : "test_findParam"
122 | }, {
123 | "name" : "subSuite",
124 | "value" : "TestRegister"
125 | }, {
126 | "name" : "host",
127 | "value" : "Leo-PC"
128 | }, {
129 | "name" : "thread",
130 | "value" : "1096-MainThread"
131 | }, {
132 | "name" : "framework",
133 | "value" : "pytest"
134 | }, {
135 | "name" : "language",
136 | "value" : "cpython3"
137 | }, {
138 | "name" : "package",
139 | "value" : "PyDemo.testcase.register.test_findParam"
140 | }, {
141 | "name" : "resultFormat",
142 | "value" : "allure2"
143 | } ],
144 | "parameters" : [ {
145 | "name" : "case_data",
146 | "value" : "{'summary': 'findParam', 'describe': 'test_findParam', 'parameter': {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': '${headtoken}'}, 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': {'success': True, 'code': None, 'msg': '返回成功', 'data': ['1', '1'], 'callTime': None}}}"
147 | } ],
148 | "links" : [ ],
149 | "hidden" : false,
150 | "retry" : false,
151 | "extra" : {
152 | "severity" : "normal",
153 | "retries" : [ ],
154 | "categories" : [ ],
155 | "tags" : [ ]
156 | },
157 | "source" : "10d4bd6301177f6.json",
158 | "parameterValues" : [ "{'summary': 'findParam', 'describe': 'test_findParam', 'parameter': {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': '${headtoken}'}, 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': {'success': True, 'code': None, 'msg': '返回成功', 'data': ['1', '1'], 'callTime': None}}}" ]
159 | }
--------------------------------------------------------------------------------
/PyDemo/report/html/data/test-cases/7d4ed4f7a18b20d4.json:
--------------------------------------------------------------------------------
1 | {
2 | "uid" : "7d4ed4f7a18b20d4",
3 | "name" : "test_getAdultCurbactList[case_data0]",
4 | "fullName" : "PyDemo.testcase.register.test_getAdultCurbactList.TestRegister#test_getAdultCurbactList",
5 | "historyId" : "27801e67fb61317f40b6cdc1f8d317aa",
6 | "time" : {
7 | "start" : 1612427970157,
8 | "stop" : 1612427971195,
9 | "duration" : 1038
10 | },
11 | "status" : "passed",
12 | "flaky" : false,
13 | "newFailed" : false,
14 | "beforeStages" : [ ],
15 | "testStage" : {
16 | "status" : "passed",
17 | "steps" : [ {
18 | "name" : "POST请求接口",
19 | "time" : {
20 | "start" : 1612427970161,
21 | "stop" : 1612427970164,
22 | "duration" : 3
23 | },
24 | "status" : "passed",
25 | "steps" : [ ],
26 | "attachments" : [ {
27 | "uid" : "aa3749b1bd00dd8e",
28 | "name" : "请求接口",
29 | "source" : "aa3749b1bd00dd8e.attach",
30 | "type" : "text/plain",
31 | "size" : 19
32 | }, {
33 | "uid" : "436a2d6b50675cb6",
34 | "name" : "请求地址",
35 | "source" : "436a2d6b50675cb6.attach",
36 | "type" : "text/plain",
37 | "size" : 58
38 | }, {
39 | "uid" : "10ea6ae95941448c",
40 | "name" : "请求头",
41 | "source" : "10ea6ae95941448c.attach",
42 | "type" : "text/plain",
43 | "size" : 67
44 | }, {
45 | "uid" : "640913aa912828ba",
46 | "name" : "请求参数",
47 | "source" : "640913aa912828ba.attach",
48 | "type" : "text/plain",
49 | "size" : 149
50 | } ],
51 | "parameters" : [ ],
52 | "stepsCount" : 0,
53 | "hasContent" : true,
54 | "attachmentsCount" : 4,
55 | "shouldDisplayMessage" : false
56 | }, {
57 | "name" : "JSON格式校验结果",
58 | "time" : {
59 | "start" : 1612427971193,
60 | "stop" : 1612427971195,
61 | "duration" : 2
62 | },
63 | "status" : "passed",
64 | "steps" : [ ],
65 | "attachments" : [ {
66 | "uid" : "f658b4378482d4a",
67 | "name" : "实际code",
68 | "source" : "f658b4378482d4a.attach",
69 | "type" : "text/plain",
70 | "size" : 3
71 | }, {
72 | "uid" : "a404884c53f9a95e",
73 | "name" : "期望code",
74 | "source" : "a404884c53f9a95e.attach",
75 | "type" : "text/plain",
76 | "size" : 3
77 | }, {
78 | "uid" : "4874af030f961a0",
79 | "name" : "实际data",
80 | "source" : "4874af030f961a0.attach",
81 | "type" : "text/plain",
82 | "size" : 6432
83 | }, {
84 | "uid" : "1dd259f7ca780bf0",
85 | "name" : "期望data",
86 | "source" : "1dd259f7ca780bf0.attach",
87 | "type" : "text/plain",
88 | "size" : 4196
89 | } ],
90 | "parameters" : [ ],
91 | "stepsCount" : 0,
92 | "hasContent" : true,
93 | "attachmentsCount" : 4,
94 | "shouldDisplayMessage" : false
95 | } ],
96 | "attachments" : [ {
97 | "uid" : "3b002256b197c3de",
98 | "name" : "log",
99 | "source" : "3b002256b197c3de.txt",
100 | "type" : "text/plain",
101 | "size" : 12683
102 | } ],
103 | "parameters" : [ ],
104 | "stepsCount" : 2,
105 | "hasContent" : true,
106 | "attachmentsCount" : 9,
107 | "shouldDisplayMessage" : false
108 | },
109 | "afterStages" : [ ],
110 | "labels" : [ {
111 | "name" : "story",
112 | "value" : "test_getAdultCurbactList"
113 | }, {
114 | "name" : "feature",
115 | "value" : "register"
116 | }, {
117 | "name" : "parentSuite",
118 | "value" : "PyDemo.testcase.register"
119 | }, {
120 | "name" : "suite",
121 | "value" : "test_getAdultCurbactList"
122 | }, {
123 | "name" : "subSuite",
124 | "value" : "TestRegister"
125 | }, {
126 | "name" : "host",
127 | "value" : "Leo-PC"
128 | }, {
129 | "name" : "thread",
130 | "value" : "1096-MainThread"
131 | }, {
132 | "name" : "framework",
133 | "value" : "pytest"
134 | }, {
135 | "name" : "language",
136 | "value" : "cpython3"
137 | }, {
138 | "name" : "package",
139 | "value" : "PyDemo.testcase.register.test_getAdultCurbactList"
140 | }, {
141 | "name" : "resultFormat",
142 | "value" : "allure2"
143 | } ],
144 | "parameters" : [ {
145 | "name" : "case_data",
146 | "value" : "{'summary': 'getAdultCurbactList', 'describe': 'test_getAdultCurbactList', 'parameter': {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': '${headtoken}'}, 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': 'getAdultCurbactList_response.json'}}"
147 | } ],
148 | "links" : [ ],
149 | "hidden" : false,
150 | "retry" : false,
151 | "extra" : {
152 | "severity" : "normal",
153 | "retries" : [ ],
154 | "categories" : [ ],
155 | "tags" : [ ]
156 | },
157 | "source" : "7d4ed4f7a18b20d4.json",
158 | "parameterValues" : [ "{'summary': 'getAdultCurbactList', 'describe': 'test_getAdultCurbactList', 'parameter': {'params': {'unitCode': '3202112002', 'first': 0, 'pym': '', 'pageSize': 10, 'page': 0}, 'headtoken': '${headtoken}'}, 'check': {'check_type': 'check_json', 'expected_code': 200, 'expected_result': 'getAdultCurbactList_response.json'}}" ]
159 | }
--------------------------------------------------------------------------------
/comm/unit/initializePremise.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2021/2/3
3 | # @Author : Leo Zhang
4 | # @File : initializePremise.py
5 | # **************************
6 | import logging
7 | import time
8 | import json
9 | import os
10 | from json import JSONDecodeError
11 | from config import PAGE_DIR, PROJECT_NAME, API_CONFIG
12 | from comm.unit import apiSend, readRelevance, replaceRelevance
13 | from comm.utils import readYaml
14 |
15 |
16 | def read_json(summary, json_obj, case_path):
17 | """
18 | 校验内容读取
19 | :param summary: 用例名称
20 | :param json_obj: json文件或数据对象
21 | :param case_path: case路径
22 | :return:
23 | """
24 | if not json_obj:
25 | return json_obj
26 | elif isinstance(json_obj, dict):
27 | return json_obj
28 | else:
29 | try:
30 | # 读取json文件指定用例数据
31 | with open(case_path+'/'+json_obj, "r", encoding="utf-8") as js:
32 | data_list = json.load(js)
33 | for data in data_list:
34 | if data['summary'] == summary:
35 | return data['body']
36 | except FileNotFoundError:
37 | raise Exception("用例关联文件不存在\n文件路径: %s" % json_obj)
38 | except JSONDecodeError:
39 | raise Exception("用例关联的文件有误\n文件路径: %s" % json_obj)
40 |
41 |
42 | def init_premise(test_info, case_data, case_path):
43 | """用例前提条件执行,提取关键值
44 |
45 | :param test_info: 测试信息
46 | :param case_data: 用例数据
47 | :param case_path: 用例路径
48 | :return:
49 | """
50 | # 获取项目公共关联值
51 | aconfig = readYaml.read_yaml_data(API_CONFIG)
52 | __relevance = aconfig[PROJECT_NAME]
53 | # 处理测试信息
54 | test_info = replaceRelevance.replace(test_info, __relevance)
55 | logging.debug("测试信息处理结果:{}".format(test_info))
56 | # 处理Cookies
57 | if test_info['cookies']:
58 | cookies = aconfig[PROJECT_NAME]['cookies']
59 | logging.debug("请求Cookies处理结果:{}".format(cookies))
60 |
61 | # 判断是否存在前置接口
62 | pre_case_yaml = test_info["premise"]
63 | if pre_case_yaml:
64 | # 获取前置接口用例
65 | logging.info("获取前置接口测试用例:{}".format(pre_case_yaml))
66 | pre_case_yaml = PAGE_DIR + pre_case_yaml
67 | pre_case_path = os.path.dirname(pre_case_yaml)
68 | pre_case_dict = readYaml.read_yaml_data(pre_case_yaml)
69 | pre_test_info = pre_case_dict['test_info']
70 | pre_case_data = pre_case_dict['test_case'][0]
71 | # 判断前置接口是否也存在前置接口
72 | if pre_test_info["premise"]:
73 | init_premise(pre_test_info, pre_case_data, pre_case_path)
74 |
75 | for i in range(3):
76 | # 处理前置接口测试信息
77 | pre_test_info = replaceRelevance.replace(pre_test_info, __relevance)
78 | logging.debug("测试信息处理结果:{}".format(pre_test_info))
79 | # 处理前置接口Cookies
80 | if pre_test_info['cookies']:
81 | cookies = aconfig[PROJECT_NAME]['cookies']
82 | logging.debug("请求Cookies处理结果:{}".format(cookies))
83 | # 处理前置接口入参:获取入参-替换关联值-发送请求
84 | pre_parameter = read_json(pre_case_data['summary'], pre_case_data['parameter'], pre_case_path)
85 | pre_parameter = replaceRelevance.replace(pre_parameter, __relevance)
86 | pre_case_data['parameter'] = pre_parameter
87 | logging.debug("请求参数处理结果:{}".format(pre_parameter))
88 | logging.info("执行前置接口测试用例:{}".format(pre_test_info))
89 | code, data = apiSend.send_request(pre_test_info, pre_case_data)
90 |
91 | # 检查接口是否调用成功
92 | if data:
93 | # 处理当前接口入参:获取入参-获取关联值-替换关联值
94 | parameter = read_json(case_data['summary'], case_data['parameter'], case_path)
95 | __relevance = readRelevance.get_relevance(data, parameter, __relevance)
96 | parameter = replaceRelevance.replace(parameter, __relevance)
97 | case_data['parameter'] = parameter
98 | logging.debug("请求参数处理结果:{}".format(parameter))
99 |
100 | # 获取当前接口期望结果:获取期望结果-获取关联值-替换关联值
101 | expected_rs = read_json(case_data['summary'], case_data['check_body']['expected_result'], case_path)
102 | parameter['data'] = data
103 | __relevance = readRelevance.get_relevance(parameter, expected_rs, __relevance)
104 | expected_rs = replaceRelevance.replace(expected_rs, __relevance)
105 | case_data['check_body']['expected_result'] = expected_rs
106 | logging.debug("期望返回处理结果:{}".format(case_data))
107 | break
108 | else:
109 | time.sleep(1)
110 | logging.error("前置接口请求失败!等待1秒后重试!")
111 | else:
112 | logging.info("前置接口请求失败!尝试三次失败!")
113 | raise Exception("获取前置接口关联数据失败!")
114 | else:
115 | # 处理当前接口入参:获取入参-获取关联值-替换关联值
116 | parameter = read_json(case_data['summary'], case_data['parameter'], case_path)
117 | parameter = replaceRelevance.replace(parameter, __relevance)
118 | case_data['parameter'] = parameter
119 | logging.debug("请求参数处理结果:{}".format(parameter))
120 |
121 | # 获取当前接口期望结果:获取期望结果-获取关联值-替换关联值
122 | expected_rs = read_json(case_data['summary'], case_data['check_body']['expected_result'], case_path)
123 | __relevance = readRelevance.get_relevance(parameter, expected_rs, __relevance)
124 | expected_rs = replaceRelevance.replace(expected_rs, __relevance)
125 | case_data['check_body']['expected_result'] = expected_rs
126 | logging.debug("期望返回处理结果:{}".format(case_data))
127 |
128 | return test_info, case_data
129 |
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/4874af030f961a0.attach:
--------------------------------------------------------------------------------
1 | {'success': True, 'code': None, 'msg': '返回成功', 'data': {'totalPage': 6, 'list': [{'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '$RanStr(10)', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:18:01', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': 'AFC56C4E-4DED-6281-2CFC-E52F5ADA80BF', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:18:01', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': 'aEc7d4F5B2', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:24:08', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': '2D643A03-5201-CCF7-4589-AFEC7CCA1DC6', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:24:08', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '2F7EB0ec6D', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:23:47', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': 'B8827B29-164E-1ADC-549A-FE256BD47389', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:23:47', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-01-01 23:59:59', 'bacttypeGroupcode': None, 'batnmb': '20191118lkl-50', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:16:08', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 1, 'delTime': None, 'first': None, 'guid': '4AAFDB6F-C0C1-269C-91D4-BC0730EFCC30', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:16:11', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 100, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 87, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': 'B827FAC9-6291-337C-D692-885013A1FE44', 'storageGuid': 'FA9C4671-A7E3-0170-23CB-5EC7ED33F019', 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '78C53aDf02', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:20:44', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': '06726F20-49FF-E3D8-6769-8B808E881E85', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:20:44', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '20110101', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:25:12', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': 'EC6F0A3F-DCB4-C2AA-AC3C-447EEA829CA1', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:25:12', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}]}, 'callTime': None}
--------------------------------------------------------------------------------
/PyDemo/report/xml/a8105e8d-2465-4d01-9dca-cec2937a0cfd-attachment.attach:
--------------------------------------------------------------------------------
1 | {'success': True, 'code': None, 'msg': '返回成功', 'data': {'totalPage': 6, 'list': [{'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '$RanStr(10)', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:18:01', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': 'AFC56C4E-4DED-6281-2CFC-E52F5ADA80BF', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:18:01', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': 'aEc7d4F5B2', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:24:08', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': '2D643A03-5201-CCF7-4589-AFEC7CCA1DC6', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:24:08', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '2F7EB0ec6D', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:23:47', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': 'B8827B29-164E-1ADC-549A-FE256BD47389', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:23:47', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-01-01 23:59:59', 'bacttypeGroupcode': None, 'batnmb': '20191118lkl-50', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:16:08', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 1, 'delTime': None, 'first': None, 'guid': '4AAFDB6F-C0C1-269C-91D4-BC0730EFCC30', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:16:11', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 100, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 87, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': 'B827FAC9-6291-337C-D692-885013A1FE44', 'storageGuid': 'FA9C4671-A7E3-0170-23CB-5EC7ED33F019', 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '78C53aDf02', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:20:44', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': '06726F20-49FF-E3D8-6769-8B808E881E85', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:20:44', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '20110101', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:25:12', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': 'EC6F0A3F-DCB4-C2AA-AC3C-447EEA829CA1', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:25:12', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}]}, 'callTime': None}
--------------------------------------------------------------------------------
/comm/unit/apiSend.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2021/2/2
3 | # @Author : Leo Zhang
4 | # @File : apiSend.py
5 | # ***********************
6 | import logging
7 | import allure
8 | import time
9 | from config import INTERVAL
10 | from comm.unit import apiMethod
11 |
12 |
13 | def send_request(test_info, case_data):
14 | """
15 | 封装请求
16 | :param test_info: 测试信息
17 | :param case_data: 用例数据
18 | :return:
19 | """
20 | try:
21 | # 获取用例基本信息
22 | host = test_info["host"]
23 | scheme = test_info["scheme"]
24 | method = test_info["method"].upper()
25 | address = test_info["address"]
26 | mime_type = test_info["mime_type"]
27 | headers = test_info["headers"]
28 | cookies = test_info["cookies"]
29 | file = test_info["file"]
30 | timeout = test_info["timeout"]
31 | summary = case_data["summary"]
32 | parameter = case_data["parameter"]
33 | except Exception as e:
34 | raise KeyError('获取用例基本信息失败:{}'.format(e))
35 |
36 | request_url = scheme + "://" + host + address
37 | logging.info("=" * 150)
38 | logging.info("请求接口:%s" % str(summary))
39 | logging.info("请求地址:%s" % request_url)
40 | logging.info("请求头: %s" % str(headers))
41 | logging.info("请求参数: %s" % str(parameter))
42 |
43 | # 判断是否保存cookies
44 | if summary == 'save_cookies':
45 | with allure.step("保存cookies信息"):
46 | allure.attach(name="请求接口", body=str(summary))
47 | allure.attach(name="请求地址", body=request_url)
48 | allure.attach(name="请求头", body=str(headers))
49 | allure.attach(name="请求参数", body=str(parameter))
50 | apiMethod.save_cookie(headers=headers,
51 | address=request_url,
52 | mime_type=mime_type,
53 | data=parameter,
54 | cookies=cookies,
55 | timeout=timeout)
56 | # 判断接口请求类型
57 | if method == 'POST':
58 | logging.info("请求方法: POST")
59 | # 判断是否上传文件
60 | if file:
61 | with allure.step("POST上传文件"):
62 | allure.attach(name="请求接口", body=str(summary))
63 | allure.attach(name="请求地址", body=request_url)
64 | allure.attach(name="请求头", body=str(headers))
65 | allure.attach(name="请求参数", body=str(parameter))
66 | result = apiMethod.post(headers=headers,
67 | address=request_url,
68 | mime_type=mime_type,
69 | files=parameter,
70 | cookies=cookies,
71 | timeout=timeout)
72 | else:
73 | with allure.step("POST请求接口"):
74 | allure.attach(name="请求接口", body=str(summary))
75 | allure.attach(name="请求地址", body=request_url)
76 | allure.attach(name="请求头", body=str(headers))
77 | allure.attach(name="请求参数", body=str(parameter))
78 | result = apiMethod.post(headers=headers,
79 | address=request_url,
80 | mime_type=mime_type,
81 | data=parameter,
82 | cookies=cookies,
83 | timeout=timeout)
84 | elif method == 'GET':
85 | logging.info("请求方法: GET")
86 | with allure.step("GET请求接口"):
87 | allure.attach(name="请求接口", body=str(summary))
88 | allure.attach(name="请求地址", body=request_url)
89 | allure.attach(name="请求头", body=str(headers))
90 | allure.attach(name="请求参数", body=str(parameter))
91 | result = apiMethod.get(headers=headers,
92 | address=request_url,
93 | data=parameter,
94 | cookies=cookies,
95 | timeout=timeout)
96 | elif method == 'PUT':
97 | logging.info("请求方法: PUT")
98 | # 判断是否上传文件
99 | if file:
100 | with allure.step("PUT上传文件"):
101 | allure.attach(name="请求接口", body=str(summary))
102 | allure.attach(name="请求地址", body=request_url)
103 | allure.attach(name="请求头", body=str(headers))
104 | allure.attach(name="请求参数", body=str(parameter))
105 | result = apiMethod.put(headers=headers,
106 | address=request_url,
107 | mime_type=mime_type,
108 | files=parameter,
109 | cookies=cookies,
110 | timeout=timeout)
111 | else:
112 | with allure.step("PUT请求接口"):
113 | allure.attach(name="请求接口", body=str(summary))
114 | allure.attach(name="请求地址", body=request_url)
115 | allure.attach(name="请求头", body=str(headers))
116 | allure.attach(name="请求参数", body=str(parameter))
117 | result = apiMethod.put(headers=headers,
118 | address=request_url,
119 | mime_type=mime_type,
120 | data=parameter,
121 | cookies=cookies,
122 | timeout=timeout)
123 | elif method == 'DELETE':
124 | logging.info("请求方法: DELETE")
125 | with allure.step("DELETE请求接口"):
126 | allure.attach(name="请求接口", body=str(summary))
127 | allure.attach(name="请求地址", body=request_url)
128 | allure.attach(name="请求头", body=str(headers))
129 | allure.attach(name="请求参数", body=str(parameter))
130 | result = apiMethod.delete(headers=headers,
131 | address=request_url,
132 | data=parameter,
133 | cookies=cookies,
134 | timeout=timeout)
135 | else:
136 | result = {"code": None, "data": None}
137 | logging.info("请求接口结果:\n %s" % str(result))
138 | time.sleep(INTERVAL)
139 | return result
140 |
--------------------------------------------------------------------------------
/PyDemo/data/getAdultCurbactList.chlsj:
--------------------------------------------------------------------------------
1 | [{"status":"COMPLETE","method":"POST","protocolVersion":"HTTP/1.1","scheme":"http","host":"127.0.0.1","port":20037,"actualPort":20037,"path":"/api/register/getAdultCurbactList","query":null,"tunnel":false,"keptAlive":true,"webSocket":false,"remoteAddress":"127.0.0.1/127.0.0.1","clientAddress":"/127.0.0.1","clientPort":59258,"times":{"start":"2021-02-04T08:35:25.297+08:00","requestBegin":"2021-02-04T08:35:25.301+08:00","requestComplete":"2021-02-04T08:35:25.302+08:00","responseBegin":"2021-02-04T08:35:25.342+08:00","end":"2021-02-04T08:35:25.344+08:00"},"durations":{"total":43,"dns":null,"connect":null,"ssl":null,"request":1,"response":2,"latency":40},"speeds":{"overall":"113116","request":"627000","response":"2118500"},"totalSize":"4864","request":{"sizes":{"headers":490,"body":137},"mimeType":"application/x-www-form-urlencoded","charset":"UTF-8","contentEncoding":null,"header":{"firstLine":"POST /api/register/getAdultCurbactList HTTP/1.1","headers":[{"name":"Host","value":"127.0.0.1:20037"},{"name":"Content-Length","value":"137"},{"name":"Accept","value":"application/json, text/plain, */*"},{"name":"User-Agent","value":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"},{"name":"Content-Type","value":"application/x-www-form-urlencoded;charset=UTF-8"},{"name":"Origin","value":"http://127.0.0.1:6006"},{"name":"Referer","value":"http://127.0.0.1:6006/"},{"name":"Accept-Encoding","value":"gzip, deflate"},{"name":"Accept-Language","value":"zh-CN,zh;q=0.9"},{"name":"Connection","value":"keep-alive"}]},"body":{"text":"{\"params\":{\"unitCode\":\"3202112002\",\"first\":0,\"pym\":\"\",\"pageSize\":10,\"page\":0},\"headtoken\":\"/8QPAj9LlNJ1MaPd9ykD9cHql4tf3Xw/fu+VnRGKtCw=\"}","charset":"UTF-8"}},"response":{"status":200,"sizes":{"headers":396,"body":3841},"mimeType":"application/json","charset":"UTF-8","contentEncoding":null,"header":{"firstLine":"HTTP/1.1 200 ","headers":[{"name":"Server","value":"nginx/1.14.2"},{"name":"Date","value":"Thu, 04 Feb 2021 00:29:29 GMT"},{"name":"Content-Type","value":"application/json;charset=UTF-8"},{"name":"Content-Length","value":"3841"},{"name":"Access-Control-Allow-Headers","value":"Content-Type,x-requested-with,Authorization,Access-Control-Allow-Origin"},{"name":"Access-Control-Allow-Methods","value":"POST, GET, OPTIONS"},{"name":"Access-Control-Allow-Origin","value":"*"},{"name":"Access-Control-Max-Age","value":"360"},{"name":"Proxy-Connection","value":"keep-alive"}]},"body":{"text":"{\"success\":true,\"code\":null,\"msg\":\"返回成功\",\"data\":{\"totalPage\":4,\"list\":[{\"bactCode\":null,\"bactValidate\":\"2022-02-02 00:00:00\",\"bacttypeGroupcode\":null,\"batnmb\":\"20220202\",\"bizType\":1,\"coreName\":\"大连雅立峰\",\"corpSimpName\":\"大连雅立峰\",\"createDate\":\"2021-01-28 15:31:48\",\"createManCode\":\"3202112002008\",\"createManName\":null,\"createUnitcode\":\"3202112002\",\"dataType\":2,\"delTime\":null,\"first\":null,\"guid\":\"CC0EF5CA-4EC0-D100-25EB-DAD3F6E5F6E0\",\"ifAdd\":null,\"ifMulti\":0,\"ifUse\":1,\"inocCorpCode\":null,\"materName\":\"狂犬病疫苗(vero细胞)\",\"materType\":\"86901119000052\",\"materTypeCode\":\"1\",\"modifyDate\":\"2021-01-28 15:32:36\",\"modifyManCode\":\"3202112002008\",\"modifyManName\":null,\"modifyUnitcode\":\"3202112002\",\"modifytDate\":null,\"packageNum\":\"盒5支\",\"pageSize\":null,\"pageType\":null,\"price\":0,\"priceEditMode\":null,\"pym\":\"kqbymveroxb\",\"qty\":9999,\"speCode\":null,\"speCodeName\":\"1.0ml\",\"stopDate\":null,\"storageCode\":null,\"storageGuid\":null,\"storageName\":null,\"synDataList\":[],\"unitCode\":\"3202112002\",\"vaccSpeCode\":\"1002\"},{\"bactCode\":null,\"bactValidate\":\"2022-02-02 00:00:00\",\"bacttypeGroupcode\":null,\"batnmb\":\"20220202\",\"bizType\":1,\"coreName\":\"辽宁成大\",\"corpSimpName\":\"辽宁成大\",\"createDate\":\"2021-01-28 15:31:49\",\"createManCode\":\"3202112002008\",\"createManName\":null,\"createUnitcode\":\"3202112002\",\"dataType\":2,\"delTime\":null,\"first\":null,\"guid\":\"3E8725A8-D8FE-0F8F-0F60-0D7844F02A5F\",\"ifAdd\":null,\"ifMulti\":0,\"ifUse\":1,\"inocCorpCode\":null,\"materName\":\"冻干狂犬病疫苗Vero\",\"materType\":\"86901202000020\",\"materTypeCode\":\"1\",\"modifyDate\":\"2021-01-28 15:32:40\",\"modifyManCode\":\"3202112002008\",\"modifyManName\":null,\"modifyUnitcode\":\"3202112002\",\"modifytDate\":null,\"packageNum\":\"盒4支\",\"pageSize\":null,\"pageType\":null,\"price\":0,\"priceEditMode\":null,\"pym\":\"kqbym\",\"qty\":9999,\"speCode\":null,\"speCodeName\":\"0.5ml\",\"stopDate\":null,\"storageCode\":null,\"storageGuid\":null,\"storageName\":null,\"synDataList\":[],\"unitCode\":\"3202112002\",\"vaccSpeCode\":\"1001\"},{\"bactCode\":null,\"bactValidate\":\"2022-02-02 00:00:00\",\"bacttypeGroupcode\":null,\"batnmb\":\"20220202\",\"bizType\":1,\"coreName\":\"武汉生物\",\"corpSimpName\":\"武汉生物\",\"createDate\":\"2021-01-28 15:31:50\",\"createManCode\":\"3202112002008\",\"createManName\":null,\"createUnitcode\":\"3202112002\",\"dataType\":2,\"delTime\":null,\"first\":null,\"guid\":\"D4D5743D-9FAB-5CEE-1750-4AC1D4835028\",\"ifAdd\":null,\"ifMulti\":0,\"ifUse\":1,\"inocCorpCode\":null,\"materName\":\"狂犬球蛋白\",\"materType\":\"86901960000553\",\"materTypeCode\":\"2\",\"modifyDate\":\"2021-01-28 15:32:43\",\"modifyManCode\":\"3202112002008\",\"modifyManName\":null,\"modifyUnitcode\":\"3202112002\",\"modifytDate\":null,\"packageNum\":\"盒1支\",\"pageSize\":null,\"pageType\":null,\"price\":0,\"priceEditMode\":null,\"pym\":\"kqqdb\",\"qty\":9999,\"speCode\":null,\"speCodeName\":\"200IU\",\"stopDate\":null,\"storageCode\":null,\"storageGuid\":null,\"storageName\":null,\"synDataList\":[],\"unitCode\":\"3202112002\",\"vaccSpeCode\":\"1020\"},{\"bactCode\":null,\"bactValidate\":\"2022-02-02 00:00:00\",\"bacttypeGroupcode\":null,\"batnmb\":\"20220202\",\"bizType\":2,\"coreName\":\"成都欧林\",\"corpSimpName\":\"成都欧林\",\"createDate\":\"2021-01-28 15:31:51\",\"createManCode\":\"3202112002008\",\"createManName\":null,\"createUnitcode\":\"3202112002\",\"dataType\":2,\"delTime\":null,\"first\":null,\"guid\":\"7EE9316A-5125-D09B-6127-C994616CA011\",\"ifAdd\":null,\"ifMulti\":0,\"ifUse\":1,\"inocCorpCode\":null,\"materName\":\"破伤风疫苗\",\"materType\":\"86981089000016\",\"materTypeCode\":\"1\",\"modifyDate\":\"2021-01-28 15:31:51\",\"modifyManCode\":\"3202112002008\",\"modifyManName\":null,\"modifyUnitcode\":\"3202112002\",\"modifytDate\":null,\"packageNum\":\"盒1支\",\"pageSize\":null,\"pageType\":null,\"price\":20,\"priceEditMode\":null,\"pym\":\"psfym\",\"qty\":0,\"speCode\":null,\"speCodeName\":\"0.5ml\",\"stopDate\":null,\"storageCode\":null,\"storageGuid\":null,\"storageName\":null,\"synDataList\":[],\"unitCode\":\"3202112002\",\"vaccSpeCode\":\"1001\"}]},\"callTime\":null}","charset":"UTF-8"}}}]
--------------------------------------------------------------------------------
/PyDemo/report/html/data/attachments/e100c861d9156d57.attach:
--------------------------------------------------------------------------------
1 | {'params': {'pageType': '0', 'unitCode': '3202112002', 'bactCode': '280101', 'materType': '86901119000052', 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'materName': '狂犬病疫苗(vero细胞)', 'inocCorpCode': '50', 'speCodeName': '1.0ml', 'vaccSpeCode': '1002', 'pym': 'kqbymveroxb', 'price': '0', 'batnmb': '20110101', 'qty': '100', 'ifUse': 1, 'dataType': 2, 'createDate': '', 'createManCode': '3202112002008', 'modifyDate': '', 'modifyManCode': '3202112002008', 'bactValidate': '2022-02-04', 'bizType': 1, 'materTypeCode': '1'}, 'headtoken': 'xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg=', 'data': {'success': True, 'code': None, 'msg': '返回成功', 'data': {'totalPage': 6, 'list': [{'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '$RanStr(10)', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:18:01', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': 'AFC56C4E-4DED-6281-2CFC-E52F5ADA80BF', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:18:01', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': 'aEc7d4F5B2', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:24:08', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': '2D643A03-5201-CCF7-4589-AFEC7CCA1DC6', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:24:08', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '2F7EB0ec6D', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:23:47', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': 'B8827B29-164E-1ADC-549A-FE256BD47389', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:23:47', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-01-01 23:59:59', 'bacttypeGroupcode': None, 'batnmb': '20191118lkl-50', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:16:08', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 1, 'delTime': None, 'first': None, 'guid': '4AAFDB6F-C0C1-269C-91D4-BC0730EFCC30', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:16:11', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 100, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 87, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': 'B827FAC9-6291-337C-D692-885013A1FE44', 'storageGuid': 'FA9C4671-A7E3-0170-23CB-5EC7ED33F019', 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '78C53aDf02', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:20:44', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': '06726F20-49FF-E3D8-6769-8B808E881E85', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:20:44', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '20110101', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:25:12', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': 'EC6F0A3F-DCB4-C2AA-AC3C-447EEA829CA1', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:25:12', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}]}, 'callTime': None}}
--------------------------------------------------------------------------------
/PyDemo/report/xml/c56c0537-21bd-4b7d-b0d8-6235c48804d2-attachment.attach:
--------------------------------------------------------------------------------
1 | {'params': {'pageType': '0', 'unitCode': '3202112002', 'bactCode': '280101', 'materType': '86901119000052', 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'materName': '狂犬病疫苗(vero细胞)', 'inocCorpCode': '50', 'speCodeName': '1.0ml', 'vaccSpeCode': '1002', 'pym': 'kqbymveroxb', 'price': '0', 'batnmb': '20110101', 'qty': '100', 'ifUse': 1, 'dataType': 2, 'createDate': '', 'createManCode': '3202112002008', 'modifyDate': '', 'modifyManCode': '3202112002008', 'bactValidate': '2022-02-04', 'bizType': 1, 'materTypeCode': '1'}, 'headtoken': 'xu5YwIZFkVGczMn0H0rot2ps7zRIbvrTHNwMXx1sJXg=', 'data': {'success': True, 'code': None, 'msg': '返回成功', 'data': {'totalPage': 6, 'list': [{'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '$RanStr(10)', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:18:01', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': 'AFC56C4E-4DED-6281-2CFC-E52F5ADA80BF', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:18:01', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': 'aEc7d4F5B2', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:24:08', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': '2D643A03-5201-CCF7-4589-AFEC7CCA1DC6', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:24:08', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '2F7EB0ec6D', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:23:47', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': 'B8827B29-164E-1ADC-549A-FE256BD47389', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:23:47', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-01-01 23:59:59', 'bacttypeGroupcode': None, 'batnmb': '20191118lkl-50', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:16:08', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 1, 'delTime': None, 'first': None, 'guid': '4AAFDB6F-C0C1-269C-91D4-BC0730EFCC30', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:16:11', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 100, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 87, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': 'B827FAC9-6291-337C-D692-885013A1FE44', 'storageGuid': 'FA9C4671-A7E3-0170-23CB-5EC7ED33F019', 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '78C53aDf02', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:20:44', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': '06726F20-49FF-E3D8-6769-8B808E881E85', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:20:44', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}, {'bactCode': None, 'bactValidate': '2022-02-04 00:00:00', 'bacttypeGroupcode': None, 'batnmb': '20110101', 'bizType': 1, 'coreName': '大连雅立峰', 'corpSimpName': '大连雅立峰', 'createDate': '2021-02-04 16:25:12', 'createManCode': '3202112002008', 'createManName': None, 'createUnitcode': '3202112002', 'dataType': 2, 'delTime': None, 'first': None, 'guid': 'EC6F0A3F-DCB4-C2AA-AC3C-447EEA829CA1', 'ifAdd': None, 'ifMulti': 0, 'ifUse': 1, 'inocCorpCode': None, 'materName': '狂犬病疫苗(vero细胞)', 'materType': '86901119000052', 'materTypeCode': '1', 'modifyDate': '2021-02-04 16:25:12', 'modifyManCode': '3202112002008', 'modifyManName': None, 'modifyUnitcode': '3202112002', 'modifytDate': None, 'packageNum': '盒5支', 'pageSize': None, 'pageType': None, 'price': 0, 'priceEditMode': None, 'pym': 'kqbymveroxb', 'qty': 100, 'speCode': None, 'speCodeName': '1.0ml', 'stopDate': None, 'storageCode': None, 'storageGuid': None, 'storageName': None, 'synDataList': [], 'unitCode': '3202112002', 'vaccSpeCode': '1002'}]}, 'callTime': None}}
--------------------------------------------------------------------------------
/comm/unit/replaceRelevance.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # @Time : 2020/12/09
3 | # @Author : Leo Zhang
4 | # @File : replaceRelevance.py
5 | # ****************************
6 | import re
7 | from comm.utils.randomly import *
8 |
9 | pattern_var = r"\${(.*?)}"
10 | pattern_eval = r"\$Eval\((.*?)\)"
11 | pattern_str = r'\$RandStr\(([0-9]*?)\)'
12 | pattern_int = r'\$RandInt\(([0-9]*,[0-9]*?)\)'
13 | pattern_choice = r"\$RandChoice\((.*?)\)"
14 | pattern_float = r'\$RandFloat\(([0-9]*,[0-9]*,[0-9]*)\)'
15 | pattern_phone = r'\$GenPhone\(\)'
16 | pattern_guid = r'\$GenGuid\(\)'
17 | pattern_wxid = r'\$GenWxid\(\)'
18 | pattern_noid = r'\$GenNoid\((.*?)\)'
19 | pattern_date = r'\$GenDate\((.*?)\)'
20 | pattern_datetime = r'\$GenDatetime\((.*?)\)'
21 |
22 |
23 | def replace_pattern(pattern, value):
24 | """替换正则表达式
25 |
26 | :param pattern: 匹配字符
27 | :param value: 匹配值
28 | :return:
29 | """
30 | patterns = pattern.split('(.*?)')
31 | return ''.join([patterns[0], value, patterns[-1]])
32 |
33 |
34 | def replace_relevance(param, relevance=None):
35 | """替换变量关联值
36 |
37 | :param param: 参数对象
38 | :param relevance: 关联对象
39 | :return:
40 | """
41 | result = re.findall(pattern_var, str(param))
42 | if (not result) or (not relevance):
43 | pass
44 | else:
45 | for each in result:
46 | try:
47 | # 关联值只考虑一个值
48 | # value = relevance[each]
49 | # pattern = re.compile(r'\${' + each + '}')
50 | # try:
51 | # param = re.sub(pattern, value, param)
52 | # except TypeError:
53 | # param = value
54 |
55 | # 关联参数多值时一一对应替换
56 | # relevance_index = 0
57 | # if isinstance(relevance[each], list):
58 | # try:
59 | # param = re.sub(pattern, relevance[each][relevance_index], param, count=1)
60 | # relevance_index += 1
61 | # except IndexError:
62 | # relevance_index = 0
63 | # param = re.sub(pattern, relevance[each][relevance_index], param, count=1)
64 | # relevance_index += 1
65 |
66 | # 关联参数多值时指定索引值替换
67 | mark = re.findall(r"\[\-?[0-9]*\]", each)
68 | # 判断关联参数是否指定索引值var[n]
69 | if len(mark)==0:
70 | if isinstance(relevance[each], list):
71 | value = relevance[each][0]
72 | else:
73 | value = relevance[each]
74 | elif len(mark)==1:
75 | var = each.strip(mark[0])
76 | n = int(mark[0].strip('[').strip(']'))
77 | value = relevance[var][n]
78 | each = each.replace('[', '\[').replace(']', '\]')
79 | else:
80 | var = each
81 | for m in mark:
82 | var = var.replace(m, '')
83 | n1 = int(mark[0].strip('[').strip(']'))
84 | n2 = int(mark[1].strip('[').strip(']'))
85 | value = relevance[var][n1][n2]
86 | each = each.replace('[', '\[').replace(']', '\]')
87 |
88 | # 生成正在表达式并替换关联参数
89 | pattern = re.compile('\${' + each + '}')
90 | try:
91 | if param.strip('${' + each + '}'):
92 | param = re.sub(pattern, str(value), param)
93 | else:
94 | param = re.sub(pattern, value, param)
95 | except TypeError:
96 | param = value
97 | except KeyError:
98 | raise KeyError('替换变量{0}失败,未发现变量对应关联值!\n关联列表:{1}'.format(param, relevance))
99 | # pass
100 | return param
101 |
102 |
103 | def replace_eval(param):
104 | """替换eval表达式结果
105 |
106 | :param param: 参数对象
107 | :return:
108 | """
109 | result = re.findall(pattern_eval, str(param))
110 | if not result:
111 | pass
112 | else:
113 | for each in result:
114 | try:
115 | if 'import' in each:
116 | raise Exception('存在非法标识import')
117 | else:
118 | value = str(eval(each))
119 | param = re.sub(pattern_eval, value, param)
120 | except KeyError as e:
121 | raise Exception('获取值[ % ]失败!\n%'.format(param, e))
122 | except SyntaxError:
123 | pass
124 | return param
125 |
126 |
127 | def replace_random(param):
128 | """替换随机方法参数值
129 |
130 | :param param:
131 | :return:
132 | """
133 | int_list = re.findall(pattern_int, str(param))
134 | str_list = re.findall(pattern_str, str(param))
135 | choice_list = re.findall(pattern_choice, str(param))
136 | guid_list = re.findall(pattern_guid, str(param))
137 | noid_list = re.findall(pattern_noid, str(param))
138 | phone_list = re.findall(pattern_phone, str(param))
139 | wxid_list = re.findall(pattern_wxid, str(param))
140 | date_list = re.findall(pattern_date, str(param))
141 | datetime_list = re.findall(pattern_datetime, str(param))
142 |
143 | if len(str_list):
144 | for each in str_list:
145 | # pattern = re.compile(r'\$RandStr\(' + each + r'\)')
146 | # param = re.sub(pattern, str(random_str(each)), param, count=1)
147 | param = re.sub(pattern_str, str(random_str(each)), param, count=1)
148 |
149 | if len(int_list):
150 | for each in int_list:
151 | param = re.sub(pattern_int, str(random_int(each)), param, count=1)
152 |
153 | if len(choice_list):
154 | for each in choice_list:
155 | param = re.sub(pattern_choice, str(random_choice(each)), param, count=1)
156 |
157 | if len(date_list):
158 | for each in date_list:
159 | param = re.sub(pattern_date, str(generate_date(each)), param, count=1)
160 |
161 | if len(datetime_list):
162 | for each in datetime_list:
163 | param = re.sub(pattern_datetime, str(generate_datetime(each)), param, count=1)
164 |
165 | if len(noid_list):
166 | for each in noid_list:
167 | param = re.sub(pattern_noid, str(generate_noid(each)), param, count=1)
168 |
169 | if len(phone_list):
170 | for i in phone_list:
171 | param = re.sub(pattern_phone, str(generate_phone()), param, count=1)
172 |
173 | if len(guid_list):
174 | for i in guid_list:
175 | param = re.sub(pattern_guid, generate_guid(), param, count=1)
176 |
177 | if len(wxid_list):
178 | for i in wxid_list:
179 | param = re.sub(pattern_wxid, generate_wxid(), param, count=1)
180 |
181 | return param
182 |
183 |
184 | def replace(param, relevance=None):
185 | """替换参数对应关联数据
186 |
187 | :param param: 参数对象
188 | :param relevance: 关联对象
189 | :return:
190 | """
191 | if not param:
192 | pass
193 | elif isinstance(param, dict):
194 | for key, value in param.items():
195 | if isinstance(value, dict):
196 | param[key] = replace(value, relevance)
197 | elif isinstance(value, list):
198 | for index, sub_value in enumerate(value):
199 | param[key][index] = replace(sub_value, relevance)
200 | else:
201 | value = replace_relevance(value, relevance)
202 | value = replace_random(value)
203 | value = replace_eval(value)
204 | param[key] = value
205 |
206 | elif isinstance(param, list):
207 | for index, value in enumerate(param):
208 | param[index] = replace(value, relevance)
209 |
210 | else:
211 | param = replace_relevance(param, relevance)
212 | param = replace_random(param)
213 | param = replace_eval(param)
214 |
215 | return param
216 |
217 |
218 | if __name__ == '__main__':
219 | print('替换变量并计算表达式:', replace('$Eval(${unitCode}*1000+1)', {'unitCode': 9876543210}))
220 | print('生成1-9之间的随机数:', replace('$RandInt(1,9)'))
221 | print('生成10位随机字符:', replace('$RandStr(10)'))
222 | print('从列表中随机选择:', replace('$RandChoice(a,b,c,d)'))
223 | print('生成一个伪手机号:', replace('$GenPhone()'))
224 | print('生成一个guid:', replace('$GenGuid()'))
225 | print('生成一个伪微信ID:', replace('$GenWxid()'))
226 | print('生成一个伪身份证:', replace('$GenNoid()'))
227 | print('生成一个18岁伪身份证:', replace("$GenNoid(y-18)"))
228 | print('生成下个月今天的日期:', replace("$GenDate(m+1)"))
229 | print('生成昨天此时的时间:', replace("$GenDatetime(d-1)"))
230 | print('通过索引指定关联值:', replace('${name[-1]}', {'name': ['test1', 'test2']}))
231 |
--------------------------------------------------------------------------------