Python移动自动化测试面试准备
自动化测试工具
Instrumenttation
UIAutomator +uiautomatorviewer
Selendroid
Robotism
Appium
selenium
自动化框架
Unittest框架
单元测试
数据驱动DDT
python的第三方库
一般进行接口测试时,每个接口的传参都不止一种情况,一般会考虑正向、逆向等多种组合,所以在测试一个接口时,通常会编写多条case,而这些除了传参不同外,并没有什么区别。这个时候就可以利用ddt来管理测试数据,提高代码复用率。
行为驱动Lettuce
基本python语言的lettuce框架
什么是BDD
行为驱动开发是一种敏捷软件开发技术,它鼓励软件项目开发者、QA和非技术人员或商业参与者之间的协作。主要是从用户的需求出发,强调系统行为。BDD包括验收测试和客户测试驱动等的极限编程的实践,作为对测试驱动开发的回应。
关键字驱动Robot Framework
Robot Framework是一款python编写的功能自动化测试框架。具备良好的可扩展性,支持关键字驱动,可以同时测试多种类型的客户端或者接口,可以进行分布式测试执行。主要用于轮次很多的验收测试和验收测试驱动开发(ATDD)。
测试报告管理(HTMLTestRunner)
邮件服务管理
接口自动化
postman
python requests
压力工具
Load-runner
Jmeter
结构化思维
功能性
关于功能性测试
常规可输入的内容、数字、字符串、特殊字符、转义字符等。
非常规有一定含义的,html标签、css、javascript代码、url等
输入内容的边界、空字符、超长文本(边界值+1,-1)
兼容性
关于兼容性测试
根据产品的用户分布、手机品牌、分辨率、选择topN机型
根据产品在不同浏览器上的占有率,选择主要的浏览器测试
关注的问题,页面渲染、页面布局等,借助firebug调试
稳定性
关于稳定性测试
在某一压力下,搜索时,结果可以正常返回
性能
关心性能测试
GPS(每秒查询率),Query Per Second,每秒钟能处理的请求数
从点击开始到页面完全加载,平均耗时情况
加载的页面大小,资源(JS,CSS文件)的数量等
安全
关于安全测试
JS注入
SQL注入
接口
关于接口测试
查询接口的正确性验证
查询接口对一些异常数据的容错情况
查询接口在非浏览器环境下的处理情况
线上监控
关于线上监控
保证线上服务的质量,建立实时监控
及时发现异常情况,降低对用户的影响
自动化
关于自动化
基于Selenium实现UI自动化
例行回归验证,提高效率
Android使用Appium基于UIAutomator,IOS使用WDA
了解测试流程
了解bug处理流程
bug分级,优先级(中高低)、严重程度(高中低)
bug分类,UI、系统、接口
bug状态 ,新建、待修改,待验证、已验证
常用的测试工具
网络调试工具:fiddler
页面调试工具:Chrome Inspector firebug
Web自动化工具:QuickTestProfessional ,selenium
移动端工具:ADB、Monkey、MonkeyRunner
移动端自动化框架:appium、 Robotium、UIAutomator、 Selendroid
服务端压力工具:loadrunner、JMeter
测试分为哪几个阶段
单元测试
集成测试
系统测试
验收测试
如何做好测试计划
5w原则
WHAT(明确测试什么)
WHY(明确测试目标)
WHEN(明确项目开始、结束时间)
HOW(明确测试方案)
WHERE(明确资料的位置)
常见的测试用例设计方法有哪些
等价类划分法
边界值分析法
错误推测法
正交表分析法
场景分析法
因果图法
一条bug记录都包含哪些内容
bug所属模块
bug状态(新建、已修复、已验证、遗留等)
bug出路记录
如何分层自动化测试
UI自动化回归
接口自动化
单元测试-白盒测试
如何保证脚本有效性
保证定位有效性,封装处理异常
保证流程有效性,封装独立方法
保证数据有效性,数据备份与恢复
如何降低自动化维护成本
UI自动化,针对不常态的页面
接口自动化,周期短,变动频繁
框架分层,用例与框架分离
常见测试覆盖类型
语句覆盖
判定覆盖
条件覆盖
判定/条件覆盖
条件组合覆盖
路径覆盖
B/S和C/S架构什么区别
c/s是Client/Server或客户/服务器模式.,如:杀毒软件
b/s是Brower/Server的缩写,如:百度
安全性测试都包含哪些内容
用户访问认证
传输数据加密
安全防护策略:如安全日志、入侵检测、隔离防护、漏洞扫描
数据备份与恢复
防病毒系统
SQL注入、JS注入
测试报告都包含哪些内容
测试背景说明
测试范围说明
测试环境说明
测试方法说明
测试结果结论
质量或分险评估
Alpha测试与Beta测试的区别
Alpha测试是由一个用户在开发环境下进行的测试
Beta测试在用户真实环境测试,通过后进入发布阶段
bug的类型都有哪些
Bug,有代码编写错误导致的功能问题
Defect即缺陷,实现与需求不一致
Fault即故障,由于环境系统问题引起运行失败
Error即错误,语法错误,逻辑错误,不易发现
说一下面向对象的概念
面向对象编程:简称oop,是一种程序设计思想
主要包括:类、继承、多态、实例、属性、方法
# -*- coding: utf-8 -*-
什么是进程、线程、协程
进程:独立数据空间。进程间不共享数据,系统调度
线程:执行程序的最小单元,进程内线程间共享资源,系统调度
协程:程序员调度,分解一个线程成为多个“微线程”
进程
# 进程from multiprocessing import Processdef foo(i):print("This is Process", i)for i in range(5):p = Process(target=foo, args=(i,))p.start()输出:This is Process 0This is Process 1This is Process 2This is Process 3This is Process 4
线程
# 线程import threadingdef show(i): print('This is Thread', i)for i in range(5): t = threading.Thread(target=show, args=(i,)) t.start()输出:This is Thread 0This is Thread 1This is Thread 2This is Thread 3This is Thread 4
协程
# 协程import geventdef foo(): print("start_foo") gevent.sleep(2) print("end_foo")def bar(): print("start_bar") gevent.sleep(0) print("end_bar")gevent.joinall({ gevent.spawn(foo), gevent.spawn(bar),})
如何使用python实现socket编程
Socket又称套接字,应用程序通过套接字向网络发出请求
应用程序通过套接字应答网络请求
使主机间或者一台计算机上的进程间可以通讯
socket-server.py
# -*- coding: utf-8 -*- # !/usr/bin/python3 # author by : yuxiangShi # tell by: 18538187569 # 服务端 # 导入socket模块import socket # 创建socket对象s = socket.socket() # 绑定端口s.bind(("127.0.0.1", 6666)) # 等待客户端连接s.listen(5)while True: # 建立客户端连接c, addr = s.accept()print('连接地址:', addr)c.send("Welcome") # 关闭连接c.close()
socket-client.py
# -*- coding: utf-8 -*- # !/usr/bin/python3 # author by : yuxiangShi # tell by: 18538187569 # 导入模块 import sockets = socket.socket() s.connect(("127.0.0.1", 6666)) server_reply = s.recv(1024)print(server_reply) s.close()
什么是lambda函数
匿名函数,即没有函数名的函数
# -*- coding: utf-8 -*- # !/usr/bin/python3 # author by : yuxiangShi # tell by: 18538187569 # 计算平方 def square(x): return x ** 2 print(square(10)) # lambda表达式 r = lambda x: x ** 2print(r(10)) 输出:100100
tuple和list什么区别
tuple为元组,list为列表
tuple的元素不可改
list的元素可修改
# -*- coding: utf-8 -*- # !/usr/bin/python3 # author by : yuxiangShi # tell by: 18538187569 tuple_a = (1, 2, 3, 4, 5) list_b = [1, 2, 3, 4, 5] tuple_a[0] = 10 list_b[0] = 10 print(tuple_a) print(list_b)
range函数的用法
返回一系列连续增加的整数
工作方式类似于分片
可以生成一个列表对象
# -*- coding: utf-8 -*- # !/usr/bin/python3 # author by : yuxiangShi # tell by: 18538187569 # range生成从0到100的列表 alist = range(0, 100) print(alist) # 设置步长为2 blist = range(2, 101, 2) print(blist)
字符串的拆分方法有哪些
string对象的split方法,不允许有多个分隔符
函数re.split(),允许为分隔符指定多个正则模式
# -*- coding: utf-8 -*- # !/usr/bin/python3 # author by : yuxiangShi # tell by: 18538187569 line = "I am super man!" # string的split方法 print(line.split(" ")) # re的split方法import reprint(re.split("[m]", line)) 输出:['I', 'am', 'super', 'man!']['I a', ' super ', 'an!']
单引号、双引号、三引号的区别
单引号,双引号没有区别,都可以用来表示字符串
三引号,字符串可以直接换行
*args,**kwargs什么作用?
*args,可变的参数列表
**kwargs,键值对参数列表
# -*- coding: utf-8 -*- # !/usr/bin/python3 # author by : yuxiangShi # tell by: 18538187569 # args # def test_args(first, *args): # print(first) # for v in args: # print("args %s" % v) ### test_args(1, 2, 3, 4, 5) # kwargsdef test_kwargs(first, *args, **kwargs): print(first)for v in args: print("args %s" % v)for k, v in kwargs.items(): print("kwargs", (k, v))test_kwargs(1, 2, 3, 4, 5, k0=4, k1=5, k2=6) 输出:1args 2args 3args 4args 5kwargs ('k0', 4)kwargs ('k1', 5)kwargs ('k2', 6)
python中pass语句的作用
占位符,实现一个空函数
re模块中match和search方法的不同
search,扫描整个字符串查找匹配
match,只在字符串的开始位置匹配
# -*- coding: utf-8 -*- # !/usr/bin/python3 # author by : yuxiangShi # tell by: 18538187569 import res1 = "helloworld,helloworld" w1 = "hello" w2 = "world" # search扫描整个字符串 print(re.search(w1, s1)) # print(re.search(w1, s1).group()) # match只在字符串开始位置匹配 print(re.match(w1, s1)) # print(re.match(w1, s1).group())
解释一下WSGI和FastCGI的关系
CGI:公共网关接口(CommonGateway Interface)
HTTP服务器与机器上的程序进行交互的一种工具
程序须运行在网络服务器上,和语言无关
解释一下WSGI和FastCGI的关系
WSGI:Python Web Server Gateway Interface
Python 应用程序和WEB服务器之间的一种接口
FastCGI像是一个常驻(long-live)型的CGI,它可以一直执行着
python是如何操作文件
打开文件
写入或读取数据
关闭文件
# -*- coding: utf-8 -*- # !/usr/bin/python3 # author by : yuxiangShi # tell by: 18538187569 # 写文件 f = open('test.txt', 'wt') f.write("hello world")f.close() # 使用with,追加内容,不用关系文件关闭问题 with open("test.txt", 'at') as f:f.write("\nhello mook") # 读取文件 with open("test.txt", 'rt') as f:print(f.read())
python的内存管理机制
引用计数
垃圾回收
内存池
# -*- coding: utf-8 -*- # !/usr/bin/python3 # author by : yuxiangShi # tell by: 18538187569 from sys import getrefcount # 引用计数a1 = 1000000a2 = 1000000d el a1del a2 print(id(a1)) print(id(a2)) # 检验a1和a2是同一个东西 print(a1 is a2) # 获取a2的引用计数 print(getrefcount(a1))
dict的items与iteritems区别
itmes方法以列表方法返回,返回时没有特殊顺序
iteritems方法类似,但返回的是一个佚代器对象
# -*- coding: utf-8 -*- # !/usr/bin/python3 # author by : yuxiangShi # tell by: 18538187569 test1 = {'key1': 2, 'key1': 3, 'key1': 4} kv1 = test1.items() # print(next(kv1)) kv2 = test1.iteritems() print(next(kv2)) print(next(kv2)) print(next(kv2))
基于python常问算法有哪些?
排序 > 从小到大排序:sorted(list) > 从大到小排序:sorted(list,reverse=True)
# -*- coding: utf-8 -*- # !/usr/bin/python3 # author by : yuxiangShi # tell by: 18538187569 alist = [0, 10, 88, 19, 9, 1] print(sorted(alist)) print(sorted(alist, reverse=True)) alist.sort() print(alist) alist.sort(reverse=True) print(alist) 输出:[0, 1, 9, 10, 19, 88][88, 19, 10, 9, 1, 0][0, 1, 9, 10, 19, 88][88, 19, 10, 9, 1, 0]
冒泡 > 比较相邻的元素,如果第一个比第二个大,就交换 > 一轮遍历,每两相邻元素,重复1,最大放队尾 > 不包括已经排队尾,重复2
# -*- coding: utf-8 -*- # !/usr/bin/python3 # author by : yuxiangShi # tell by: 18538187569 # 冒泡排序 def bubble_sort(list): # 获取数组长度 count = len(list) - 1 # N个元素遍历N次 for index in range(count, 0, -1): # 第一个和第i+1个依次对比 for sub_index in range(index): # 最大的元素冒上去 if list[sub_index] > list[sub_index + 1]: list[sub_index], list[sub_index + 1] = list[sub_index + 1], list[sub_index] return listalist = [0, 10, 88, 19, 9, 1] print(bubble_sort(alist)) 输出:[0, 1, 9, 10, 19, 88]
快排 > 从列表中挑出一个元素,作为基准值key > 所有小于key的元素放左边,所有大于key的元素放右边 > 分别递归左侧列表,右侧列表
# -*- coding: utf-8 -*- # !/usr/bin/python3 # author by : yuxiangShi # tell by: 18538187569 # 快速排序 def quick_sort(lists, left, right): # 递归过程中,发现left和right一致时,停止递归,直接返回列表 if left >= right: return lists # 定义游标low = lefthigh = right # 取参考标志,最左边的元素key = lists[low]while low < high: # 从最右侧向左,依次和标志元素对比,如果右侧的元素大于标志元素 while low < high and lists[high] >= key: # 右侧减1 high = 1 # 否则low赋high值 lists[low] = lists[high] # 从最左侧向右,依次和标志元素对比,如果左侧的元素小于标志元素 while low < high and lists[low] <= key: # 右侧加1 low += 1 # 否则high赋low值 lists[high] = lists[low] # 最后给high位置符值lists[high] = key # 处理左侧元素quick_sort(lists, left, low - 1) # 处理右侧元素quick_sort(lists, low + 1, right) return listsalist = [0, 10, 88, 19, 1, 7] print(quick_sort(alist, 0, 6))
堆排序 > 堆排序指利用的数据结构设计的一种排序算法 > 堆近似一个完全二叉树结构 > 子结点的键值小于(或者大于)它的父节点
# -*- coding: utf-8 -*-# !/usr/bin/python3# author by : yuxiangShi# tell by: 18538187569def heap_sort(lst):def sift_down(start, end): """最大堆调整""" root = start print("root %d start %d end %d" % (root, start, end)) while True: child = 2 * root + 1 print("child index: %d" % child) # 终止条件,孩子的索引值超过数组最大长度 if child > end: break print("lst child value:%d" % lst[child]) # 确定最大的孩子节点的索引值 if child + 1 <= end and lst[child] < lst[child + 1]: child += 1 print("child+1 index: %d" % child) # 孩子节点最大值和根节点交换 if lst[root] < lst[child]: lst[root], list[child] = lst[child], lst[root] print("lst root %d" % lst[root], "lst child %d" % lst[child]) root = child print("root %d" % root) else: break print("--------创建最大值--------") # 创建最大堆 print(xrange((len(lst) - 2) // 2, -1, -1)) for start in xrange((len(lst) - 2) // 2, -1, -1): print("---->Loop start %d" % start) sift_down(start, len(lst) - 1) print(lst) print("--------排序过程----------") # 堆排序 for end in xrange(len(lst) - 1, 0, -1): # 首尾交换 lst[0], lst[end] = lst[end], lst[0] # 剩余重新堆排序 sift_down(0, end - 1) print(lst) return lstalist = [70, 60, 12, 40, 30, 8, 10]print(heap_sort(alist))
二分查找 > 二分查找又称折半查找 > 必须采用顺序存储结构 > 必须按关键字大小有序排列
# -*- coding: utf-8 -*-# !/usr/bin/python3# author by : yuxiangShi# tell by: 18538187569alist = [0, 1, 10, 88, 19, 9, 1]def binary_search(arr, start, end, hkey):if start > end: return -1mid = start + (end - start) / 2if arr[mid] > hkey: return binary_search(arr, start, mid - 1, hkey)if arr[mid] < hkey: return binary_search(arr, mid + 1, end, hkey)return midalist = sorted(alist)print(alist)print(binary_search(alist, 0, 6, 9))
素数 > 素数又称质数 > 0,1不是素数 > 除了1和它自身外,不能被其他自然数整除的数
# -*- coding: utf-8 -*-# !/usr/bin/python3# author by : yuxiangShi# tell by: 18538187569# 0,1不是素数# 除了1和它自身外,不能被其他自然数整除的数def is_prime(n):if n <= 1: return Falsefor i in range(2, n - 1): if n % i == 0: return False return Truefor i in range(0, 100):if is_prime(i): print(i)
基础命令
cd 切换目录
ls -l 列出文件详细信息;ls -a 列出当前目录下所有文件
touch 创建文件;mkdir 创建目录
echo 创建带有内容的文件
cat 查看文件内容
cp 拷贝
mv 移动或重命名
rm -r 递归删除;rm -f 强制删除
wc统计文本中行数、字数、字符数
grep 在文本文件中查找某个字符串
tree 显示目录结构
ln 创建软链
more、less 分页显示文本内容
head、tail显示文件头尾内容
网络命令
curl 利用URL规则在命令下工作的文件传输工具
netstat 显示网络状态信息
telnet 用于登录主机
系统命令
ping 测试网络连通
man 查看帮助
kill 杀死进程
top 动态显示当前耗费资源最多进程信息
ps 显示瞬间进程状态
df 查看磁盘大小 df -h 带有单位显示磁盘信息
OSI七层模型指的是哪些内容
物理层,建立、维护、断开物理连接
数据链路层,逻辑链接、硬件地址寻址、差错校验
网络层,逻辑地址寻址,不同网络之间的路径选择,IP
传输层,传输数据的协议,TCP、UDP
会话层,建立、管理、终止会话,本地与远程主机的会话
表示层,数据的标示、安全、压缩、JPEG、ASCII等
应用层,与最终用户的接口,HTTP、HTTPS、SMTP等
http协议中get、post的区别
功能差异
数据传输
安全性
tcp和udp的区别
[image:C0E62692-F54F-4E32-AAD0-DC732B83FBBF-275-00022443262E7424/95E38541-6E13-492C-B105-F0E2CE67127C.png]
TCP连接三次握手具体过程
socket建立连接的过程
服务器建立监听,socket,bind,listen
客户端发送请求,connect,send
连接确认,accept, response
操作系统相关问题
进程与线程的区别? > 进程:独立数据空间。进程间不共享数据,系统调度 > 线程:执行程序的最小单元,进程内线程间共享资源,系统调度 > 一个进程可以有多个线程,多个线程也可以并发执行
进程都有哪些状态? > 就绪状态:已获除处理以外所需资源,等待分配处理机资源 > 运行状态:占用处理机资源运行,此状态进程数<=CPU数 > 阻塞状态:进程等待某种条件,在条件满足之前无法执行
进程同步与互斥的区别? > 互斥:某一资源同时只允许一个访问者对其进行访问 > 具有唯一性和排他性 > 互斥无法限制访问者对资源的访问顺序,即访问是无序的 > 同步:基于互斥,经其他机制实现访问者对资源的有序访问 > 大多数情况下,同步已经实现了互斥,写入资源是互斥的 > 少数情况下,可以允许多个访问者同时访问资源
进程间通信都包括哪些? > 管道:半双工通方式,数据单项流动,父子进程间 > 命名管道:半双工通信方式,无亲缘关系进程间通信 > 信号量:是计数器,锁机制,控制多进程对资源访问 > 消息队列:消息链表,存放在内核中消息队列标识符标识 > 信号:比较复杂的通信方式,通知进程某个事件已经发生 > 共享内存:映射一段能被多个进程可访问的内存
进程的调度算法都有哪些? > 先来先服务 > 短作业服务优先 > 时间片轮转调度算法 > 高响应优先 > 优先权调度算法 > 多级队列调度算法
死锁产生的原因? > 资源竞争;进程推进顺序不当 > 必要条件:互斥,不剥夺,请求与保持,环路等待 > 预防死锁:破坏四个必要条件之一
页面的置换算法都有哪些? > 最佳置换算法 > 先进先出置换算法 > 最近最久未使用置换算法 > Clock置换算法,也叫最近未使用算法 > 最少使用置换算法
makefile的作用是什么? > 定义规则,指定哪些文件先翻译、后编译、重新编译 > Makefile的好处,自动化编译 > makefile需要make工具解释执行
什么是虚存、实存、共享内容? > 虚存(VIRT=SWAP+RES):进程“需要的”虚拟内存大小 > 包括进程使用的库、代码、数据,以及malloc、new分配的堆空间和分配的栈空间等 > 申请10MB,使用1MB,增长10MB > 实存(RES=CODE+DATA): > 包括使用中的malloc、new分配的堆空间和分配的栈空间,但不包括swap out量 > 申请10MB,使用1MB,增长1MB > 共享内存(SHR):自身,也包括其他进程的共享内容 > 进程只使用了几个共享库的函数,但包含真个共享库大小 > 某个进程所占的物理内存大小:RES - SHR
Fiddler工具都有哪些功能
如何抓取手机包
如何配置fake response、fake request
数据包request、response中的字段含义
如何实现慢网速
如果抓取的数据过多怎么处理
模拟不同的状态吗,200、302、404、502
Android系统相关的问题
Android的四大组件是什么? > Activity:程序与用户的交互窗口 > Service:在程序后台,完成用户的操作 > ContentProvider:提供数据的统一访问格式 > BroadcastReceiver:应用程序之间传输信息的机制
Activity的生命周期是什么?
什么是ANR? > ANR:Application Not Responding > Actiivity的最长执行时间是5秒 > 用户可以选择“等待”让程序继续运行,或“强制关闭”
Android常见的五种布局是什么? > FrameLayout(框架布局) > LinearLayout(线性布局) > AbsoluteLayout(绝对布局) > RelativeLayout(相对布局) > TableLayout(表格布局)
Android中动画有哪几种类型? > Tween动画,组件移动、缩放、透明度的变化 > Frame动画,通过顺序播放来实现,类似电影
ADB相关的问题?
如何重启adb服务?
adb kill-server # 停止服务adb start-server # 启动服务
App的安装与卸载
adb -s <devicename> install <path-to-apk> # 安装adb -s <devicename> install -r <path-to-apk> # 安装adb -s <devicename> uninstall <packagename> # 卸载
如何在电脑和手机之间传输数据?
adb push *.apk /data/local/tmp/*.apk adb pull /data/local/tmp/*.apk *.apk
如何静默安装App?
adb push *.apk /data/local/tmp/*.apk adb shell pm install -f /data/local/tmp/*.apk
如何使用adb启停一个App?
adb shell am start -W -S package/activiyadb shell am force-stop package
如何通过某个关键词查找已安装的包?
adb shell pm list package -f keywordadb shell pm list package -3 keywordadb shell pm list package -i keyword
如何截屏、录屏?
adb shell screencap /data/local/tmp/screen.pngadb shell screenrecord /data/local/tmp/demo.mp4
如何抓取logcat日志?
adb logcatadb shell logcat
如何获取当前的cpu、内存状态?
adb shell dumpsys meminfo packageadb shell dumpsys cpuinfo | findstr package
Monkey相关的问题?
Monkey进行压力测试的命令?
adb shell monkey -p <packagename> <count>
如何重现Crash、ANR过程?
添加参数 -s seed
如何提取Crash、ANR的信息? > 将monkey执行过程中的日志重定向到文件 > 测试版App连接第三方统计平台
如何设置monkey运行8个小时?
添加参数 --throttle
在Crash/ANR后,如何继续执行?
添加忽略Crash参数 --ignore-crashes添加忽略ANR参数 --ignore-timeouts
如何让monkey执行指定的事件? > 触摸事件—pct-touch > 动作事件—pct-motion > 轨迹球事件—pct-trackball > 基本导航事件—pct-nav > 主要导航事件—pct-majornav > 系统导航事件—pct-syskeys > 应用启动事件—pct-appswitch > 其他类型事件—pct-anyevent
Instrumentation
Instrumentation原理是什么? [image:40185C44-D79C-4C13-A9BA-38B7027D780C-275-0002541F1D5DB1C5/3D642E82-B0EA-48D5-BF0B-920C1EDEF971.png]
Instrumentation测试是什么? > 功能性测试 > Activity生命周期的测试 > 模拟数据库操作的测试和兼容性测试
什么情况使用Instrumentation? > 使用Java JUnit框架 > 需要进行白盒测试时 > 需要使用mock技术模拟系统对象时
UIAutomator
UIAutomator原理是什么? > UIAutomator是Android UI自动化测试工具 > 不需要源码,基于Java开发语言 > UiDevice,UiSelector,UiScrollable,UiObject,UiCollection
UIAutomator可以测试什么? > APP UI层的交互操作 > 不需要源码,可以模拟跨进程过程 > 基于Java JUnit框架,黑盒UI自动化
如何识别App视图内的元素? > UiAutomatorViewer > 可以识别元素的id、classname、bounds等
Selendroid&Robotium
Selendroid的原理是什么?
Selendroid四大组件: > Selendroid Client:Webdriver + 移动特性的实现 > Selendroid Server:一个Instrumentation APK > AndroidDriver-App:一个WebViewActivity,即浏览器 > Selendroid-Standalone:大总管,负责准备环境
Robotium的原理是什么? > 基于Instrumentation进行封装,实现的Android测试框架 > 封装了一个Solo类库,提供自动化测试API > 由于是基于Instrumentation,测试时需要源码
Appium
什么是Appium? > 一个开源的移动端UI自动化测试框架
Appium的理念是什么? > 不需要App源码 > 不局限于语言或者框架 > 接口统一,不需要重复开发 > 必须是开源的
Appium相关的概念都有哪些? > C/S架构,Appium核心是一个web服务器 > Session,客户端初始化session与服务端交互 > Desired Capabilites,初始化时的键值对组合 > Appium Server,操作与驱动手机的 > Appium Client,支持多语言调用
Appium环境都包括哪些内容? > Android SDK、JDK、Appium > Pycharm、Python环境 > 库:Selenium、Appium-Python-Client
Appium都支持哪些开发语言? > Java、Javascript、PHP、Python > Ruby、C#、Perl、Object C
Appium初始化时都需要配置哪些内容? > platformName,目标设备平台Android/iOS > platformVersion,目标设备的平台版本 > appPackage,App包名(Android) > AppActivity,App Activity名称(Android) > automationName,自动化启动类型Selendroid/Appium > unicodeKeyboard,是否使用Appium输入法 > resetKeyboard,是否恢复默认键盘
Appium测试Native App的原理是什么?
如何自动化测试Native App?
元素的定位、识别工具? > 第一个选择,使用UIAutomatorViewer > 第二个选择,使用Appium的Inspector
定位元素的API都有哪些? > find_element_by_accessibility_id > find_element_by_id > find_element_by_name > find_element_by_xpath > find_element_by_class_name
脚本的编写规则 > LOVE规则 > L:Locate定位 > O:Operate操作 > V:Verify验证 > E:Exception异常的处理
初始化注意事项 > 不需要指定App的包路径 > 默认使用Appium驱动 > 如果需要输入中文,需要添加输入法相关的配置
Appium测试Hybrid App的原理是什么?
如何自动化测试Hybrid App?
元素的定位、识别工具? > Native部分,UIAutomator或者Appium Inspector > WebView部分,Chrome浏览器的调试模式
定位元素的API都有哪些? > find_element_by_id > find_element_by_name > find_element_by_xpath > find_element_by_link_text > find_element_by_tag_name > find_element_by_class_name > find_elements_by_id > find_elements_by_name > find_elements_by_xpath > find_elements_by_link_text > find_elements_by_tag_name > find_elements_by_class_name
脚本的编写规则 > S-LOVE规则 > S:Switch > L:Locate定位 > O:Operate操作 > V:Verify验证 > E:Exception异常的处理
初始化注意事项 > 需要明确指定驱动名称为:Selendroid > 需要明确指定App的路径,因为需要重签名
Appium测试iOS App的原理是什么?
如何使用selenium测试WEB页面?
都需要准备哪些环境? > 工具:Pycharm、chrome > 包:selenium、Python > webdriver:chrome driver/firefox driver/ie driver等
元素识别工具是什么? > firefox或者chrome的调试工具
元素定位的方法都有哪些? > find_element_by_id > find_element_by_name > find_element_by_xpath > find_element_by_link_text > find_element_by_tag_name > find_element_by_class_name > find_elements_by_id > find_elements_by_name > find_elements_by_xpath > find_elements_by_link_text > find_elements_by_tag_name > find_elements_by_class_name
如何使用Appium测试WAP页面?
都需要准备哪些环境? > IDE:PyCharm > 包:Python、Selenium、Appium-python-client > 工具:Appium、Chrome
元素的识别 > chrome浏览器调试wap页面
脚本的编写 > 初始化时,指定browsername为:Browser > 自动化测试代码和selenium代码相同
unittest原理
unittest框架都包含哪些内容? > TestFirxture:setUp、TestCase、TearDown
# -*- coding: utf-8 -*-# !/usr/bin/python3# author by : yuxiangShi# tell by: 18538187569import unittestclass MyTestCase(unittest.TestCase):# 每条用例初始化def setUp(self) -> None: self.initdata = "hello imooc"# 测试用例、以test开头def test_something(self): self.assertEqual("hello imooc", self.initdata)# 每条用例执行完后释放资源def tearDown(self) -> None: passif __name__ == '__main__':# 声明一个suitesuite = unittest.TestSuite()# 从类加载用例集cases = unittest.TestLoader().loadTestsFromTestCase(MyTestCase)# 添加用例到suitesuite.addTests(cases)# 声明TestRunnermyTestRunner = unittest.TextTestRunner(verbosity=2)# 执行RunnermyTestRunner.run(suite)
TestCase TestSuite TestRunner
DDT-数据驱动
什么是数据驱动? 数据驱动测试,即黑盒测试,又称为功能测试 数据驱动单元测试为数据源中的每行重复进行一种单元测试 数据驱动单元测试,常用情况是使用多个输入值测试API
DDT的原理是什么? Python下的数据驱动框架名称也叫DDT(Data-Driven Tests) 效果:使用多个数据运行一条用例,使其表现为多条用例 原理:通过Python的装饰器、装饰每条用例
如何使用DDT测试搜索功能?
# -*- coding: utf-8 -*-# !/usr/bin/python3# author by : yuxiangShi# tell by: 18538187569import unittestfrom appium import webdriverfrom ddt import ddt, dataimport time@ddtclass MyTestCase(unittest.TestCase):# 初始化def setUp(self) -> None: desired_caps = {'platformName': 'Android', 'platformVersion': '5.1', 'deviceName': '192.168.56.102:5555', 'browerName': 'Browser', 'unicodekeyboard': 'True', 'resetKeyboard': 'True'} self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)# 释放资源def tearDown(self) -> None: self.driver.quit()@data(u"Android 专项测试 Python篇", u"Javascript")def test_searchkeyword(self, keyword): # 打开首页 self.driver.get('http://www.imooc.com') # 等待加载完成 time.sleep(3) # 定位输入框 input = self.driver.find_element_by_xpath("/html/body/header/div/input") # 定位搜索按钮 button = self.driver.find_element_by_xpath("/html/body/header/div/form/div/div/button") # 点击搜索 button.click() # 等待页面加载完成 time.sleep(3) # 定位搜索结果的首条 result0 = self.driver.find_element_by_xpath('//*[@id="pages-container"]/div/div[1]/dl/dd[1]/a/div/p[1]') # 验证包含关键词 self.assertTrue(keyword in result0.text)if __name__ == '__main__':suite = unittest.TestSuite()cases = unittest.TestLoader().loadTestsFromTestCase(MyTestCase)suite.addTest(cases)myTestRunner = unittest.TextTestRunner(verbosity=2)myTestRunner.run(suite)数据驱动测试的意义? 代码复用率高,一次编写多条数据复用逻辑 异常排查效率高,测试执行隔离,数据间无影响 代码可维护性高,提高代码的易读性
Lettuce-行为驱动
什么是行为驱动? 行为驱动开发,Behavior-Driven Development,简写BDD 在软件工程中,BDD是一种敏捷开发的技术
Lettuce的原理是什么? Lettuce是基于Python语言的行为驱动测试框架 Lettuce将测试用例和自动化测试代码分离 Lettuce写测试用例就像写文本一样清晰
行为驱动的实现? 行为驱动测试实例
KDT-关键词驱动
什么是关键词驱动? 关键词驱动测试也称为表格驱动测试或行动驱动测试 它将创建测试程序的步骤分为规划及实现二个阶段 关键词驱动使不懂代码的人可以完成自动化过程
Robot Framework的原理是什么? 基于RIDE可视化工具,导入AppiumLibrary 使用AppiumLibrary中提供的关键词,实现用例过程 使用RIDE完成用例的执行与结果的管理
关键词驱动的实现?
API测试框架
如何实现一个API测试框架
Python Requests API自动化
如何使用Python Request发送Get请求?
如何使用Python Request发送Post请求?
如何实现一个API测试框架?
持续集成的理念
说一下什么是持续集成? > 持续集成是指开发阶段,对项目进行持续性 > 自动化编译、测试,以达到控制代码质量的手段 > 持续集成是一种软件开发实践
持续集成都包括哪些内容? > 开发人员、版本控制 > CI服务器、构建脚本 > 反馈机制、集成构建
持续集成的意义是什么? > 减少分险、减少重复过程 > 任何时间、任何地点生成可部署的软件 > 增强项目可见性、建立团队对开发产品的信心
持续集成工具配置
你都用过哪些持续集成的工具? > Jenkins、Buildbot > Travis CI、Strider > Go、Integrity
如何搭建Jenkins持续集成平台? > 下载Jenkins.war > 命令行运行:java -jar jenkins.war > 在浏览器窗口打开:http://localhost:8080
使用Jenkins都需要做哪些配置? > 系统级配置 > 工程级配置
持续集成工具应用
如何配置一个App打包的过程?
如何持续执行脚本?
如何使用持续集成工具执行Monkey?
服务端测试的工具
服务端的压力工具都包括哪些? > LoadRunner > JMeter > 自主研发的工具
服务端的压力测试都需要监控哪些指标? > CPU > 内存(虚存、实存) > QPS、平均相应时间
如何开展服务端的压力测试? > 搭建服务端模块、并启动服务 > 监控进程相关指标,内存、CPU > 监控模块的执行情况,QPS、平均相应时间 > 收集数据并进行分析,生成曲线图 > 根据分析结果,得出测试结论
App兼容性测试
App兼容性测试都考虑哪些因素?
系统版本(Android&IOS平台,不同版本)
分辨率(小屏、大屏、全屏)
手机品牌(华为、小米、OPPO、VIVO等)
WAP兼容性测试都考虑哪些因素?
不同平台的不同浏览器(safari、chrome等)
分辨率(小屏、大屏、全屏)
转发到QQ、微信、微博等第三方平台
PC页面兼容性测试都考虑哪些因素?
操作系统(常用windows、Mac os、平板电脑)
浏览器(IE系列、firefox、chrome等)
分辨率(笔记本、台式机、窗口缩放等)
APP的bug调试
调试APP相关的bug常用哪些工具?
网络相关工具,fiddler、wareshark、Charles
adb、am、logcat等
云平台,bug复现
WAP网页的bug调试
调试WAP页面相关工具有哪些?
Chrome调试工具,可设置移动App UA
WINRE,Web Inspector Remote
PC网页的bug调试
调试PC页面相关工具有哪些?
Chrome调试工具
火狐的firebug