├── .idea
├── auto_api_test.iml
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
├── vcs.xml
└── workspace.xml
├── case
├── test_app_search_class.py
└── test_pc_signup.py
├── common
├── __init__.py
├── get_base_parms.py
├── get_token.py
└── sign_up.py
├── config
├── DB_config.ini
├── UrlConf.ini
├── __init__.py
├── __init__.pyc
├── __pycache__
│ ├── __init__.cpython-35.pyc
│ └── __init__.cpython-36.pyc
└── global.ini
├── doc
├── changelog.txt
├── jenkins持续集成说明.docx
├── 接口自动化测试框架环境搭建说明.docx
└── 接口自动化测试框架说明.docx
├── lib
├── Assertion.py
├── BSTestRunner.py
├── DubboRequest.py
├── HttpRequest.py
├── MySQL.py
├── MySQL.pyc
├── PyRedis.py
├── SendMail.py
├── SwitchHost.py
├── __init__.py
├── __init__.pyc
├── __pycache__
│ ├── BSTestRunner.cpython-37.pyc
│ ├── MySQL.cpython-35.pyc
│ ├── MySQL.cpython-36.pyc
│ ├── SendMail.cpython-37.pyc
│ ├── __init__.cpython-35.pyc
│ ├── __init__.cpython-36.pyc
│ ├── __init__.cpython-37.pyc
│ ├── config_operate.cpython-36.pyc
│ ├── config_operate.cpython-37.pyc
│ ├── log.cpython-37.pyc
│ ├── tools.cpython-36.pyc
│ └── tools.cpython-37.pyc
├── config_operate.py
├── excel.py
├── generator.py
├── log.py
└── tools.py
├── log
├── Interface-2018-09-03-14.log
├── Interface-2018-09-04-10.log
├── Interface-2018-09-04-11.log
├── Interface-2018-09-04-14.log
├── Interface-2018-09-04-15.log
└── __init__.py
├── main.py
├── report
├── 2018-09-04 11_37_58result.html
├── 2018-09-04 11_39_11result.html
├── 2018-09-04 14_04_24result.html
├── 2018-09-04 14_35_51result.html
└── __init__.py
└── requirements.txt
/.idea/auto_api_test.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
228 |
229 |
230 |
231 | print('接口请求出错,HTTP响应为%d' % rp[1])
232 | heading
233 | QA
234 | style
235 | pt
236 |
237 |
238 | self.fail('接口请求出错,HTTP响应为%d' % rp[1])
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 | true
300 | DEFINITION_ORDER
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 | project
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 | 1493283853706
689 |
690 |
691 | 1493283853706
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 |
806 |
807 |
808 |
809 |
810 |
811 |
812 |
813 |
814 |
815 |
816 |
817 |
818 |
819 |
820 |
821 |
822 |
823 |
824 |
825 |
826 |
827 |
828 |
829 |
830 |
831 |
832 |
833 |
834 |
835 |
836 |
837 |
838 |
839 |
840 |
841 |
842 |
843 |
844 |
845 |
846 |
847 |
848 |
849 |
850 |
851 |
852 |
853 |
854 |
855 |
856 |
857 |
858 |
859 |
860 |
861 |
862 |
863 |
864 |
865 |
866 |
867 |
868 |
869 |
870 |
871 |
872 |
873 |
874 |
875 |
876 |
877 |
878 |
879 |
880 |
881 |
882 |
883 |
884 |
885 |
886 |
887 |
888 |
889 |
890 |
891 |
892 |
893 |
894 |
895 |
896 |
897 |
898 |
899 |
900 |
901 |
902 |
903 |
904 |
905 |
906 |
907 |
908 |
909 |
910 |
911 |
912 |
913 |
914 |
915 |
916 |
917 |
918 |
919 |
920 |
921 |
922 |
923 |
924 |
925 |
926 |
927 |
928 |
929 |
930 |
931 |
932 |
933 |
934 |
935 |
936 |
937 |
938 |
939 |
940 |
941 |
942 |
943 |
944 |
945 |
946 |
947 |
948 |
949 |
950 |
951 |
952 |
953 |
954 |
955 |
956 |
957 |
958 |
959 |
960 |
961 |
962 |
963 |
964 |
965 |
966 |
967 |
968 |
969 |
970 |
971 |
972 |
973 |
974 |
975 |
976 |
977 |
978 |
979 |
980 |
981 |
982 |
983 |
984 |
985 |
986 |
987 |
988 |
989 |
990 |
991 |
992 |
993 |
994 |
995 |
996 |
997 |
998 |
999 |
1000 |
1001 |
1002 |
1003 |
1004 |
1005 |
1006 |
1007 |
1008 |
1009 |
1010 |
1011 |
1012 |
1013 |
1014 |
1015 |
1016 |
1017 |
1018 |
1019 |
1020 |
1021 |
1022 |
1023 |
1024 |
1025 |
1026 |
1027 |
1028 |
1029 |
1030 |
1031 |
1032 |
1033 |
1034 |
1035 |
1036 |
1037 |
1038 |
1039 |
1040 |
1041 |
1042 |
1043 |
1044 |
1045 |
1046 |
1047 |
1048 |
1049 |
1050 |
1051 |
1052 |
1053 |
1054 |
1055 |
1056 |
1057 |
1058 |
1059 |
1060 |
1061 |
1062 |
1063 |
1064 |
1065 |
1066 |
1067 |
1068 |
1069 |
--------------------------------------------------------------------------------
/case/test_app_search_class.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 | """
5 | @version: 1.0
6 | @author: liuyu
7 | @license: None
8 | @file: test_login.py
9 | @time: 17-4-19 上午10:41
10 | """
11 | import unittest, requests
12 | from lib.log import LOG
13 | from lib.config_operate import ConfigOperate
14 | from parameterized import parameterized, param
15 |
16 |
17 | class TestAppSearchClass(unittest.TestCase):
18 | '''app接口搜索、获取信息类接口'''
19 |
20 | def setUp(self):
21 | self.url = ConfigOperate('UrlConf').get_config('bj_tuanche', 'url')
22 | self.headers = {
23 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
24 | "Accept-Encoding": "gzip, deflate, br",
25 | "Accept-Language": "zh-CN,zh;q=0.9",
26 | "Content-Type":"application/json",
27 | "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"
28 | }
29 |
30 | @parameterized.expand(
31 | [ param("all_null",
32 | data_params={}),
33 |
34 | param("phone_null",
35 | data_params={'name': 'linlang9', 'cityId': 10, 'carStyleId': 32633, 'brandId': 67, 'groupbyType': 1,
36 | 'groupbyNum': 2001}),
37 | param(
38 | "name_null",
39 | data_params={'phone': '15633669988', 'cityId': 10, 'carStyleId': 32633, 'brandId': 67, 'groupbyType': 1,
40 | 'groupbyNum': 2001}),
41 | param("city_null",
42 | data_params={'name': 'linlang9', 'phone': '15633669988', 'carStyleId': 32633, 'brandId': 67,
43 | 'groupbyType': 1,
44 | 'groupbyNum': 2001})
45 | ]
46 | )
47 | def test_sign_params_null(self, _, data_params):
48 | '''验证报名各字段参数为空'''
49 | uri = '/bentley/api/applyForTcjAsyn/'
50 | response = requests.post(self.url + uri, data=data_params, headers=self.headers)
51 | LOG.info('请求{0},参数{1},状态{2},\n 响应数据{3}'.format(uri, data_params, response, response.text))
52 | self.assertEqual(response.status_code, 200, '断言响应结果为200')
53 | self.assertEqual(response.json()['code'], 100000, '断言结果为100001')
54 | self.assertEqual(response.json()['msg'], '参数异常', '断言参数异常')
55 |
56 | @parameterized.expand(
57 | [ param("all_long",
58 | data_params={'name': 'linlang9669533256997412666666', 'cityId': 108888888888, 'carStyleId': 326336666666666, 'brandId': 67666666, 'groupbyType': 18888888888888,
59 | 'groupbyNum': 20016666666666}),
60 | param("name_long",
61 | data_params={'name': 'linlang9669533256997412666666', 'cityId': 10, 'carStyleId': 32633, 'brandId': 67, 'groupbyType': 1,
62 | 'groupbyNum': 2001}),
63 | param(
64 | "phone_long",
65 | data_params={'phone': '156336699886633996666666666666', 'cityId': 10, 'carStyleId': 32633, 'brandId': 67, 'groupbyType': 1,
66 | 'groupbyNum': 2001}),
67 | param("city_long",
68 | data_params={'name': 'linlang9', 'phone': '15633669988', 'cityId': 10999999966666666666, 'carStyleId': 32633, 'brandId': 67,
69 | 'groupbyType': 1,
70 | 'groupbyNum': 2001})
71 | ]
72 | )
73 | def test_sign_params_toolong(self, _, data_params):
74 | '''验证报名各字段字符超长'''
75 | uri = '/bentley/api/applyForTcjAsyn/'
76 | response = requests.post(self.url + uri, data=data_params, headers=self.headers)
77 | LOG.info('请求{0},参数{1},状态{2},\n 响应数据{3}'.format(uri, data_params, response, response.text))
78 | self.assertEqual(response.status_code, 200, '断言响应结果为200')
79 | self.assertEqual(response.json()['code'], 100001, '断言结果为100001')
80 | self.assertEqual(response.json()['msg'], '参数异常', '断言参数异常')
81 |
82 | @unittest.skip('pass')
83 | def test_sign(self):
84 | '''验证正常参数报名'''
85 | uri = '/bentley/api/applyForTcjAsyn/'
86 | data_params = {'name': 'linlang66', 'phone': '15633996699','cityId': 10, 'carStyleId': 32,
87 | 'brandId': 67, 'groupbyType': 1,'groupbyNum': 2001}
88 | response = requests.post(self.url + uri, data=data_params, headers=self.headers)
89 | LOG.info('请求{0},参数{1},状态{2},\n 响应数据{3}'.format(uri, data_params, response, response.text))
90 | self.assertEqual(response.status_code, 200, '断言响应结果为200')
91 | self.assertEqual(response.json()['code'], 10000, '断言结果为100000')
92 | self.assertEqual(response.json()['msg'], '报名成功', '断言结果为100000')
93 |
94 | @unittest.skip('pass')
95 | def test_signed(self):
96 | '''验证已经报名过重复报名'''
97 | uri = '/bentley/api/applyForTcjAsyn/'
98 | data_params = {'name': 'linlang66', 'phone': '15633996699','cityId': 10, 'carStyleId': 32,
99 | 'brandId': 67, 'groupbyType': 1,'groupbyNum': 2001}
100 | response = requests.post(self.url + uri, data=data_params, headers=self.headers)
101 | LOG.info('请求{0},参数{1},状态{2},\n 响应数据{3}'.format(uri, data_params, response, response.text))
102 | self.assertEqual(response.status_code, 200, '断言响应结果为200')
103 | self.assertEqual(response.json()['code'], 100000, '断言结果为100000')
104 |
105 | def test_reqMethodN(self):
106 | '''验证请求方法错误'''
107 | uri = '/bentley/api/applyForTcjAsyn/'
108 | data_params = {'name': 'linlang66', 'phone': '15633996699','cityId': 10, 'carStyleId': 32,
109 | 'brandId': 67, 'groupbyType': 1,'groupbyNum': 2001}
110 | response = requests.get(self.url + uri, params=data_params, headers=self.headers)
111 | LOG.info('请求{0},参数{1},状态{2},\n 响应数据{3}'.format(uri, data_params, response, response.text))
112 | self.assertEqual(response.status_code, 200, '断言响应结果为200')
113 | self.assertEqual(response.json()['code'], 10000, '断言结果为10000')
114 |
115 |
116 |
117 | def tearDown(self):
118 | pass
119 |
120 | if __name__ == '__main__':
121 | unittest.main()
122 |
123 |
--------------------------------------------------------------------------------
/case/test_pc_signup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 | """
5 | @version: 1.0
6 | @author: liuyu
7 | @license: None
8 | @file: test_login.py
9 | @time: 17-4-19 上午10:41
10 | """
11 | import unittest, requests
12 | from lib.log import LOG
13 | from lib.config_operate import ConfigOperate
14 | from parameterized import parameterized, param
15 |
16 |
17 | class TestPcSignUp(unittest.TestCase):
18 | '''报名接口测试'''
19 |
20 | def setUp(self):
21 | self.url = ConfigOperate('UrlConf').get_config('bj_tuanche', 'url')
22 | self.headers = {
23 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
24 | "Accept-Encoding": "gzip, deflate, br",
25 | "Accept-Language": "zh-CN,zh;q=0.9",
26 | "Content-Type":"application/json",
27 | "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"
28 | }
29 |
30 | @parameterized.expand(
31 | [ param("all_null",
32 | data_params={}),
33 |
34 | param("phone_null",
35 | data_params={'name': 'linlang9', 'cityId': 10, 'carStyleId': 32633, 'brandId': 67, 'groupbyType': 1,
36 | 'groupbyNum': 2001}),
37 | param(
38 | "name_null",
39 | data_params={'phone': '15633669988', 'cityId': 10, 'carStyleId': 32633, 'brandId': 67, 'groupbyType': 1,
40 | 'groupbyNum': 2001}),
41 | param("city_null",
42 | data_params={'name': 'linlang9', 'phone': '15633669988', 'carStyleId': 32633, 'brandId': 67,
43 | 'groupbyType': 1,
44 | 'groupbyNum': 2001})
45 | ]
46 | )
47 | def test_sign_params_null(self, _, data_params):
48 | '''验证报名各字段参数为空'''
49 | uri = '/bentley/api/applyForTcjAsyn/'
50 | response = requests.post(self.url + uri, data=data_params, headers=self.headers)
51 | LOG.info('请求{0},参数{1},状态{2},\n 响应数据{3}'.format(uri, data_params, response, response.text))
52 | self.assertEqual(response.status_code, 200, '断言响应结果为200')
53 | self.assertEqual(response.json()['code'], 100000, '断言结果为100001')
54 | self.assertEqual(response.json()['msg'], '参数异常', '断言参数异常')
55 |
56 | @parameterized.expand(
57 | [ param("all_long",
58 | data_params={'name': 'linlang9669533256997412666666', 'cityId': 108888888888, 'carStyleId': 326336666666666, 'brandId': 67666666, 'groupbyType': 18888888888888,
59 | 'groupbyNum': 20016666666666}),
60 | param("name_long",
61 | data_params={'name': 'linlang9669533256997412666666', 'cityId': 10, 'carStyleId': 32633, 'brandId': 67, 'groupbyType': 1,
62 | 'groupbyNum': 2001}),
63 | param(
64 | "phone_long",
65 | data_params={'phone': '156336699886633996666666666666', 'cityId': 10, 'carStyleId': 32633, 'brandId': 67, 'groupbyType': 1,
66 | 'groupbyNum': 2001}),
67 | param("city_long",
68 | data_params={'name': 'linlang9', 'phone': '15633669988', 'cityId': 10999999966666666666, 'carStyleId': 32633, 'brandId': 67,
69 | 'groupbyType': 1,
70 | 'groupbyNum': 2001})
71 | ]
72 | )
73 | def test_sign_params_toolong(self, _, data_params):
74 | '''验证报名各字段字符超长'''
75 | uri = '/bentley/api/applyForTcjAsyn/'
76 | response = requests.post(self.url + uri, data=data_params, headers=self.headers)
77 | LOG.info('请求{0},参数{1},状态{2},\n 响应数据{3}'.format(uri, data_params, response, response.text))
78 | self.assertEqual(response.status_code, 200, '断言响应结果为200')
79 | self.assertEqual(response.json()['code'], 100001, '断言结果为100001')
80 | self.assertEqual(response.json()['msg'], '参数异常', '断言参数异常')
81 |
82 | @unittest.skip('pass')
83 | def test_sign(self):
84 | '''验证正常参数报名'''
85 | uri = '/bentley/api/applyForTcjAsyn/'
86 | data_params = {'name': 'linlang66', 'phone': '15633996699','cityId': 10, 'carStyleId': 32,
87 | 'brandId': 67, 'groupbyType': 1,'groupbyNum': 2001}
88 | response = requests.post(self.url + uri, data=data_params, headers=self.headers)
89 | LOG.info('请求{0},参数{1},状态{2},\n 响应数据{3}'.format(uri, data_params, response, response.text))
90 | self.assertEqual(response.status_code, 200, '断言响应结果为200')
91 | self.assertEqual(response.json()['code'], 100000, '断言结果为100000')
92 |
93 | @unittest.skip('pass')
94 | def test_signed(self):
95 | '''验证已经报名过重复报名'''
96 | uri = '/bentley/api/applyForTcjAsyn/'
97 | data_params = {'name': 'linlang66', 'phone': '15633996699','cityId': 10, 'carStyleId': 32,
98 | 'brandId': 67, 'groupbyType': 1,'groupbyNum': 2001}
99 | response = requests.post(self.url + uri, data=data_params, headers=self.headers)
100 | LOG.info('请求{0},参数{1},状态{2},\n 响应数据{3}'.format(uri, data_params, response, response.text))
101 | self.assertEqual(response.status_code, 200, '断言响应结果为200')
102 | self.assertEqual(response.json()['code'], 100000, '断言结果为100000')
103 |
104 | def tearDown(self):
105 | pass
106 | if __name__ == '__main__':
107 | unittest.main()
108 |
109 |
--------------------------------------------------------------------------------
/common/__init__.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 | """
5 | @author: liuyu
6 | @file: __init__
7 | @time: 2018/8/27
8 | """
--------------------------------------------------------------------------------
/common/get_base_parms.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 | """
5 | @version: 1.0
6 | @author: liuyu
7 | @license: None
8 | @file: get_base_parms.py
9 | @time: 17-4-13 下午12:18
10 | """
11 | from lib.MySQL import ConnMysql
12 | from common.get_token import get_token
13 | import random
14 | import execjs
15 |
16 |
17 | def get_user_agent(agent):
18 | chrome = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
19 | firefox = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0'
20 | webkit = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0'
21 | if agent == 'chrome':
22 | return chrome
23 | elif agent == 'firefox':
24 | return firefox
25 | elif agent == 'webkit':
26 | return webkit
27 |
28 |
29 | def get_js_method(**kwargs):
30 | jsstr = get_js()
31 | ctx = execjs.compile(jsstr)
32 | return (ctx.call('strEnc', kwargs))
33 |
34 |
35 | def get_js(js_path):
36 | f = open(js_path, 'r', encoding='utf-8')
37 | line = f.readline()
38 | htmlstr = ''
39 | while line:
40 | htmlstr = htmlstr + line
41 | line = f.readline()
42 | return htmlstr
43 |
44 |
45 | if __name__ == '__main__':
46 | print(get_des_psswd('123456', 'RUY2OTdCRUFFRTg0OUQ0Q0E0ODNDRDMxN0YzOEEzREQudG9tY2F0OTQ='))
47 |
--------------------------------------------------------------------------------
/common/get_token.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 | """
5 | @version: 1.0
6 | @author: liuyu
7 | @license: None
8 | @file: get_token.py
9 | @time: 17-4-13 下午12:17
10 | """
11 | import requests
12 |
13 |
14 | def get_token():
15 | data = {
16 | "username": "yyhdggtest000",
17 | "password": "9628FFAECF05013841852CB572D50D45",
18 | "type": "username",
19 | "device": {
20 | "mac": "unknown",
21 | "fingerprint": "Xiaomi/kenzo/kenzo:6.0.1/MMB29M/V8.2.1.0.MHOCNDL:user/release-keys",
22 | "model": "Redmi Note 3",
23 | "product": "kenzo",
24 | "vendor": "Xiaomi",
25 | "sdk": 23,
26 | "widthPixels": 1080,
27 | "heightPixels": 1920,
28 | "density": 480,
29 | "currentAndroidId": "1b8d2c5ea5c93c11",
30 | "firstAndroidId": "unknown",
31 | "firstBoot": 1491357039345,
32 | "firstImei": "unknown",
33 | "hasWeChat": "true",
34 | "hasqq": "true",
35 | "language": "zh",
36 | "country": "CN",
37 | "cpu": {
38 | "cpuimplementer": "0x41",
39 | "cpuarchitecture": "8",
40 | "cpurevision": "4",
41 | "revision": "4",
42 | "processorcnt": "5",
43 | "hardware": "Qualcomm Technologies, Inc MSM8956",
44 | "cpuvariant": "0x0",
45 | "features": "fp asimd evtstrm aes pmull sha1 sha2 crc32 wp half thumb fastmult vfp edsp neon vfpv3 tlsi vfpv4 idiva idivt",
46 | "cpupart": "0xd03"
47 | },
48 | "prop": {
49 | "ro.product.brand": "Xiaomi",
50 | "ro.product.name": "kenzo",
51 | "ro.product.model": "Redmi Note 3",
52 | "ro.build.fingerprint": "Xiaomi/kenzo/kenzo:6.0.1/MMB29M/V8.2.1.0.MHOCNDL:user/release-keys",
53 | "ro.build.version.sdk": "23",
54 | "ro.build.version.release": "6.0.1",
55 | "ro.build.date": "Tue Feb 14 20:19:12 CST 2017",
56 | "ro.build.date.utc": "1487074752",
57 | "ro.boot.cpuid": "",
58 | "ro.btconfig.vendor": "",
59 | "persist.sys.timezone": "Asia/Shanghai",
60 | "persist.sys.country": "",
61 | "persist.sys.language": "",
62 | "persist.sys.dalvik.vm.lib": "",
63 | "ro.build.description": "kenzo-user 6.0.1 MMB29M V8.2.1.0.MHOCNDL release-keys",
64 | "ro.runtime.firstboot": "1491357039345",
65 | "ro.serialno": "acccbe9c",
66 | "ro.product.device": "kenzo",
67 | "ro.kernel.qemu": "",
68 | "ro.hardware": "qcom",
69 | "ro.product.cpu.abi": "arm64-v8a"
70 | },
71 | "gpuVendor": "Adreno (TM) 510",
72 | "imei": "861735031851214",
73 | "connectionType": "WiFi",
74 | "carrier": "Unknown"
75 | },
76 | "caller": {
77 | "id": "ggclient",
78 | "sf": "A052F5F784A80A2A9B3AE97339C2C9C5",
79 | "rsa": "F08C552DA28E99672ACACFA7039F3560",
80 | "mf": "08D2F61DAD464B916FBFA11ADCC550A0",
81 | "regId": "D/sj08XtOhp/xqO61JeJ6rgt2bNqMfk47FJ2rNwdee8=",
82 | "pkgName": "com.iplay.assistant",
83 | "channel": "B1",
84 | "verCode": 417,
85 | "token": ""
86 | },
87 | "token": "",
88 | "reqTime": 1491470331215
89 | }
90 | response = requests.post('https://bbs.ggzhushou.cn:444/login', json=data)
91 | return response.json()["data"]["token"]
92 |
93 |
94 | if __name__ == '__main__':
95 | print(get_token())
96 |
--------------------------------------------------------------------------------
/common/sign_up.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 | """
5 | @author: liuyu
6 | @file: sign_up
7 | @time: 2018/9/3
8 | """
9 |
10 |
--------------------------------------------------------------------------------
/config/DB_config.ini:
--------------------------------------------------------------------------------
1 | [mysql_conf]
2 | host = 172.16.5.100
3 | port = 3306
4 | username = testuser
5 | password = hegXoWF0Gs
6 | [redis_conf]
7 |
8 |
--------------------------------------------------------------------------------
/config/UrlConf.ini:
--------------------------------------------------------------------------------
1 | [bj_tuanche]
2 | url = http://bj.tuanche.com
3 |
--------------------------------------------------------------------------------
/config/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linlang781/auto_api_test/093f2c95aaa86551d8a4873031b3f8bb897217ee/config/__init__.py
--------------------------------------------------------------------------------
/config/__init__.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linlang781/auto_api_test/093f2c95aaa86551d8a4873031b3f8bb897217ee/config/__init__.pyc
--------------------------------------------------------------------------------
/config/__pycache__/__init__.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linlang781/auto_api_test/093f2c95aaa86551d8a4873031b3f8bb897217ee/config/__pycache__/__init__.cpython-35.pyc
--------------------------------------------------------------------------------
/config/__pycache__/__init__.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linlang781/auto_api_test/093f2c95aaa86551d8a4873031b3f8bb897217ee/config/__pycache__/__init__.cpython-36.pyc
--------------------------------------------------------------------------------
/config/global.ini:
--------------------------------------------------------------------------------
1 | [report_conf]
2 | title =
3 | content =
4 | [email_base]
5 | username = yu.liu03011@tuanche.com
6 | passwd = A
7 | smtp = smtp.exmail.qq.com
8 | [email_send]
9 | to_list = yu.liu03011@tuanche.com;15601128781@163.com
10 | cc_list = yu.liu03011@tuanche.com
11 |
12 |
--------------------------------------------------------------------------------
/doc/changelog.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linlang781/auto_api_test/093f2c95aaa86551d8a4873031b3f8bb897217ee/doc/changelog.txt
--------------------------------------------------------------------------------
/doc/jenkins持续集成说明.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linlang781/auto_api_test/093f2c95aaa86551d8a4873031b3f8bb897217ee/doc/jenkins持续集成说明.docx
--------------------------------------------------------------------------------
/doc/接口自动化测试框架环境搭建说明.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linlang781/auto_api_test/093f2c95aaa86551d8a4873031b3f8bb897217ee/doc/接口自动化测试框架环境搭建说明.docx
--------------------------------------------------------------------------------
/doc/接口自动化测试框架说明.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linlang781/auto_api_test/093f2c95aaa86551d8a4873031b3f8bb897217ee/doc/接口自动化测试框架说明.docx
--------------------------------------------------------------------------------
/lib/Assertion.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # encoding: utf-8
3 |
4 | """
5 | @author: liuyu
6 | @file: Assertion
7 | @time: 2018/8/27
8 | """
9 |
10 |
11 | def res(d, code):
12 | result = []
13 | if isinstance(d, dict) and code in d.keys():
14 | value = d[code]
15 | result.append(value)
16 | return result
17 | elif isinstance(d, (list, tuple)):
18 | for item in d:
19 | value = res(item, code)
20 | if value == "None" or value is None:
21 | pass
22 | elif len(value) == 0:
23 | pass
24 | else:
25 | result.append(value)
26 | return result
27 | else:
28 | if isinstance(d, dict):
29 | for k in d:
30 | value = res(d[k], code)
31 | if value == "None" or value is None:
32 | pass
33 | elif len(value) == 0:
34 | pass
35 | else:
36 | for item in value:
37 | result.append(item)
38 | return result
39 |
40 |
41 | def assert_in(asserqiwang, fanhuijson):
42 | if len(asserqiwang.split('=')) > 1:
43 | data = asserqiwang.split('&')
44 | result = dict([(item.split('=')) for item in data])
45 | value1 = ([(str(res(fanhuijson, key))) for key in result.keys()])
46 | value2 = ([(str(value)) for value in result.values()])
47 | if value1 == value2:
48 | return {'code': 0, "result": 'pass'}
49 | else:
50 | return {'code': 1, 'result': 'fail'}
51 | else:
52 | return {"code": 2, 'result': '填写测试预期值'}
53 |
54 |
55 | def assertre(asserqingwang):
56 | if len(asserqingwang.split('=')) > 1:
57 | data = asserqingwang.split('&')
58 | result = dict([(item.split('=')) for item in data])
59 | return result
60 | else:
61 | raise {"code": 1, 'result': '填写测试预期值'}
62 |
--------------------------------------------------------------------------------
/lib/BSTestRunner.py:
--------------------------------------------------------------------------------
1 | """
2 | A TestRunner for use with the Python unit testing framework. It generates a HTML report to show the result at a glance.
3 | The simplest way to use this is to invoke its main method. E.g.
4 |
5 | import unittest
6 | import BSTestRunner
7 |
8 | ... define your tests ...
9 |
10 | if __name__ == '__main__':
11 | BSTestRunner.main()
12 |
13 |
14 | For more customization options, instantiates a BSTestRunner object.
15 | BSTestRunner is a counterpart to unittest's TextTestRunner. E.g.
16 |
17 | # output to a file
18 | fp = file('my_report.html', 'wb')
19 | runner = BSTestRunner.BSTestRunner(
20 | stream=fp,
21 | title='My unit test',
22 | description='This demonstrates the report output by BSTestRunner.'
23 | )
24 |
25 | # Use an external stylesheet.
26 | # See the Template_mixin class for more customizable options
27 | runner.STYLESHEET_TMPL = ''
28 |
29 | # run the test
30 | runner.run(my_test_suite)
31 |
32 |
33 | ------------------------------------------------------------------------
34 | Copyright (c) 2004-2007, Wai Yip Tung
35 | Copyright (c) 2016, Eason Han
36 | All rights reserved.
37 |
38 | Redistribution and use in source and binary forms, with or without
39 | modification, are permitted provided that the following conditions are
40 | met:
41 |
42 | * Redistributions of source code must retain the above copyright notice,
43 | this list of conditions and the following disclaimer.
44 | * Redistributions in binary form must reproduce the above copyright
45 | notice, this list of conditions and the following disclaimer in the
46 | documentation and/or other materials provided with the distribution.
47 | * Neither the name Wai Yip Tung nor the names of its contributors may be
48 | used to endorse or promote products derived from this software without
49 | specific prior written permission.
50 |
51 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
52 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
53 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
54 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
55 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
58 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
59 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
60 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 | """
63 |
64 | __author__ = "Wai Yip Tung && Eason Han"
65 | __version__ = "0.8.4"
66 |
67 | """
68 | Change History
69 |
70 | Version 0.8.3
71 | * Modify html style using bootstrap3.
72 |
73 | Version 0.8.3
74 | * Prevent crash on class or module-level exceptions (Darren Wurf).
75 |
76 | Version 0.8.2
77 | * Show output inline instead of popup window (Viorel Lupu).
78 |
79 | Version in 0.8.1
80 | * Validated XHTML (Wolfgang Borgert).
81 | * Added description of test classes and test cases.
82 |
83 | Version in 0.8.0
84 | * Define Template_mixin class for customization.
85 | * Workaround a IE 6 bug that it does not treat
215 |
216 |
217 |
218 |
219 |
313 |
314 |
315 | %(heading)s
316 | %(report)s
317 | %(ending)s
318 |
319 |
320 |
321 |