├── .idea
├── .name
├── encodings.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── misc.xml
├── modules.xml
├── monkey_test.iml
├── scopes
│ └── scope_settings.xml
├── vcs.xml
└── workspace.xml
├── Base
├── AdbCommon.py
├── BaseAnalysis.py
├── BaseCashEmnu.py
├── BaseFile.py
├── BaseMonitor.py
├── BaseMonkeyConfig.py
├── BasePhoneMsg.py
├── BasePickle.py
├── BaseReport.py
├── BaseWriteReport.py
├── Cprint.py
├── OperateFile.py
├── __init__.py
└── __pycache__
│ ├── AdbCommon.cpython-34.pyc
│ ├── BaseAnalysis.cpython-34.pyc
│ ├── BaseCashEmnu.cpython-34.pyc
│ ├── BaseFile.cpython-34.pyc
│ ├── BaseMonitor.cpython-34.pyc
│ ├── BaseMonkeyConfig.cpython-34.pyc
│ ├── BasePhoneMsg.cpython-34.pyc
│ ├── BasePickle.cpython-34.pyc
│ ├── BaseReport.cpython-34.pyc
│ ├── BaseWriteReport.cpython-34.pyc
│ ├── Cprint.cpython-34.pyc
│ ├── OperateFile.cpython-34.pyc
│ └── __init__.cpython-34.pyc
├── Chinese.md
├── MainActivity.java
├── README.md
├── img
├── analysis.jpg
├── crash.PNG
└── monitor.png
├── info
├── DU2TAN15AJ049163_battery.pickle
├── DU2TAN15AJ049163_cpu.pickle
├── DU2TAN15AJ049163_flow.pickle
├── DU2TAN15AJ049163_fps.pickle
├── DU2TAN15AJ049163_men.pickle
├── info.pickle
└── sumInfo.pickle
├── kill5037.bat
├── log
├── adece0c8-1f61-4cae-8ed4-e8db510de83dlogcat.log
├── adece0c8-1f61-4cae-8ed4-e8db510de83dmonkey.log
└── adece0c8-1f61-4cae-8ed4-e8db510de83dtraces.log
├── monkey.ini
├── monkey1.apk
├── monkeyTest.py
└── report.xlsx
/.idea/.name:
--------------------------------------------------------------------------------
1 | monkey_test
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/monkey_test.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/scopes/scope_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.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 | sum
133 | k
134 | ----
135 | fps
136 | _maxFlow
137 | 93
138 | 117
139 | result
140 | -----flow---------
141 | flow
142 | cpu
143 | maxCpu
144 | men
145 | mkdirInit
146 | 读取文件错误
147 |
148 |
149 | data
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 | true
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 | Python
227 |
228 |
229 |
230 |
231 | PyArgumentListInspection
232 |
233 |
234 |
235 |
236 |
237 |
238 |
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 |
300 |
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 |
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 | 1442816524593
587 |
588 |
589 | 1442816524593
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 |
689 |
690 |
691 |
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 |
--------------------------------------------------------------------------------
/Base/AdbCommon.py:
--------------------------------------------------------------------------------
1 | # python module for interacting with adb
2 | import os
3 |
4 | '''
5 | 基本的adb操作
6 | '''
7 | class AndroidDebugBridge(object):
8 | def call_adb(self, command):
9 | command_result = ''
10 | command_text = 'adb %s' % command
11 | print(command_text)
12 | results = os.popen(command_text, "r")
13 | while 1:
14 | line = results.readline()
15 | if not line: break
16 | command_result += line
17 | results.close()
18 | return command_result
19 |
20 | # check for any fastboot device
21 | def fastboot(self, device_id):
22 | pass
23 |
24 | # 检查设备
25 | def attached_devices(self):
26 | result = self.call_adb("devices")
27 | devices = result.partition('\n')[2].replace('\n', '').split('\tdevice')
28 | return [device for device in devices if len(device) > 2]
29 | # 状态
30 | def get_state(self):
31 | result = self.call_adb("get-state")
32 | result = result.strip(' \t\n\r')
33 | return result or None
34 | #重启
35 | def reboot(self, option):
36 | command = "reboot"
37 | if len(option) > 7 and option in ("bootloader", "recovery",):
38 | command = "%s %s" % (command, option.strip())
39 | self.call_adb(command)
40 |
41 | # 将电脑文件拷贝到手机里面
42 | def push(self, local, remote):
43 | result = self.call_adb("push %s %s" % (local, remote))
44 | return result
45 |
46 | # 拉数据到本地
47 | def pull(self, remote, local):
48 | result = self.call_adb("pull %s %s" % (remote, local))
49 | return result
50 | # 同步更新 很少用此命名
51 | def sync(self, directory, **kwargs):
52 | command = "sync %s" % directory
53 | if 'list' in kwargs:
54 | command += " -l"
55 | result = self.call_adb(command)
56 | return result
57 |
58 | # 打开指定app
59 | def open_app(self,packagename,activity,devices):
60 | result = self.call_adb("-s "+ devices+" shell am start -n %s/%s" % (packagename, activity))
61 | check = result.partition('\n')[2].replace('\n', '').split('\t ')
62 | if check[0].find("Error") >= 1:
63 | return False
64 | else:
65 | return True
66 |
67 | # 根据包名得到进程id
68 | def get_app_pid(self, pkg_name):
69 | string = self.call_adb("shell ps | grep "+pkg_name)
70 | # print(string)
71 | if string == '':
72 | return "the process doesn't exist."
73 | result = string.split(" ")
74 | # print(result[4])
75 | return result[4]
76 |
77 | if __name__ == '__main__':
78 |
79 | reuslt = AndroidDebugBridge().attached_devices()
80 | for info in reuslt:
81 |
82 | print(info)
83 |
--------------------------------------------------------------------------------
/Base/BaseAnalysis.py:
--------------------------------------------------------------------------------
1 | import math
2 |
3 |
4 | # total 是rom容量
5 | def avgMen(men, total):
6 | if len(men):
7 | _men = [math.ceil(((men[i]) / total) * 1024) for i in range(len(men))]
8 | print(_men)
9 | return str(math.ceil(sum(_men) / len(_men))) + "M"
10 | return "0"
11 |
12 |
13 | def avgCpu(cpu):
14 | if len(cpu):
15 | resutl = "%.1f" % (sum(cpu) / len(cpu))
16 | return str(math.ceil(float(resutl)*10)) + "%"
17 | return "0%"
18 |
19 |
20 | def avgFps(fps):
21 | if len(fps):
22 | return '%.2f' % float(str(math.ceil(sum(fps) / len(fps))))
23 | return 0.00
24 |
25 |
26 | def maxMen(men):
27 | if len(men):
28 | print("men=" + str(men))
29 | return str(math.ceil((max(men)) / 1024)) + "M"
30 | return "0M"
31 |
32 |
33 | def maxCpu(cpu):
34 | print("maxCpu="+str(cpu))
35 | if len(cpu):
36 | result = "%.1f" % max(cpu)
37 | return str(math.ceil(float(result)*10)) + "%"
38 | return "0%"
39 |
40 |
41 | def maxFps(fps):
42 | return str(max(fps))
43 |
44 |
45 | def maxFlow(flow):
46 | print("---maxFlow111----------")
47 | print(flow)
48 | _flowUp = []
49 | _flowDown = []
50 | for i in range(len(flow[0])):
51 | if i + 1 == len(flow[0]):
52 | break
53 | _flowUp.append(math.ceil((flow[0][i + 1] - flow[0][i]) / 1024))
54 | print("---maxFlow2222---------")
55 | print(_flowUp)
56 | for i in range(len(flow[1])):
57 | if i + 1 == len(flow[1]):
58 | break
59 | _flowDown.append(math.ceil((flow[1][i + 1] - flow[1][i]) / 1024))
60 | print("---maxFlow3333---------")
61 | print(_flowDown)
62 | if _flowUp:
63 | maxFpsUp = str(max(_flowUp)) + "KB" # 上行流量
64 | else:
65 | maxFpsUp = "0"
66 | if _flowDown:
67 | maxFpsDown = str(max(_flowDown)) + "KB" # 下行流量
68 | else:
69 | maxFpsDown = "0"
70 | return maxFpsUp, maxFpsDown
71 |
72 | def avgFlow(flow):
73 | _flowUp = []
74 | _flowDown = []
75 | for i in range(len(flow[0])):
76 | if i + 1 == len(flow[0]):
77 | break
78 | _flowUp.append((flow[0][i + 1] - flow[0][i])/1024)
79 |
80 | for i in range(len(flow[1])):
81 | if i + 1 == len(flow[1]):
82 | break
83 | _flowDown.append((flow[1][i + 1] - flow[1][i])/1024)
84 | avgFpsUp = str(math.ceil(sum(_flowUp) / len(_flowUp))) + "KB"
85 | avgFpsDown = str(math.ceil(sum(_flowDown) / len(_flowDown))) + "KB"
86 | return avgFpsUp, avgFpsDown
87 |
88 | if __name__ == '__main__':
89 | flow = [[93919172, 94987124, 96309507], [14250800, 14285269, 14331153]]
90 | cpu = [1.9164759725400458, 0.40045766590389015, 0.8493771234428086, 1.8407534246575343]
91 | men = [310171, 323267, 321179, 317913, 316569, 335277, 323853, 315837, 333765, 333829, 337433, 337473, 339877, 328953, 328881, 328909, 334029, 329873, 334645, 338649, 332541, 329273, 333581]
92 |
93 | print(avgMen(men, 3014000))
94 | # print(maxFlow(flow))
95 |
--------------------------------------------------------------------------------
/Base/BaseCashEmnu.py:
--------------------------------------------------------------------------------
1 | __author__ = 'Administrator'
2 |
3 | ANR = "ANR"
4 | I_ANR = 0
5 | CRASH = "CRASH"
6 | I_CRASH = 0
7 | EXCEPTION = "Exception"
8 | I_EXCEPTION = 0
9 |
10 | # finish实际已经测试完设备个数
11 | # devices 测试设备个数
12 | info = []
13 | finish = 0
14 |
--------------------------------------------------------------------------------
/Base/BaseFile.py:
--------------------------------------------------------------------------------
1 | __author__ = 'shikun'
2 | import os
3 |
4 | '''
5 | 操作文件
6 | '''
7 | class OperateFile:
8 | #method(r,w,a)
9 | def __init__(self, file, method='w+'):
10 | self.file = file
11 | self.method = method
12 | self.fileHandle = None
13 |
14 | def write_txt(self, line):
15 | OperateFile(self.file).check_file()
16 | self.fileHandle = open(self.file, self.method)
17 | self.fileHandle.write(line + "\n")
18 | self.fileHandle.close()
19 |
20 | def read_txt_row(self):
21 | resutl = ""
22 | if OperateFile(self.file).check_file():
23 | self.fileHandle = open(self.file, self.method)
24 | resutl = self.fileHandle.readline()
25 | self.fileHandle.close()
26 | return resutl
27 |
28 | def read_txt_rows(self):
29 | if OperateFile(self.file).check_file():
30 | self.fileHandle = open(self.file, self.method)
31 | file_list = self.fileHandle.readlines()
32 | for i in file_list:
33 | print(i.strip("\n"))
34 | self.fileHandle.close()
35 | def check_file(self):
36 | if not os.path.isfile(self.file):
37 | # print('文件不存在' + self.file)
38 | # sys.exit()
39 | return False
40 | else:
41 | return True
42 | # print("文件存在!")
43 |
44 | def mkdir_file(self):
45 | if not os.path.isfile(self.file):
46 | f = open(self.file, self.method)
47 | f.close()
48 | print("创建文件成功")
49 | else:
50 | print("文件已经存在")
51 | def remove_file(self):
52 | if os.path.isfile(self.file):
53 | os.remove(self.file)
54 | print("删除文件成功")
55 | else:
56 | print("文件不存在")
57 | # if __name__ == '__main__':
58 | # bf = OperateFile("text.xml")
59 | # if bf.check_file() == False:
60 | # bf.mkdir_file()
61 | # bf.write_txt("111")
--------------------------------------------------------------------------------
/Base/BaseMonitor.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | import os
3 | import re
4 | from wsgiref.validate import validator
5 | import time
6 | from Base.BasePickle import *
7 | PATH = lambda p: os.path.abspath(
8 | os.path.join(os.path.dirname(__file__), p)
9 | )
10 |
11 |
12 |
13 |
14 | def get_men(pkg_name, devices):
15 | try:
16 | cmd = "adb -s " + devices +" shell dumpsys meminfo %s" % (pkg_name)
17 | print(cmd)
18 | output = subprocess.check_output(cmd).split()
19 | # print(output)
20 | s_men = ".".join([x.decode() for x in output]) # 转换为string
21 | print(s_men)
22 | men2 = int(re.findall("TOTAL.(\d+)*", s_men, re.S)[0])
23 | except:
24 | men2 = 0
25 | writeInfo(men2, PATH("../info/" + devices + "_men.pickle"))
26 | return men2
27 | # men_s = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.readlines()
28 | # for info in men_s:
29 | # if len(info.split()) and info.split()[0].decode() == "TOTAL":
30 | # # print("men="+info.split()[1].decode())
31 | # men.append(int(info.split()[1].decode()))
32 | # # writeInfo(int(info.split()[1].decode()), PATH("../info/" + devices + "_men.pickle"))
33 | # print("----men----")
34 | # print(men)
35 | # return men
36 |
37 |
38 | # 得到fps
39 | '''
40 | @author fenfenzhong
41 | '''
42 |
43 |
44 | def get_fps(pkg_name, devices):
45 | _adb = "adb -s " + devices +" shell dumpsys gfxinfo %s" % pkg_name
46 | print(_adb)
47 | results = os.popen(_adb).read().strip()
48 | frames = [x for x in results.split('\n') if validator(x)]
49 | frame_count = len(frames)
50 | jank_count = 0
51 | vsync_overtime = 0
52 | render_time = 0
53 | for frame in frames:
54 | time_block = re.split(r'\s+', frame.strip())
55 | if len(time_block) == 3:
56 | try:
57 | render_time = float(time_block[0]) + float(time_block[1]) + float(time_block[2])
58 | except Exception as e:
59 | render_time = 0
60 |
61 | '''
62 | 当渲染时间大于16.67,按照垂直同步机制,该帧就已经渲染超时
63 | 那么,如果它正好是16.67的整数倍,比如66.68,则它花费了4个垂直同步脉冲,减去本身需要一个,则超时3个
64 | 如果它不是16.67的整数倍,比如67,那么它花费的垂直同步脉冲应向上取整,即5个,减去本身需要一个,即超时4个,可直接算向下取整
65 |
66 | 最后的计算方法思路:
67 | 执行一次命令,总共收集到了m帧(理想情况下m=128),但是这m帧里面有些帧渲染超过了16.67毫秒,算一次jank,一旦jank,
68 | 需要用掉额外的垂直同步脉冲。其他的就算没有超过16.67,也按一个脉冲时间来算(理想情况下,一个脉冲就可以渲染完一帧)
69 |
70 | 所以FPS的算法可以变为:
71 | m / (m + 额外的垂直同步脉冲) * 60
72 | '''
73 | if render_time > 16.67:
74 | jank_count += 1
75 | if render_time % 16.67 == 0:
76 | vsync_overtime += int(render_time / 16.67) - 1
77 | else:
78 | vsync_overtime += int(render_time / 16.67)
79 |
80 | _fps = int(frame_count * 60 / (frame_count + vsync_overtime))
81 | writeInfo(_fps, PATH("../info/" + devices + "_fps.pickle"))
82 |
83 | # return (frame_count, jank_count, fps)
84 | print("-----fps------")
85 | print(_fps)
86 |
87 |
88 | def get_battery(devices):
89 | try:
90 | cmd = "adb -s " + devices + " shell dumpsys battery"
91 | print(cmd)
92 | output = subprocess.check_output(cmd).split()
93 | # _batter = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
94 | # stderr=subprocess.PIPE).stdout.readlines()
95 | st = ".".join([x.decode() for x in output]) # 转换为string
96 | print(st)
97 | battery2 = int(re.findall("level:.(\d+)*", st, re.S)[0])
98 |
99 | except:
100 | battery2 = 90
101 | writeInfo(battery2, PATH("../info/" + devices + "_battery.pickle"))
102 |
103 | return battery2
104 |
105 |
106 |
107 | def get_pid(pkg_name, devices):
108 | cmd = "adb -s " + devices + " shell ps | findstr " + pkg_name
109 | print("----get_pid-------")
110 | print(cmd)
111 | pid = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
112 | stderr=subprocess.PIPE).stdout.readlines()
113 | for item in pid:
114 | if item.split()[8].decode() == pkg_name:
115 | return item.split()[1].decode()
116 |
117 |
118 | def get_flow(pid, type, devices):
119 | # pid = get_pid(pkg_name)
120 | upflow = downflow = 0
121 | if pid is not None:
122 | cmd = "adb -s " + devices + " shell cat /proc/" + pid + "/net/dev"
123 | print(cmd)
124 | _flow = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
125 | stderr=subprocess.PIPE).stdout.readlines()
126 | for item in _flow:
127 | if type == "wifi" and item.split()[0].decode() == "wlan0:": # wifi
128 | # 0 上传流量,1 下载流量
129 | upflow = int(item.split()[1].decode())
130 | downflow = int(item.split()[9].decode())
131 | print("------flow---------")
132 | print(upflow)
133 | break
134 | if type == "gprs" and item.split()[0].decode() == "rmnet0:": # gprs
135 | print("-----flow---------")
136 | upflow = int(item.split()[1].decode())
137 | downflow = int(item.split()[9].decode())
138 | print(upflow)
139 | break
140 |
141 | writeFlowInfo(upflow, downflow, PATH("../info/" + devices + "_flow.pickle"))
142 |
143 | '''
144 | 每一个cpu快照均
145 | '''
146 | def totalCpuTime(devices):
147 | user=nice=system=idle=iowait=irq=softirq= 0
148 | '''
149 | user:从系统启动开始累计到当前时刻,处于用户态的运行时间,不包含 nice值为负进程。
150 | nice:从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间
151 | system 从系统启动开始累计到当前时刻,处于核心态的运行时间
152 | idle 从系统启动开始累计到当前时刻,除IO等待时间以外的其它等待时间
153 | iowait 从系统启动开始累计到当前时刻,IO等待时间(since 2.5.41)
154 | irq 从系统启动开始累计到当前时刻,硬中断时间(since 2.6.0-test4)
155 | softirq 从系统启动开始累计到当前时刻,软中断时间(since 2.6.0-test4)
156 | stealstolen 这是时间花在其他的操作系统在虚拟环境中运行时(since 2.6.11)
157 | guest 这是运行时间guest 用户Linux内核的操作系统的控制下的一个虚拟CPU(since 2.6.24)
158 | '''
159 |
160 | cmd = "adb -s " + devices +" shell cat /proc/stat"
161 | print(cmd)
162 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
163 | stderr=subprocess.PIPE,
164 | stdin=subprocess.PIPE, shell=True)
165 | (output, err) = p.communicate()
166 | res = output.split()
167 |
168 | for info in res:
169 | if info.decode() == "cpu":
170 | user = res[1].decode()
171 | nice = res[2].decode()
172 | system = res[3].decode()
173 | idle = res[4].decode()
174 | iowait = res[5].decode()
175 | irq = res[6].decode()
176 | softirq = res[7].decode()
177 | print("user=" + user)
178 | print("nice=" + nice)
179 | print("system=" + system)
180 | print("idle=" + idle)
181 | print("iowait=" + iowait)
182 | print("irq=" + irq)
183 | print("softirq=" + softirq)
184 | result = int(user) + int(nice) + int(system) + int(idle) + int(iowait) + int(irq) + int(softirq)
185 | print("totalCpuTime"+str(result))
186 | return result
187 |
188 |
189 |
190 | '''
191 | 每一个进程快照
192 | '''
193 | def processCpuTime(pid, devices):
194 | '''
195 |
196 | pid 进程号
197 | utime 该任务在用户态运行的时间,单位为jiffies
198 | stime 该任务在核心态运行的时间,单位为jiffies
199 | cutime 所有已死线程在用户态运行的时间,单位为jiffies
200 | cstime 所有已死在核心态运行的时间,单位为jiffies
201 | '''
202 | utime=stime=cutime=cstime = 0
203 | try:
204 | cmd = "adb -s "+ devices + " shell cat /proc/" + pid +"/stat"
205 | print(cmd)
206 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
207 | stderr=subprocess.PIPE,
208 | stdin=subprocess.PIPE, shell=True)
209 | (output, err) = p.communicate()
210 | res = output.split()
211 |
212 | utime = res[13].decode()
213 | stime = res[14].decode()
214 | cutime = res[15].decode()
215 | cstime = res[16].decode()
216 | print("utime="+utime)
217 | print("stime="+stime)
218 | print("cutime="+cutime)
219 | print("cstime="+cstime)
220 | result = int(utime) + int(stime) + int(cutime) + int(cstime)
221 | print("processCpuTime="+str(result))
222 | except :
223 | result = 0
224 | return result
225 |
226 | # 得到几核cpu
227 | def get_cpu_kel(devices):
228 | cmd = "adb -s " + devices + " shell cat /proc/cpuinfo"
229 | print(cmd)
230 | output = subprocess.check_output(cmd).split()
231 | sitem = ".".join([x.decode() for x in output]) # 转换为string
232 | return len(re.findall("processor", sitem))
233 |
234 | '''
235 | 计算某进程的cpu使用率
236 | 100*( processCpuTime2 – processCpuTime1) / (totalCpuTime2 – totalCpuTime1) (按100%计算,如果是多核情况下还需乘以cpu的个数);
237 | cpukel cpu几核
238 | pid 进程id
239 | '''
240 | def cpu_rate(pid, cpukel, devices):
241 | # pid = get_pid(pkg_name)
242 | processCpuTime1 = processCpuTime(pid, devices)
243 | time.sleep(1)
244 | processCpuTime2 = processCpuTime(pid, devices)
245 | processCpuTime3 = processCpuTime2 - processCpuTime1
246 |
247 | totalCpuTime1 = totalCpuTime(devices)
248 | time.sleep(1)
249 | totalCpuTime2 = totalCpuTime(devices)
250 | totalCpuTime3 = (totalCpuTime2 - totalCpuTime1)*cpukel
251 | print("totalCpuTime3="+str(totalCpuTime3))
252 | print("processCpuTime3="+str(processCpuTime3))
253 |
254 | cpu = 100 * (processCpuTime3) / (totalCpuTime3)
255 | writeInfo(cpu, PATH("../info/" + devices + "_cpu.pickle"))
256 | print("--------cpu--------")
257 | print(cpu)
258 | if __name__ == '__main__':
259 |
260 | # cpu_rate("2749")
261 | pid = get_pid("com.jianshu.haruki", "DU2TAN15AJ049163")
262 | # print(pid)
263 | # get_flow(pid, "wifi", "DU2TAN15AJ049163")
264 | # get_battery("DU2TAN15AJ049163")
265 | # get_men("com.jianshu.haruki", "DU2TAN15AJ049163")
266 | # print(get_cpu_kel())
267 | # cpu_kel = get_cpu_kel("DU2TAN15AJ049163")
268 | # print(cpu_rate(pid,cpu_kel,"DU2TAN15AJ049163"))
269 | get_flow(pid, "gprs", "emulator-5554")
270 | # print(get_flow("com.jianshu.haruki", "gprs"))
271 | # print(get_flow("com.jianshu.haruki", "gprs"))
272 | # print(get_flow("com.jianshu.haruki", "gprs"))
273 |
--------------------------------------------------------------------------------
/Base/BaseMonkeyConfig.py:
--------------------------------------------------------------------------------
1 | __author__ = 'Administrator'
2 | import configparser
3 | import time
4 | import os
5 | PATH = lambda p: os.path.abspath(
6 | os.path.join(os.path.dirname(__file__), p)
7 | )
8 |
9 | def monkeyConfig(init_file):
10 | config = configparser.ConfigParser()
11 | config.read(init_file)
12 | app = {}
13 | app["package_name"] = config['DEFAULT']['package_name']
14 | # app["activity"] = config['DEFAULT']['activity']
15 | app["net"] = config['DEFAULT']['net']
16 | app["cmd"] = config['DEFAULT']['cmd'] + ">"
17 | return app
18 |
--------------------------------------------------------------------------------
/Base/BasePhoneMsg.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import time
4 |
5 | __author__ = 'shikun'
6 | import re
7 | import subprocess
8 |
9 |
10 | def stop_monkey(dev):
11 | monkey_name = "com.android.commands.monkey"
12 | print("--------------------")
13 | pid = subprocess.Popen("adb -s " + dev + " shell ps | findstr " + monkey_name, shell=True, stdout=subprocess.PIPE,stderr=subprocess.PIPE).stdout.readlines()
14 | if pid =="":
15 | print("No monkey running in %s" % dev)
16 | else:
17 | for item in pid:
18 | if item.split()[8].decode() == monkey_name:
19 | monkey_pid = item.split()[1].decode()
20 | cmd_monkey = "adb -s " + dev + " shell kill %s" % (monkey_pid)
21 | os.popen(cmd_monkey)
22 | print("Monkey in %s was killed" % dev)
23 | time.sleep(2)
24 | subprocess.Popen("taskkill /f /t /im python.exe", shell=True)
25 |
26 | def reboot(dev):
27 | cmd_reboot = "adb -s " + dev + " reboot"
28 | os.popen(cmd_reboot)
29 |
30 | def getModel( devices):
31 | result = {}
32 | cmd = "adb -s " + devices + " shell cat /system/build.prop"
33 | print(cmd)
34 | # output = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.readlines()
35 | output = subprocess.check_output(cmd).decode()
36 | result["release"] = re.findall("version.release=(\d\.\d)*", output, re.S)[0] # Android 系统,如anroid 4.0
37 | result["phone_name"] = re.findall("ro.product.model=(\S+)*", output, re.S)[0] # 手机名
38 | result["phone_model"] = re.findall("ro.product.brand=(\S+)*", output, re.S)[0] # 手机品牌
39 | return result
40 |
41 |
42 | def get_men_total(devices):
43 | cmd = "adb -s " + devices + " shell cat /proc/meminfo"
44 | print(cmd)
45 | output = subprocess.check_output(cmd).split()
46 | # item = [x.decode() for x in output]
47 | return int(output[1].decode())
48 |
49 | # # 得到几核cpu
50 | def get_cpu_kel(devices):
51 | cmd = "adb -s " + devices +" shell cat /proc/cpuinfo"
52 | print(cmd)
53 | output = subprocess.check_output(cmd).split()
54 | sitem = ".".join([x.decode() for x in output]) # 转换为string
55 | return str(len(re.findall("processor", sitem))) + "核"
56 |
57 |
58 | # 得到手机分辨率
59 | def get_app_pix(devices):
60 | cmd = "adb -s " + devices + " shell wm size"
61 | print(cmd)
62 | return subprocess.check_output(cmd).split()[2].decode()
63 |
64 | #
65 | def get_phone_Kernel(devices):
66 | pix = get_app_pix(devices)
67 | men_total = get_men_total(devices)
68 | phone_msg = getModel(devices)
69 | cpu_sum = get_cpu_kel(devices)
70 | return phone_msg, men_total, cpu_sum, pix
71 | if __name__ == '__main__':
72 | # get_app_pix("emulator-5554")
73 | stop_monkey("DU2TAN15AJ049163")
--------------------------------------------------------------------------------
/Base/BasePickle.py:
--------------------------------------------------------------------------------
1 | __author__ = "shikun"
2 | import pickle
3 | import os
4 |
5 | PATH = lambda p: os.path.abspath(
6 | os.path.join(os.path.dirname(__file__), p)
7 | )
8 |
9 |
10 | def writeSum(init, data=None, path="data.pickle"):
11 | if init == 0:
12 | result = data
13 | else:
14 | _read = readInfo(path)
15 | result = _read - 1
16 |
17 | with open(path, 'wb') as f:
18 | print("------writeSum-------")
19 | print(result)
20 | pickle.dump(result, f)
21 |
22 |
23 | def readSum(path):
24 | data = {}
25 | with open(path, 'rb') as f:
26 | try:
27 | data = pickle.load(f)
28 | except EOFError:
29 | data = {}
30 | print("读取文件错误")
31 | print("------read-------")
32 | print(path)
33 | print(data)
34 | return data
35 |
36 |
37 | def readInfo(path):
38 | data = []
39 | with open(path, 'rb') as f:
40 | try:
41 | data = pickle.load(f)
42 | # print(data)
43 | except EOFError:
44 | data = []
45 | # print("读取文件错误")
46 | print("------read-------")
47 | print(path)
48 | print(data)
49 | return data
50 |
51 |
52 | def writeInfo(data, path="data.pickle"):
53 | _read = readInfo(path)
54 | result = []
55 | if _read:
56 | _read.append(data)
57 | result = _read
58 | else:
59 | result.append(data)
60 | with open(path, 'wb') as f:
61 | print("------writeInfo-------")
62 | print(result)
63 | pickle.dump(result, f)
64 |
65 | def writeFlowInfo(upflow, downflow, path="data.pickle"):
66 | print("---data-----")
67 | print("上行流量="+str(upflow))
68 | print("下行流量="+str(downflow))
69 |
70 | _read = readInfo(path)
71 | result = [[], []]
72 | if _read:
73 | _read[0].append(upflow)
74 | _read[1].append(downflow)
75 | result = _read
76 | else:
77 | result[0].append(upflow)
78 | result[1].append(downflow)
79 | with open(path, 'wb') as f:
80 | print("------writeFlowInfo-------")
81 | print(result)
82 | pickle.dump(result, f)
83 |
84 |
85 | if __name__ == "__main__":
86 | # readInfo(PATH("../info/DU2TAN15AJ049163_battery.pickle"))
87 | # readInfo(PATH("../info/emulator-5554_fps.pickle"))
88 | # readInfo(PATH("../info/emulator-5554_battery.pickle"))
89 | # readInfo(PATH("../info/emulator-5554_men.pickle"))
90 | # readInfo(PATH("../info/DU2TAN15AJ049163_men.pickle"))
91 | # readInfo(PATH("../info/emulator-5554_flow.pickle"))
92 | readInfo("E:\\app\\py\\monkey1\\info\\info.pickle")
93 | # readInfo(PATH("../info/DU2TAN15AJ049163_cpu.pickle"))
94 |
--------------------------------------------------------------------------------
/Base/BaseReport.py:
--------------------------------------------------------------------------------
1 | import math
2 | import re
3 |
4 | import xlsxwriter
5 |
6 | from Base import BaseAnalysis, BaseCashEmnu as go
7 | from Base.BasePickle import readInfo
8 |
9 |
10 | class OperateReport:
11 | def __init__(self, wd):
12 | self.wd = wd
13 | self._crashM = []
14 | # self.pie(self.wd, worksheet)
15 |
16 | def monitor(self, info):
17 | worksheet = self.wd.add_worksheet("Analysis")
18 | worksheet.set_column("A:A", 15)
19 | worksheet.set_column("B:B", 10)
20 | worksheet.set_column("C:C", 10)
21 | worksheet.set_column("D:D", 10)
22 | worksheet.set_column("E:E", 10)
23 | worksheet.set_column("F:F", 10)
24 | worksheet.set_column("G:G", 10)
25 | worksheet.set_column("H:H", 10)
26 | worksheet.set_column("I:I", 10)
27 | worksheet.set_column("J:J", 10)
28 | worksheet.set_column("K:K", 10)
29 | worksheet.set_column("L:L", 10)
30 | worksheet.set_column("L:L", 10)
31 | worksheet.set_column("M:M", 10)
32 | worksheet.set_column("N:N", 10)
33 | worksheet.set_column("O:O", 10)
34 | worksheet.set_column("P:P", 10)
35 | worksheet.set_column("Q:Q", 10)
36 | worksheet.set_column("R:R", 10)
37 |
38 | worksheet.set_row(1, 30)
39 | worksheet.set_row(2, 30)
40 | worksheet.set_row(3, 30)
41 | worksheet.set_row(4, 30)
42 | worksheet.set_row(5, 30)
43 | worksheet.set_row(6, 30)
44 | worksheet.set_row(7, 30)
45 | worksheet.set_row(8, 30)
46 | worksheet.set_row(9, 30)
47 | worksheet.set_row(10, 30)
48 | worksheet.set_row(11, 30)
49 | worksheet.set_row(12, 30)
50 |
51 | define_format_H1 = get_format(self.wd, {'bold': True, 'font_size': 18})
52 | define_format_H2 = get_format(self.wd, {'bold': True, 'font_size': 14})
53 | define_format_H1.set_border(1)
54 |
55 | define_format_H2.set_border(1)
56 | define_format_H1.set_align("center")
57 | define_format_H2.set_align("center")
58 | define_format_H2.set_bg_color("blue")
59 | define_format_H2.set_color("#ffffff")
60 | worksheet.merge_range('A1:L1', 'monkey性能监控', define_format_H1)
61 | _write_center(worksheet, "A2", '设备名', self.wd)
62 | _write_center(worksheet, "B2", 'CPU', self.wd)
63 | _write_center(worksheet, "C2", '内存', self.wd)
64 | _write_center(worksheet, "D2", '分辨率', self.wd)
65 | _write_center(worksheet, "E2", '网络', self.wd)
66 | _write_center(worksheet, "F2", "耗时", self.wd)
67 | _write_center(worksheet, "G2", "CPU峰值", self.wd)
68 | _write_center(worksheet, "H2", "CPU均值", self.wd)
69 | _write_center(worksheet, "I2", "内存峰值", self.wd)
70 | _write_center(worksheet, "J2", "内存均值", self.wd)
71 | _write_center(worksheet, "K2", "fps峰值", self.wd)
72 | _write_center(worksheet, "L2", "fps均值", self.wd)
73 | _write_center(worksheet, "M2", "电量测试之前", self.wd)
74 | _write_center(worksheet, "N2", "电量测试之后", self.wd)
75 | _write_center(worksheet, "O2", "上行流量峰值", self.wd)
76 | _write_center(worksheet, "P2", "上行流量均值", self.wd)
77 | _write_center(worksheet, "Q2", "下行流量峰值", self.wd)
78 | _write_center(worksheet, "R2", "下行流量均值", self.wd)
79 |
80 |
81 | temp = 3
82 | for t in info:
83 | for wrap in t:
84 | for item in t[wrap]:
85 | self.getCrashMsg(t[wrap]["header"]["monkey_log"])
86 | _write_center(worksheet, "A" + str(temp), t[wrap]["header"]["phone_name"], self.wd)
87 | _write_center(worksheet, "B" + str(temp), t[wrap]["header"]["kel"], self.wd)
88 | _write_center(worksheet, "C" + str(temp), str(math.ceil(t[wrap]["header"]["rom"] / 1024)) + "M", self.wd)
89 | _write_center(worksheet, "D" + str(temp), t[wrap]["header"]["pix"], self.wd)
90 | _write_center(worksheet, "E" + str(temp), t[wrap]["header"]["net"], self.wd)
91 | _write_center(worksheet, "F" + str(temp), t[wrap]["header"]["time"], self.wd)
92 |
93 | cpu = readInfo(t[wrap]["cpu"])
94 | men = readInfo(t[wrap]["men"])
95 | fps = readInfo(t[wrap]["fps"])
96 | flow = readInfo(t[wrap]["flow"])
97 | print("----wrap-----")
98 | print(flow)
99 | _write_center(worksheet, "G" + str(temp), BaseAnalysis.maxCpu(cpu), self.wd)
100 | _write_center(worksheet, "H" + str(temp), BaseAnalysis.avgCpu(cpu), self.wd)
101 | _write_center(worksheet, "I" + str(temp), BaseAnalysis.maxMen(men), self.wd)
102 | _write_center(worksheet, "J" + str(temp), BaseAnalysis.avgMen(men, t[wrap]["header"]["rom"]), self.wd)
103 | _write_center(worksheet, "K" + str(temp), BaseAnalysis.maxFps(fps), self.wd)
104 | _write_center(worksheet, "L" + str(temp), BaseAnalysis.avgFps(fps), self.wd)
105 | _write_center(worksheet, "M" + str(temp), t[wrap]["header"]["beforeBattery"], self.wd)
106 | _write_center(worksheet, "N" + str(temp), t[wrap]["header"]["afterBattery"], self.wd)
107 |
108 | _maxFlow = BaseAnalysis.maxFlow(flow)
109 | _avgFLow = BaseAnalysis.avgFlow(flow)
110 | print("-----_maxFlow----------")
111 | print(_maxFlow)
112 | _write_center(worksheet, "O" + str(temp), _maxFlow[0], self.wd)
113 | _write_center(worksheet, "Q" + str(temp), _maxFlow[1], self.wd)
114 | _write_center(worksheet, "P" + str(temp), _avgFLow[1], self.wd)
115 | _write_center(worksheet, "R" + str(temp), _avgFLow[1], self.wd)
116 |
117 | break
118 | temp = temp + 1
119 |
120 | def getCrashMsg(self, log):
121 | with open(log, encoding="utf-8") as monkey_log:
122 | lines = monkey_log.readlines()
123 | for line in lines:
124 | if re.findall(go.ANR, line):
125 | print("存在anr错误:" + line)
126 | self._crashM.append(line)
127 | if re.findall(go.CRASH, line):
128 | print("存在crash错误:" + line)
129 | self._crashM.append(line)
130 | if re.findall(go.EXCEPTION, line):
131 | print("存在crash错误:" + line)
132 | self._crashM.append(line)
133 | def crash(self):
134 | if len(self._crashM):
135 | worksheet = self.wd.add_worksheet("crash")
136 | _write_center(worksheet, "A1", '崩溃统计日志', self.wd)
137 | temp = 2
138 | for item in self._crashM:
139 | _write_center(worksheet, "A" + str(temp), item, self.wd)
140 | temp = temp + 1
141 |
142 | def plot(self, worksheet, types, lenData, name):
143 | '''
144 |
145 | :param worksheet:
146 | :param types: cpu,fps,flow,battery
147 | :param lenData: 数据长度
148 | :param name: sheet名字
149 | :return:
150 | '''
151 | values = ""
152 | row = ""
153 | title = ""
154 | if types == "cpu":
155 | values = "="+name+"!$A$1:$A$" + str(lenData + 1)
156 | row = 'A' + str(lenData)
157 | title = "cpu使用率"
158 | elif types == "men":
159 | values = "="+name+"!$B$1:$B$" + str(lenData + 1)
160 | row = 'B' + str(lenData)
161 | title = "内存使用MB"
162 | elif types == "fps":
163 | values = "=" + name + "!$C$1:$C$" + str(lenData + 1)
164 | row = 'C' + str(lenData)
165 | title = "fps使用情况"
166 | elif types == "battery":
167 | values = "="+name+"!$D$1:$D$" + str(lenData + 1)
168 | row = 'D' + str(lenData)
169 | title = "电池剩余%"
170 | elif types == "flowUp":
171 | values = "="+name+"!$E$1:$E$" + str(lenData + 1)
172 | row = 'E' + str(lenData)
173 | title = "上行流量KB"
174 | elif types == "flowDown":
175 | values = "="+name+"!$F$1:$F$" + str(lenData + 1)
176 | row = 'F' + str(lenData)
177 | title = "下行流量KB"
178 | chart1 = self.wd.add_chart({'type': 'line'})
179 | chart1.add_series({
180 | 'values': values
181 | })
182 | chart1.set_title({'name': title})
183 | # worksheet.insert_chart('A9', chart1, {'x_offset': 2, 'y_offset': 2})
184 | worksheet.insert_chart(row, chart1)
185 |
186 |
187 |
188 | def close(self):
189 | self.wd.close()
190 |
191 | def analysis(self, info):
192 | for t in info:
193 | for wrap in t:
194 | name = wrap + "detail" # sheet名字
195 | worksheet = self.wd.add_worksheet(name)
196 | worksheet.set_column("A:A", 10)
197 | worksheet.set_column("B:B", 10)
198 | worksheet.set_column("C:C", 10)
199 | worksheet.set_column("D:D", 10)
200 | worksheet.set_column("E:E", 10)
201 | worksheet.set_column("F:F", 10)
202 |
203 | worksheet.set_row(1, 30)
204 | worksheet.set_row(2, 30)
205 | worksheet.set_row(3, 30)
206 | worksheet.set_row(4, 30)
207 | worksheet.set_row(5, 30)
208 | worksheet.set_row(6, 30)
209 | define_format_H1 = get_format(self.wd, {'bold': True, 'font_size': 18})
210 | define_format_H2 = get_format(self.wd, {'bold': True, 'font_size': 14})
211 | define_format_H1.set_border(1)
212 |
213 | define_format_H2.set_border(1)
214 | define_format_H1.set_align("center")
215 | define_format_H2.set_align("center")
216 | define_format_H2.set_bg_color("blue")
217 | define_format_H2.set_color("#ffffff")
218 |
219 | _write_center(worksheet, "A1", 'cpu(%)', self.wd)
220 | _write_center(worksheet, "B1", 'men(M)', self.wd)
221 | _write_center(worksheet, "C1", 'fps', self.wd)
222 | _write_center(worksheet, "D1", 'battery(%)', self.wd)
223 | _write_center(worksheet, "E1", '上行流量(KB)', self.wd)
224 | _write_center(worksheet, "F1", '下行流量(KB)', self.wd)
225 | for item in t[wrap]:
226 | print("------data-----")
227 | temp = 2
228 | cpu = readInfo(t[wrap]["cpu"])
229 | for item in cpu:
230 | _write_center(worksheet, "A" + str(temp), float("%.1f" % item)*10, self.wd)
231 | temp = temp + 1
232 |
233 | temp = 2
234 | men = readInfo(t[wrap]["men"])
235 | for item in men:
236 | _write_center(worksheet, "B" + str(temp), math.ceil(item/1024), self.wd)
237 | temp = temp + 1
238 |
239 |
240 | temp = 2
241 | fps = readInfo(t[wrap]["fps"])
242 | for item in fps:
243 | _write_center(worksheet, "C" + str(temp), item, self.wd)
244 | temp = temp + 1
245 |
246 | temp = 2
247 | battery = readInfo(t[wrap]["battery"])
248 | for item in battery:
249 | _write_center(worksheet, "D" + str(temp), item, self.wd)
250 | temp = temp + 1
251 |
252 | temp = 2
253 | flow = readInfo(t[wrap]["flow"])
254 | for item in flow[0]:
255 | if item > 0:
256 | _write_center(worksheet, "E" + str(temp), math.ceil(item/1024), self.wd)
257 | else:
258 | _write_center(worksheet, "E" + str(temp), 0, self.wd)
259 | temp = temp + 1
260 |
261 | temp = 2
262 | for item in flow[1]:
263 | if item > 0:
264 | _write_center(worksheet, "F" + str(temp), math.ceil(item/1024), self.wd)
265 | else:
266 | _write_center(worksheet, "F" + str(temp), 0, self.wd)
267 | temp = temp + 1
268 | self.plot(worksheet, "cpu", len(cpu), name)
269 | self.plot(worksheet, "men", len(men), name)
270 | self.plot(worksheet, "battery", len(battery), name)
271 | self.plot(worksheet, "fps", len(fps), name)
272 | self.plot(worksheet, "flowUp", len(flow[0]), name)
273 | self.plot(worksheet, "flowDown", len(flow[1]), name)
274 | break
275 |
276 |
277 | def get_format(wd, option={}):
278 | return wd.add_format(option)
279 |
280 |
281 | def get_format_center(wd, num=1):
282 | return wd.add_format({'align': 'center', 'valign': 'vcenter', 'border': num})
283 |
284 |
285 | def set_border_(wd, num=1):
286 | return wd.add_format({}).set_border(num)
287 |
288 |
289 | def _write_center(worksheet, cl, data, wd):
290 | return worksheet.write(cl, data, get_format_center(wd))
291 |
292 |
293 | def set_row(worksheet, num, height):
294 | worksheet.set_row(num, height)
295 |
296 |
297 | if __name__ == '__main__':
298 |
299 | workbook = xlsxwriter.Workbook('report.xlsx')
300 | info = [{'emulator-5554': {'cpu': 'E:\\app\\py\\monkey1\\info\\emulator-5554_cpu.pickle', 'battery': 'E:\\app\\py\\monkey1\\info\\emulator-5554_battery.pickle', 'men': 'E:\\app\\py\\monkey1\\info\\emulator-5554_men.pickle', 'flow': 'E:\\app\\py\\monkey1\\info\\emulator-5554_flow.pickle', 'header': {'rom': 770300, 'kel': '2核', 'monkey_log': 'E:\\app\\py\\monkey1\\log\\55dd9a83-3337-46d5-bb1f-6f64b85be7cbmonkey.log', 'beforeBattery': 99, 'pix': '1440x810', 'time': '10秒', 'afterBattery': 99, 'phone_name': 'GT-I9500_samsung_4.4', 'net': 'gprs'}, 'fps': 'E:\\app\\py\\monkey1\\info\\emulator-5554_fps.pickle'}}, {'DU2TAN15AJ049163': {'cpu': 'E:\\app\\py\\monkey1\\info\\DU2TAN15AJ049163_cpu.pickle', 'battery': 'E:\\app\\py\\monkey1\\info\\DU2TAN15AJ049163_battery.pickle', 'men': 'E:\\app\\py\\monkey1\\info\\DU2TAN15AJ049163_men.pickle', 'flow': 'E:\\app\\py\\monkey1\\info\\DU2TAN15AJ049163_flow.pickle', 'header': {'rom': 3085452, 'kel': '8核', 'monkey_log': 'E:\\app\\py\\monkey1\\log\\732ac6cd-dd84-4818-80ea-d9b5339c6774monkey.log', 'beforeBattery': 94, 'pix': '1080x1920', 'time': '15秒', 'afterBattery': 94, 'phone_name': 'H60-L02_Huawei_4.4', 'net': 'gprs'}, 'fps': 'E:\\app\\py\\monkey1\\info\\DU2TAN15AJ049163_fps.pickle'}}]
301 |
302 |
303 | tem = OperateReport(workbook)
304 | tem.monitor(info)
305 | tem.analysis(info)
306 | tem.crash()
307 | tem.close()
308 | # print(len(data["cpu"]))
309 |
--------------------------------------------------------------------------------
/Base/BaseWriteReport.py:
--------------------------------------------------------------------------------
1 | import os
2 | import xlsxwriter
3 | from Base import BaseReport
4 |
5 |
6 | PATH = lambda p: os.path.abspath(
7 | os.path.join(os.path.dirname(__file__), p)
8 | )
9 |
10 |
11 | def report(info):
12 | workbook = xlsxwriter.Workbook('report.xlsx')
13 | bo = BaseReport.OperateReport(workbook)
14 | bo.monitor(info)
15 | bo.crash()
16 | bo.analysis(info)
17 | bo.close()
--------------------------------------------------------------------------------
/Base/Cprint.py:
--------------------------------------------------------------------------------
1 | __author__ = 'Administrator'
2 | import ctypes
3 |
4 | STD_INPUT_HANDLE = -10
5 | STD_OUTPUT_HANDLE= -11
6 | STD_ERROR_HANDLE = -12
7 |
8 | FOREGROUND_BLACK = 0x0
9 | FOREGROUND_BLUE = 0x01 # text color contains blue.
10 | FOREGROUND_GREEN= 0x02 # text color contains green.
11 | FOREGROUND_RED = 0x04 # text color contains red.
12 | FOREGROUND_INTENSITY = 0x08 # text color is intensified.
13 |
14 | BACKGROUND_BLUE = 0x10 # background color contains blue.
15 | BACKGROUND_GREEN= 0x20 # background color contains green.
16 | BACKGROUND_RED = 0x40 # background color contains red.
17 | BACKGROUND_INTENSITY = 0x80 # background color is intensified.
18 |
19 | class Color:
20 | ''''' See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winprog/winprog/windows_api_reference.asp
21 | for information on Windows APIs.'''
22 | std_out_handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
23 |
24 | def set_cmd_color(self, color, handle=std_out_handle):
25 | """(color) -> bit
26 | Example: set_cmd_color(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY)
27 | """
28 | bool = ctypes.windll.kernel32.SetConsoleTextAttribute(handle, color)
29 | return bool
30 |
31 | def reset_color(self):
32 | self.set_cmd_color(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
33 |
34 | def print_red_text(self, print_text):
35 | self.set_cmd_color(FOREGROUND_RED | FOREGROUND_INTENSITY)
36 | print(print_text)
37 | self.reset_color()
38 |
39 | def print_green_text(self, print_text):
40 | self.set_cmd_color(FOREGROUND_GREEN | FOREGROUND_INTENSITY)
41 | print(print_text)
42 | self.reset_color()
43 |
44 | def print_blue_text(self, print_text):
45 | self.set_cmd_color(FOREGROUND_BLUE | FOREGROUND_INTENSITY)
46 | print(print_text)
47 | self.reset_color()
48 |
49 | def print_red_text_with_blue_bg(self, print_text):
50 | self.set_cmd_color(FOREGROUND_RED | FOREGROUND_INTENSITY| BACKGROUND_BLUE | BACKGROUND_INTENSITY)
51 | print(print_text)
52 | self.reset_color()
--------------------------------------------------------------------------------
/Base/OperateFile.py:
--------------------------------------------------------------------------------
1 | __author__ = 'Administrator'
2 | import os
3 | class base_file:
4 | #method(r,w,a)
5 | def __init__(self, file, method='w+'):
6 | self.file = file
7 | self.method = method
8 | self.fileHandle = None
9 |
10 | def write_txt(self, line):
11 | base_file(self.file).check_file()
12 | self.fileHandle = open(self.file, self.method)
13 | self.fileHandle.write(line + "\n")
14 | self.fileHandle.close()
15 |
16 | def read_txt_row(self):
17 | base_file(self.file).check_file()
18 | self.fileHandle = open(self.file, self.method)
19 | print(self.fileHandle.readline())
20 | self.fileHandle.close()
21 |
22 | def read_txt_rows(self):
23 | base_file(self.file).check_file()
24 | self.fileHandle = open(self.file, self.method)
25 | file_list = self.fileHandle.readlines()
26 | for i in file_list:
27 | print(i.strip("\n"))
28 | self.fileHandle.close()
29 | def check_file(self):
30 | if not os.path.isfile(self.file):
31 | # print('文件不存在' + self.file)
32 | # sys.exit()
33 | return False
34 | else:
35 | return True
36 | # print("文件存在!")
37 |
38 | def mkdir_file(self):
39 | if not os.path.isfile(self.file):
40 | f = open(self.file, self.method)
41 | f.close()
42 | print("创建文件成功")
43 | return True
44 | else:
45 | print("文件已经存在")
46 | return False
47 | def remove_file(self):
48 | if os.path.isfile(self.file):
49 | os.remove(self.file)
50 | print("删除文件成功")
51 | else:
52 | print("文件不存在")
53 | # if __name__ == '__main__':
54 | # bf = base_file("text.xml")
55 | # if bf.check_file() == False:
56 | # bf.mkdir_file()
57 | # bf.write_txt("111")
--------------------------------------------------------------------------------
/Base/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/Base/__init__.py
--------------------------------------------------------------------------------
/Base/__pycache__/AdbCommon.cpython-34.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/Base/__pycache__/AdbCommon.cpython-34.pyc
--------------------------------------------------------------------------------
/Base/__pycache__/BaseAnalysis.cpython-34.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/Base/__pycache__/BaseAnalysis.cpython-34.pyc
--------------------------------------------------------------------------------
/Base/__pycache__/BaseCashEmnu.cpython-34.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/Base/__pycache__/BaseCashEmnu.cpython-34.pyc
--------------------------------------------------------------------------------
/Base/__pycache__/BaseFile.cpython-34.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/Base/__pycache__/BaseFile.cpython-34.pyc
--------------------------------------------------------------------------------
/Base/__pycache__/BaseMonitor.cpython-34.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/Base/__pycache__/BaseMonitor.cpython-34.pyc
--------------------------------------------------------------------------------
/Base/__pycache__/BaseMonkeyConfig.cpython-34.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/Base/__pycache__/BaseMonkeyConfig.cpython-34.pyc
--------------------------------------------------------------------------------
/Base/__pycache__/BasePhoneMsg.cpython-34.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/Base/__pycache__/BasePhoneMsg.cpython-34.pyc
--------------------------------------------------------------------------------
/Base/__pycache__/BasePickle.cpython-34.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/Base/__pycache__/BasePickle.cpython-34.pyc
--------------------------------------------------------------------------------
/Base/__pycache__/BaseReport.cpython-34.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/Base/__pycache__/BaseReport.cpython-34.pyc
--------------------------------------------------------------------------------
/Base/__pycache__/BaseWriteReport.cpython-34.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/Base/__pycache__/BaseWriteReport.cpython-34.pyc
--------------------------------------------------------------------------------
/Base/__pycache__/Cprint.cpython-34.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/Base/__pycache__/Cprint.cpython-34.pyc
--------------------------------------------------------------------------------
/Base/__pycache__/OperateFile.cpython-34.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/Base/__pycache__/OperateFile.cpython-34.pyc
--------------------------------------------------------------------------------
/Base/__pycache__/__init__.cpython-34.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/Base/__pycache__/__init__.cpython-34.pyc
--------------------------------------------------------------------------------
/Chinese.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/Chinese.md
--------------------------------------------------------------------------------
/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.monkneytest;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.util.Log;
6 | import android.view.View;
7 | import android.view.View.OnClickListener;
8 | import android.widget.Button;
9 | public class MainActivity extends Activity {
10 | Button btn;
11 | @Override
12 | protected void onCreate(Bundle savedInstanceState) {
13 | super.onCreate(savedInstanceState);
14 |
15 | setContentView(R.layout.activity_main);
16 | btn = (Button) findViewById(R.id.btn1);
17 | btn.setOnClickListener(newOnClickListener);
18 |
19 | }
20 | private OnClickListener newOnClickListener = new OnClickListener(){
21 | @Override
22 | public void onClick(View v) {
23 | String a =null; a.toString();
24 | }
25 | };
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/README.md
--------------------------------------------------------------------------------
/img/analysis.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/img/analysis.jpg
--------------------------------------------------------------------------------
/img/crash.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/img/crash.PNG
--------------------------------------------------------------------------------
/img/monitor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/img/monitor.png
--------------------------------------------------------------------------------
/info/DU2TAN15AJ049163_battery.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/info/DU2TAN15AJ049163_battery.pickle
--------------------------------------------------------------------------------
/info/DU2TAN15AJ049163_cpu.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/info/DU2TAN15AJ049163_cpu.pickle
--------------------------------------------------------------------------------
/info/DU2TAN15AJ049163_flow.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/info/DU2TAN15AJ049163_flow.pickle
--------------------------------------------------------------------------------
/info/DU2TAN15AJ049163_fps.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/info/DU2TAN15AJ049163_fps.pickle
--------------------------------------------------------------------------------
/info/DU2TAN15AJ049163_men.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/info/DU2TAN15AJ049163_men.pickle
--------------------------------------------------------------------------------
/info/info.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/info/info.pickle
--------------------------------------------------------------------------------
/info/sumInfo.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/info/sumInfo.pickle
--------------------------------------------------------------------------------
/kill5037.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | color a
3 | title ReleaseAdbPort
4 | echo ======================
5 | echo *** liyu 2015-01-15***
6 | echo *** v1.0.0 ***
7 | echo ======================
8 | echo ---------------------------
9 | echo Checking adb port...
10 | for /F "usebackq tokens=5" %%a in (`"netstat -ano | findstr "5037""`) do (
11 | if not "%%a" =="0" call :ReleasePort %%a
12 | )
13 | echo ---------------------------
14 | echo adb port has been released!
15 | echo ---------------------------
16 |
17 |
18 | exit
19 |
20 | :ReleasePort
21 | TASKKILL /f /PID %1
22 |
23 | exit
--------------------------------------------------------------------------------
/log/adece0c8-1f61-4cae-8ed4-e8db510de83dmonkey.log:
--------------------------------------------------------------------------------
1 | :Monkey: seed=1518933798525 count=500
2 | :AllowPackage: com.jianshu.haruki
3 | :IncludeCategory: android.intent.category.LAUNCHER
4 | :IncludeCategory: android.intent.category.MONKEY
5 | // Selecting main activities from category android.intent.category.LAUNCHER
6 | // - NOT USING main activity com.android.browser.BrowserActivity (from package com.android.browser)
7 | // - NOT USING main activity com.android.contacts.activities.PeopleActivity (from package com.android.contacts)
8 | // - NOT USING main activity com.android.contacts.activities.DialtactsActivity (from package com.android.contacts)
9 | // - NOT USING main activity com.android.mms.ui.ConversationList (from package com.android.contacts)
10 | // - NOT USING main activity com.huawei.gallery.app.GalleryActivity (from package com.android.gallery3d)
11 | // - NOT USING main activity com.android.email.activity.Welcome (from package com.android.email)
12 | // - NOT USING main activity com.huawei.camera (from package com.huawei.camera)
13 | // - NOT USING main activity com.android.settings.HWSettings (from package com.android.settings)
14 | // - NOT USING main activity com.android.calculator2.Calculator (from package com.android.calculator2)
15 | // - NOT USING main activity com.android.calendar.AllInOneActivity (from package com.android.calendar)
16 | // - NOT USING main activity com.android.deskclock.AlarmsMainActivity (from package com.android.deskclock)
17 | // - NOT USING main activity com.huawei.android.hicloud.hisync.activity.NewHiSyncSettingActivity (from package com.huawei.android.ds)
18 | // - NOT USING main activity com.android.mediacenter.PageActivity (from package com.android.mediacenter)
19 | // - NOT USING main activity com.example.android.notepad.NotePadActivity (from package com.example.android.notepad)
20 | // - NOT USING main activity com.huawei.hidisk.filemanager.FileManager (from package com.huawei.hidisk)
21 | // - NOT USING main activity com.google.android.apps.chrome.Main (from package com.android.chrome)
22 | // - NOT USING main activity com.evernote.ui.HomeActivity (from package com.evernote)
23 | // - NOT USING main activity com.tencent.pangu.link.SplashActivity (from package com.tencent.android.qqdownloader)
24 | // - NOT USING main activity com.sohu.inputmethod.sogou.SogouIMELauncher (from package com.sohu.inputmethod.sogou)
25 | // - NOT USING main activity com.baidu.baidumaps.WelcomeScreen (from package com.baidu.BaiduMap)
26 | // - NOT USING main activity com.huawei.phoneservice.ui.HelpCenterActivity (from package com.huawei.phoneservice)
27 | // - NOT USING main activity com.huawei.hwvplayer.framework.MainActivity (from package com.huawei.hwvplayer)
28 | // - NOT USING main activity com.android.keyguard.keyguardplus.OneKeyLockActivity (from package com.android.keyguard)
29 | // - NOT USING main activity com.android.providers.downloads.ui.DownloadList (from package com.android.providers.downloads.ui)
30 | // - NOT USING main activity com.huawei.KoBackup.InitializeActivity (from package com.huawei.KoBackup)
31 | // - NOT USING main activity com.huawei.android.FMRadio.FMRadioMainActivity (from package com.huawei.android.FMRadio)
32 | // - NOT USING main activity com.huawei.vassistant.ui.VAssistantActivity (from package com.huawei.vassistant)
33 | // - NOT USING main activity com.huawei.android.hwouc.ui.activities.MainEntranceActivity (from package com.huawei.android.hwouc)
34 | // - NOT USING main activity com.android.soundrecorder.SoundRecorder (from package com.android.soundrecorder)
35 | // - NOT USING main activity com.huawei.systemmanager.mainscreen.MainScreenActivity (from package com.huawei.systemmanager)
36 | // - NOT USING main activity com.huawei.android.thememanager.HwThemeManagerActivity (from package com.huawei.android.thememanager)
37 | // - NOT USING main activity com.huawei.vdrive.ui.VDriveActivity (from package com.huawei.vdrive)
38 | // - NOT USING main activity com.huawei.android.totemweather.WeatherHome (from package com.huawei.android.totemweather)
39 | // - NOT USING main activity com.huawei.magnifier.MagnifierActivity (from package com.huawei.magnifier)
40 | // - NOT USING main activity com.android.stk.StkLauncherActivity (from package com.android.stk)
41 | // - NOT USING main activity com.android.stk.StkLauncherActivity2 (from package com.android.stk)
42 | // - NOT USING main activity com.android.systemui.flashlight.FlashlightActivity (from package com.android.systemui)
43 | // - NOT USING main activity com.android.hwmirror.Mirror (from package com.android.hwmirror)
44 | // - NOT USING main activity com.huawei.android.remotecontroller.StartActivity (from package com.huawei.android.remotecontroller)
45 | // - NOT USING main activity com.huawei.appmarket.MainActivity (from package com.huawei.appmarket)
46 | // - NOT USING main activity com.autonavi.map.activity.SplashActivity (from package com.autonavi.minimap)
47 | // - NOT USING main activity com.kingroot.kinguser.activitys.SliderMainActivity-Entry (from package com.kingroot.kinguser)
48 | // - NOT USING main activity com.example.monkey.MainActivity (from package com.example.monkey)
49 | // - NOT USING main activity com.alipay.mobile.quinox.LauncherActivity (from package com.MobileTicket)
50 | // - NOT USING main activity io.appium.settings.Settings (from package io.appium.settings)
51 | // + Using main activity com.baiji.jianshu.ui.splash.SplashScreenActivity (from package com.jianshu.haruki)
52 | // - NOT USING main activity com.jecelyin.editor.JecEditor (from package com.jecelyin.editor)
53 | // - NOT USING main activity io.appium.unlock.Unlock (from package io.appium.unlock)
54 | // - NOT USING main activity com.jingdong.app.mall.main.MainActivity (from package com.jingdong.app.mall)
55 | // - NOT USING main activity com.tencent.mtt.SplashActivity (from package com.tencent.mtt)
56 | // - NOT USING main activity com.intsig.camscanner.WelcomeActivity (from package com.intsig.camscanner)
57 | // - NOT USING main activity com.tencent.qqmail.LaucherActivity (from package com.tencent.androidqqmail)
58 | // - NOT USING main activity cn.etouch.ecalendar.ECalendar (from package cn.etouch.ecalendar)
59 | // - NOT USING main activity com.sankuai.meituan.activity.Welcome (from package com.sankuai.meituan)
60 | // - NOT USING main activity com.baidu.netdisk.ui.Navigate (from package com.baidu.netdisk)
61 | // - NOT USING main activity com.speedsoftware.rootexplorer.RootExplorer (from package com.speedsoftware.rootexplorer)
62 | // - NOT USING main activity com.oasisfeng.greenify.GreenifyActivity (from package com.oasisfeng.greenify)
63 | // - NOT USING main activity com.netease.cloudmusic.activity.LoadingActivity (from package com.netease.cloudmusic)
64 | // - NOT USING main activity com.tencent.qqlive.ona.activity.WelcomeActivity (from package com.tencent.qqlive)
65 | // - NOT USING main activity com.sinovatech.unicom.ui.WelcomeClient (from package com.sinovatech.unicom.ui)
66 | // - NOT USING main activity com.xxAssistant.View.SplashActivity (from package com.xxAssistant)
67 | // - NOT USING main activity com.tencent.tmgp.supercell.clashofclans.GameAppTencent (from package com.tencent.tmgp.supercell.clashofclans)
68 | // - NOT USING main activity com.tencent.mm.ui.LauncherUI (from package com.tencent.mm)
69 | // - NOT USING main activity so.ofo.labofo.activities.EntryActivity (from package so.ofo.labofo)
70 | // - NOT USING main activity com.yipiao.activity.LaunchActivity (from package com.yipiao)
71 | // - NOT USING main activity com.mobike.mobikeapp.SplashActivity (from package com.mobike.mobikeapp)
72 | // - NOT USING main activity com.eg.android.AlipayGphone.AlipayLogin (from package com.eg.android.AlipayGphone)
73 | // - NOT USING main activity com.didi.sdk.app.DidiLoadDexActivity (from package com.sdu.didi.psnger)
74 | // - NOT USING main activity dev.xesam.chelaile.app.module.func.SplashActivity (from package com.ygkj.chelaile.standard)
75 | // - NOT USING main activity com.tencent.mobileqq.activity.SplashActivity (from package com.tencent.mobileqq)
76 | // - NOT USING main activity com.zhihu.android.app.ui.activity.MainActivity (from package com.zhihu.android)
77 | // - NOT USING main activity com.tencent.news.activity.SplashActivity (from package com.tencent.news)
78 | // - NOT USING main activity com.tencent.tmgp.sgame.SGameActivity (from package com.tencent.tmgp.sgame)
79 | // Selecting main activities from category android.intent.category.MONKEY
80 | // - NOT USING main activity com.android.settings.Settings$RunningServicesActivity (from package com.android.settings)
81 | // - NOT USING main activity com.android.settings.Settings$StorageUseActivity (from package com.android.settings)
82 | // - NOT USING main activity com.huawei.android.launcher.Launcher (from package com.huawei.android.launcher)
83 | // Seeded: 1518933798525
84 | // Event percentages:
85 | // 0: 15.0%
86 | // 1: 10.0%
87 | // 2: 2.0%
88 | // 3: 15.0%
89 | // 4: -0.0%
90 | // 5: 25.0%
91 | // 6: 15.0%
92 | // 7: 2.0%
93 | // 8: 2.0%
94 | // 9: 1.0%
95 | // 10: 13.0%
96 | :Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.jianshu.haruki/com.baiji.jianshu.ui.splash.SplashScreenActivity;end
97 | // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.jianshu.haruki/com.baiji.jianshu.ui.splash.SplashScreenActivity } in package com.jianshu.haruki
98 | Sleeping for 500 milliseconds
99 | :Sending Key (ACTION_DOWN): 20 // KEYCODE_DPAD_DOWN
100 | :Sending Key (ACTION_UP): 20 // KEYCODE_DPAD_DOWN
101 | Sleeping for 500 milliseconds
102 | // Allowing start of Intent { cmp=com.jianshu.haruki/com.baiji.jianshu.MainActivity } in package com.jianshu.haruki
103 | // activityResuming(com.jianshu.haruki)
104 | // activityResuming(com.jianshu.haruki)
105 | :Sending Key (ACTION_DOWN): 164 // KEYCODE_VOLUME_MUTE
106 | :Sending Key (ACTION_UP): 164 // KEYCODE_VOLUME_MUTE
107 | Sleeping for 500 milliseconds
108 | :Sending Key (ACTION_DOWN): 126 // KEYCODE_MEDIA_PLAY
109 | :Sending Key (ACTION_UP): 126 // KEYCODE_MEDIA_PLAY
110 | Sleeping for 500 milliseconds
111 | :Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=com.jianshu.haruki/com.baiji.jianshu.ui.splash.SplashScreenActivity;end
112 | // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.jianshu.haruki/com.baiji.jianshu.ui.splash.SplashScreenActivity } in package com.jianshu.haruki
113 | Sleeping for 500 milliseconds
114 | :Sending Key (ACTION_DOWN): 21 // KEYCODE_DPAD_LEFT
115 | :Sending Key (ACTION_UP): 21 // KEYCODE_DPAD_LEFT
116 | Sleeping for 500 milliseconds
117 | :Sending Key (ACTION_DOWN): 253 // 253
118 | :Sending Key (ACTION_UP): 253 // 253
119 | Sleeping for 500 milliseconds
120 | :Sending Key (ACTION_DOWN): 20 // KEYCODE_DPAD_DOWN
121 | :Sending Key (ACTION_UP): 20 // KEYCODE_DPAD_DOWN
122 | Sleeping for 500 milliseconds
123 | :Sending Key (ACTION_DOWN): 22 // KEYCODE_DPAD_RIGHT
124 | :Sending Key (ACTION_UP): 22 // KEYCODE_DPAD_RIGHT
125 | Sleeping for 500 milliseconds
126 | :Sending Key (ACTION_DOWN): 23 // KEYCODE_DPAD_CENTER
127 | :Sending Key (ACTION_UP): 23 // KEYCODE_DPAD_CENTER
128 | Sleeping for 500 milliseconds
129 | :Sending Key (ACTION_DOWN): 20 // KEYCODE_DPAD_DOWN
130 | :Sending Key (ACTION_UP): 20 // KEYCODE_DPAD_DOWN
131 | Sleeping for 500 milliseconds
132 | :Sending Touch (ACTION_DOWN): 0:(10.0,51.0)
133 | :Sending Touch (ACTION_POINTER_DOWN 1): 0:(9.24655,50.689335) 1:(741.0,810.0)
134 | :Sending Touch (ACTION_MOVE): 0:(7.588022,49.52343) 1:(747.7333,808.75116)
135 | :Sending Touch (ACTION_MOVE): 0:(4.4343414,48.509113) 1:(758.92554,797.54)
136 | :Sending Touch (ACTION_MOVE): 0:(0.0,48.21961) 1:(771.9343,785.41644)
137 | :Sending Touch (ACTION_MOVE): 0:(0.0,47.021748) 1:(793.7777,778.644)
138 | :Sending Touch (ACTION_MOVE): 0:(0.0,46.606693) 1:(796.2478,769.4633)
139 | :Sending Touch (ACTION_POINTER_UP 1): 0:(0.0,45.48305) 1:(818.06445,760.0704)
140 | :Sending Touch (ACTION_UP): 0:(0.0,44.87091)
141 | Sleeping for 500 milliseconds
142 | :Sending Key (ACTION_DOWN): 20 // KEYCODE_DPAD_DOWN
143 | :Sending Key (ACTION_UP): 20 // KEYCODE_DPAD_DOWN
144 | Sleeping for 500 milliseconds
145 | :Sending Key (ACTION_DOWN): 19 // KEYCODE_DPAD_UP
146 | :Sending Key (ACTION_UP): 19 // KEYCODE_DPAD_UP
147 | Sleeping for 500 milliseconds
148 | :Sending Key (ACTION_DOWN): 23 // KEYCODE_DPAD_CENTER
149 | :Sending Key (ACTION_UP): 23 // KEYCODE_DPAD_CENTER
150 | Sleeping for 500 milliseconds
151 | :Sending Trackball (ACTION_MOVE): 0:(1.0,-3.0)
152 | :Sending Trackball (ACTION_MOVE): 0:(-4.0,0.0)
153 | :Sending Trackball (ACTION_MOVE): 0:(-1.0,-3.0)
154 | :Sending Trackball (ACTION_MOVE): 0:(3.0,1.0)
155 | :Sending Trackball (ACTION_MOVE): 0:(4.0,-5.0)
156 | :Sending Trackball (ACTION_MOVE): 0:(-2.0,0.0)
157 | :Sending Trackball (ACTION_MOVE): 0:(-4.0,-3.0)
158 | :Sending Trackball (ACTION_MOVE): 0:(1.0,2.0)
159 | :Sending Trackball (ACTION_MOVE): 0:(-1.0,-1.0)
160 | :Sending Trackball (ACTION_MOVE): 0:(1.0,1.0)
161 | :Sending Key (ACTION_DOWN): 82 // KEYCODE_MENU
162 | :Sending Key (ACTION_UP): 82 // KEYCODE_MENU
163 | Sleeping for 500 milliseconds
164 | :Sending Touch (ACTION_DOWN): 0:(637.0,1292.0)
165 | :Sending Touch (ACTION_UP): 0:(629.91626,1311.5186)
166 | Sleeping for 500 milliseconds
167 | :Sending Touch (ACTION_DOWN): 0:(670.0,765.0)
168 | :Sending Touch (ACTION_UP): 0:(677.3006,767.5015)
169 | Sleeping for 500 milliseconds
170 | :Sending Touch (ACTION_DOWN): 0:(375.0,367.0)
171 | :Sending Touch (ACTION_UP): 0:(374.69092,378.29987)
172 | Sleeping for 500 milliseconds
173 | :Sending Touch (ACTION_DOWN): 0:(475.0,1195.0)
174 | :Sending Touch (ACTION_UP): 0:(482.29504,1175.4089)
175 | Sleeping for 500 milliseconds
176 | :Sending Key (ACTION_DOWN): 22 // KEYCODE_DPAD_RIGHT
177 | :Sending Key (ACTION_UP): 22 // KEYCODE_DPAD_RIGHT
178 | Sleeping for 500 milliseconds
179 | :Sending Key (ACTION_DOWN): 21 // KEYCODE_DPAD_LEFT
180 | :Sending Key (ACTION_UP): 21 // KEYCODE_DPAD_LEFT
181 | Sleeping for 500 milliseconds
182 | :Sending Key (ACTION_DOWN): 302 // 302
183 | :Sending Key (ACTION_UP): 302 // 302
184 |
--------------------------------------------------------------------------------
/monkey.ini:
--------------------------------------------------------------------------------
1 | [DEFAULT]
2 | cmd=monkey -p com.jianshu.haruki --throttle 500 --ignore-timeouts --ignore-crashes --monitor-native-crashes -v -v -v 500 >
3 | package_name=com.jianshu.haruki
4 | activity = com.baiji.jianshu.account.SplashScreenActivity
5 | net = gprs
--------------------------------------------------------------------------------
/monkey1.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/monkey1.apk
--------------------------------------------------------------------------------
/monkeyTest.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import pickle
3 |
4 | import subprocess
5 | import shutil
6 | import threading
7 |
8 | from multiprocessing import Process
9 |
10 | from Base.BasePickle import writeInfo, writeSum, readInfo
11 | from Base.BaseWriteReport import report
12 | __author__ = 'shikun'
13 | import datetime
14 | import uuid
15 | import time
16 | from multiprocessing import Pool
17 |
18 | from Base.BaseFile import OperateFile
19 | import os
20 | from Base import AdbCommon
21 | from Base import BaseMonkeyConfig
22 |
23 | from Base import BasePhoneMsg
24 | from Base import BaseMonitor
25 |
26 | PATH = lambda p: os.path.abspath(
27 | os.path.join(os.path.dirname(__file__), p)
28 | )
29 |
30 | ba = AdbCommon.AndroidDebugBridge()
31 |
32 |
33 | info = []
34 |
35 |
36 | # 手机信息
37 | def get_phome(devices):
38 | bg = BasePhoneMsg.get_phone_Kernel(devices)
39 | app = {}
40 | app["phone_name"] = bg[0]["phone_name"] + "_" + bg[0]["phone_model"] + "_" + bg[0]["release"]
41 | app["pix"] = bg[3]
42 | app["rom"] = bg[1]
43 | app["kel"] = bg[2]
44 | return app
45 |
46 |
47 | def mkdirInit(devices, app, data=None):
48 | # destroy(devices)
49 | cpu = PATH("./info/" + devices + "_cpu.pickle")
50 | men = PATH("./info/" + devices + "_men.pickle")
51 | flow = PATH("./info/" + devices + "_flow.pickle")
52 | battery = PATH("./info/" + devices + "_battery.pickle")
53 | fps = PATH("./info/" + devices + "_fps.pickle")
54 | app[devices] = {"cpu": cpu, "men": men, "flow": flow, "battery": battery, "fps": fps, "header": get_phome(devices)}
55 | OperateFile(cpu).mkdir_file()
56 | OperateFile(men).mkdir_file()
57 | OperateFile(flow).mkdir_file()
58 | OperateFile(battery).mkdir_file()
59 | OperateFile(fps).mkdir_file()
60 | OperateFile(PATH("./info/sumInfo.pickle")).mkdir_file() # 用于记录是否已经测试完毕,里面存的是一个整数
61 | OperateFile(PATH("./info/info.pickle")).mkdir_file() # 用于记录统计结果的信息,是[{}]的形式
62 |
63 | writeSum(0, data, PATH("./info/sumInfo.pickle")) # 初始化记录当前真实连接的设备数
64 |
65 | def runnerPool():
66 | shutil.rmtree((PATH("./info/"))) # 删除持久化目录
67 | os.makedirs(PATH("./info/")) # 创建持久化目录
68 | devices_Pool = []
69 | devices = ba.attached_devices()
70 | if devices:
71 | for item in range(0, len(devices)):
72 | _app = {}
73 | _app["devices"] = devices[item]
74 | _app["num"] = len(devices)
75 | devices_Pool.append(_app)
76 | pool = Pool(len(devices))
77 | pool.map(start, devices_Pool)
78 | pool.close()
79 | pool.join()
80 | else:
81 | print("设备不存在")
82 |
83 |
84 | def start(devicess):
85 | devices = devicess["devices"]
86 | num = devicess["num"]
87 | app = {}
88 | mkdirInit(devices, app, num)
89 | mc = BaseMonkeyConfig.monkeyConfig(PATH("monkey.ini"))
90 | # 打开想要的activity
91 | # ba.open_app(mc["package_name"], mc["activity"], devices) 留着备用可以统计每次打开哪个页面的启动时间等
92 | # monkey开始测试
93 | mc["log"] = PATH("./log") + "\\" + str(uuid.uuid4())
94 | mc["monkey_log"] = mc["log"] + "monkey.log"
95 | mc["cmd"] = mc['cmd'] + mc["monkey_log"]
96 | start_monkey("adb -s " + devices + " shell " + mc["cmd"], mc["log"])
97 | time.sleep(1)
98 | starttime = datetime.datetime.now()
99 | pid = BaseMonitor.get_pid(mc["package_name"], devices)
100 | cpu_kel = BaseMonitor.get_cpu_kel(devices)
101 | beforeBattery = BaseMonitor.get_battery(devices)
102 | while True:
103 | with open(mc["monkey_log"], encoding='utf-8') as monkeylog:
104 | time.sleep(1) # 每1秒采集检查一次
105 | BaseMonitor.cpu_rate(pid, cpu_kel, devices)
106 | BaseMonitor.get_men(mc["package_name"], devices)
107 | BaseMonitor.get_fps(mc["package_name"], devices)
108 | BaseMonitor.get_flow(pid, mc["net"], devices)
109 | BaseMonitor.get_battery(devices)
110 | if monkeylog.read().count('Monkey finished') > 0:
111 | endtime = datetime.datetime.now()
112 | print(str(devices)+"测试完成咯")
113 | writeSum(1, path=PATH("./info/sumInfo.pickle"))
114 | app[devices] ["header"]["beforeBattery"] = beforeBattery
115 | app[devices]["header"]["afterBattery"] = BaseMonitor.get_battery(devices)
116 | app[devices]["header"]["net"] = mc["net"]
117 | app[devices]["header"]["monkey_log"] = mc["monkey_log"]
118 | app[devices]["header"]["time"] = str((endtime - starttime).seconds) + "秒"
119 | writeInfo(app, PATH("./info/info.pickle"))
120 | break
121 | # go.info[devices]["header"]["sumTime"] = str((endtime - starttime).seconds) + "秒"
122 | # report(go.info)
123 | if readInfo(PATH("./info/sumInfo.pickle")) <= 0:
124 | print(readInfo(PATH("./info/info.pickle")))
125 | report(readInfo(PATH("./info/info.pickle")))
126 | subprocess.Popen("taskkill /f /t /im adb.exe", shell=True)
127 | # shutil.rmtree((PATH("./info/"))) # 删除持久化目录
128 |
129 |
130 | # 开始脚本测试
131 | def start_monkey(cmd, log):
132 | # Monkey测试结果日志:monkey_log
133 | os.popen(cmd)
134 | print(cmd)
135 |
136 | # Monkey时手机日志,logcat
137 | logcatname = log + r"logcat.log"
138 | cmd2 = "adb logcat -d >%s" % (logcatname)
139 | os.popen(cmd2)
140 |
141 | # "导出traces文件"
142 | tracesname = log + r"traces.log"
143 | cmd3 = "adb shell cat /data/anr/traces.txt>%s" % tracesname
144 | os.popen(cmd3)
145 |
146 | def killport():
147 | os.system(PATH('./kill5037.bat'))
148 | os.popen("adb kill-server adb")
149 | os.popen("adb start-server")
150 | if __name__ == '__main__':
151 | killport()
152 | time.sleep(1)
153 | runnerPool()
154 |
--------------------------------------------------------------------------------
/report.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Louis-me/monkeyTest/1dc89a5f5765e1dcc2fd5bfb8e457ad37e014de6/report.xlsx
--------------------------------------------------------------------------------