测试笔记

第五单元、性能测试

1.什么是性能测试

        通过自动化的测试工具模拟系统正常、异常、峰值的场景对系统的各项性能指标测试

2.什么是性能

        时间:系统处理用户请求的响应时间

        资源:系统运行过程中,系统资源的消耗情况

3.为什么进行性能测试

        1.评估当前系统的能力

        2.评估软件是否满足未来的需要

        3.寻找性能瓶颈,优化系统性能

        4.招聘需要

4.性能测试的分类

        1.基准测试

            单用户测试/建立基准线,当系统软硬件环境发生变化之后

            再进行一次基准测试以确定变化对性能的影响。

        2.负载测试

            增加系统负载,在满足性能指标的情况下,找出系统所能承受最大负载量的测试

        3.稳定性测试

            服务器稳定运行的情况下进行长时间测试并最终保证服务器能满足线上业务需求

        4.压力测试

            在强压下,查看系统是否具有良好的容错能力和修复能力

        5.并发测试

            在极短时间内,发送多个请求,验证服务器对并发的处理能力

5.性能测试的指标

        1.响应时间  2s  5s  8s

            客户端发送请求开始,到客户端接收到结果的总时间

            服务器处理时间+网络传输时间

        2.并发用户数

            某一时刻同时向服务器发送请求的用户数

        3.吞吐量

            单位时间内处理客户端的请求数量,直接体现软件系统的承载能力。

        4.QPS

            每秒查询数,即控制服务器每秒处理的指定请求的数量

        5.TPS

            每秒事务数,即控制服务数每秒处理事务请求的数量

        6.点击数

            所有页面元素的请求总数量

        7.错误率

            系统在负载情况下,失败业务的概率

        8.资源利用率

            系统各种资源的使用情况    率=资源使用率/总资源可用率*100%

            常见资源指标:

            CPU使用率:不高于75%-85%

            内存大小使用率:不高于80%

            磁盘IO(速率):不高于90%

            网路(速率):不高于80%

        9.业务成功率

            多用户对某一业务发送操作的成功率

6.jmeter的作用

        1.接口测试 面试说postman,因为方便好用。

        2.性能测试 jmeter,也可以用postman(runner),但是没有性能指标

        3.数据库测试

7.线程组是什么?

        概念:性质相同的线程放在一个组内

        线程组包含线程数、准备时长、循环次数

        1.线程数:虚拟用户数

        2.准备时长:启动所有用户的时间

        3.循环次数:每个线程发送请求的次数

8.jmeter主要组件

        1.测试计划

        2.线程组:性质相同的一组线程(线程数、准备时间、循环次数)

        3.采样器:HTTP

协议、主机地址、端口号(选填)、请求方法、路径、编码格式(选填)、参数

        4.监听器:采集测试结构

            察看结果树、用表格查看、聚合报告

        5.循环控制器

        6.事务控制器

            事务:多个操作组合

            作用:

        7.固定定时器

                作用:控制两个采样器的间隔

        8.断言

                1.Json断言:判断某个key对应某个value

                2.响应断言:响应中包含某个串

        9.前置处理器和后置处理器

9.参数化

        1.用户自定义变量:

                作用:提供全局变量,方便修改

                使用:配置元件 → 用户定义的变量 → key value → ${key}

        2.CSV data set config

                配置文件:

                添加元件:CSV data set config → 选中文件 → 编码 → 字段1,字段2

                在采样器界面:添加参数 → 调用${字段名称}

        3.CSV函数小助手

                  工具  → 函数小助手 → 选择CSV Read → 复制文件路径 → 字段编号 → 生成 → 自动复制,过去粘贴

10.接口依赖

        正则语法:* + ? . ()

        实现:

            ①添加HTTP请求,使用正则提取一个需要字段

            ②在第一个HTTP请求里边调用字段${字段}

第六单元 jmeter脚本录制和压测

1.什么是脚本录制

在进行测试的时候,可能有好多脚本或者界面需要操作测试,并且有些测试链接需要重复多线程高并发进行测试,我们一般会针对这一些操作,进行一个脚本录制,录制好之后,之后测试就可以在这个基础上进行测试。

2.脚本录制方式

    web端:badboy脚本录制

    app端:使用Jmeter自带的代理服务器进行脚本录制

3.Android手机端脚本录制

    1.同网

    2.添加http代理服务器

    3.在线程中添加录制控制器

    4.在http代理服务器中指定录制脚本的路径,默认端口8888

    5.查看本地的ip

    6.设置移动端代理,IP和端口号

    7.启动

    8.打开手机app,抓取接口

4.web端脚本录制

安装badboy脚本软件→打开badboy软件→使用

第七单元 Jmeter压测

一.数据库压测

    1.为什么要紧行数据库压测

        不断给数据库施加压力,验证数据库处理的性能

    2.如何进行数据库压测

        1.jdbc配置:创建线程组→添加配置元件JDBC Connection Configuration→对数据库连接的配置进行设置→添加jdbc Request请求→运行

select statement:只支持单条查询,只支持第一条数据查询

updata statement:修改数据

Callable Statement:支持查询、修改、支持多个查询

Prepared Select Statement:类型必须为varchar**结合csv配置数据

二.1.jmeter对服务器压测(windows)

      资源准备:  JMeterPlugins-Extras.jar和JMeterPlugins-Standard.jar放到apache-jmeter-3.0\lib\ext目录下

    操作:打开server的监听→添加监听器-jp@gc - PerfMon Metrics Collector→添加性能指标,线程组设置线程数和时间

    2.jmeter对服务器压测(linux)

同上


第八单元 Python基本语法

一、Python介绍

    Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言

二、发展历程

Python: Guido van Rossum 八十年代末和九十年代初 荷兰

三、Python的特点

易于学习, 易于阅读, 易于维护, 一个广泛的标准库, 互动模式的支持

可移植, 可扩展, 提供数据局接口,GUI编程,可嵌入

四、Pycharm及python安装详细教程

五、Python变量和数据类型

Python3 的六个标准数据类型中:

不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);

可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)

六、标识符

. 标识符只能由字母、下划线“_”、数字组成。

. 标识符不能以数字开头。

. 标识符不能使用关键字

. 标识符对大小写敏感。

(建议:标识符命名应“见名知意”)

七、关键字

'False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield'

八、运算符

算术运算符: +,-,*,/,%,**,//

逻辑运算符:and, or, not

比较运算符: ==, !=, >,<,>=,<=

赋值运算符:=, +=, -=, /=, %=, **=, //=, :=

第九单元 python基础--语句

一、判断语句

if语句的使用格式

if 要判断的条件:

       条件成立时,要做的事情

if-else的使用格式

if要判断的条件:

   条件成立时,要做的事情

else:

   条件不成立时,要做的事情

if-elif-else的使用格式

if要判断的条件:

   条件成立时,要做的事情

elif要判断的条件:

   条件成立时,要做的事情

else:

   条件不成立时,要做的事情

if嵌套

if要判断的条件:

   条件成立时,要做的事情

if要判断的条件:

       条件成立时,要做的事情

else:

       条件不成立时,要做的事情

else:

   条件不成立时,要做的事情

二:循环语句

while循环的格式

while条件:

   条件成立时,要做的事情

   条件成立时,要做的事情

   .....

while循环嵌套

while条件:

   条件成立时,要做的事情

   条件成立时,要做的事情

   .....

while条件:

       条件成立时,要做的事情

       条件成立时,要做的事情

       .....

for循环

for 临时变量 in 列表或者字符串等可迭代对象:

   循环满足条件时执行的代码

pass的使用

1.Pythonpass是空语句,是为了保持程序结构的完整性。

2.pass不做任何事情,一般用做占位语句。

第十单元列表

1.格式:listName=[元素,元素]

2.特点:有序,可重复,可变,任意类型,性能不好

3.增:

        1.append:list.append(元素),追加到末尾

2.extend:list.extend(元素),追加到末尾,散开添加

3.insert:list.insert:(index,元素),添加元素到指定位置,如果新增的索引不存在添加到末尾

4.改:list[index]=新元素

注意:如果index存在则修改,不存在则越界

5.删

1.del:del list[index],删除指定下标对应的元素,如果index不存在,则报错索引越界

2.pop:list.pop(),删除末尾元素

3.remove:删除指定元素,list.remove(元素),如果元素不存在报错

6.查

1.list.index(元素):查看元素下标

2.list.count(元素):查询列表中的元素的个数

7.排序:

1.升序:list.sort()

2.降序:

1.list.sort(Reverse=True)

2.list.sort().reverse()

注意:如果不是数字,则报错

8.列表的循环取值

1.for

for i in list:

    list[i]

2.while

i=0

while 条件:

    list[i]

    i+=1

9.list嵌套

1.格式:list=[list1,list2,list3]

2.取值:list[外层下标][内层下标】

3.删除:del [外层下标][内层下标】

4.添加:list[外层下标].insert(内层插入下标,元素)

5.[外层下标][内层下标】=值

第十一单元 元组和字典

1.格式:t=(元素,元素)

2.特点:有序,可重复,不可变,任意类型

3.访问元组

索引值存在:print(t[2])

索引值不存在:报错

4.查询:

1.查询个数:t.count(元素

2.查询下标:t.index(元素)

5.修改:不可修改,虚转换类型

6.类型转换

列表转换元祖

aa = [23,34,45,56,67]

tuple(aa)

print(aa)

#[23, 34, 45, 56, 67]

元组转换列表

aTuple=('b','c','d','e','f','g')

a = list(aTuple)

print(a)

#['b', 'c', 'd', 'e', 'f', 'g']

7.元组的循环取值

1.for

for i in aTuple:

   print(i)

2.while

i=0

while i < len(aTuple):

   print(aTuple[i])

   i=i+1


第十一单元 元组和字典

一.元组

1.格式:t=(元素,元素)

2.特点:有序,可重复,不可变,任意类型,性能好

3.访问元组

索引值存在:print(t[2])

索引值不存在:报错

4.查询:

1.查询个数:t.count(元素)

2.查询下标:t.index(元素)

5.修改:不可修改,虚转换类型

6.类型转换

列表转换元祖

aa = [23,34,45,56,67]

tuple(aa)

print(aa)

#[23, 34, 45, 56, 67]

元组转换列表

aTuple=('b','c','d','e','f','g')

a = list(aTuple)

print(a)

#['b', 'c', 'd', 'e', 'f', 'g']

7.元组的循环取值

1.for

for i in aTuple:

   print(i)

2.while

i=0

while i < len(aTuple):

   print(aTuple[i])

   i=i+1

二.字典

1.格式:变量名={key1:value,key2:value}

2.特点:有序,不可重复,可变,任意类型,性能不好

3.根据键访问

1.z={key1:value,key2:value}

print(z["key"])

2.z={key1:value,key2:value}

print(z.get("name"))

4.修改

1.有对应的key

z["key"]="value"

print(z)

2.没有对应的key是新增数据到末尾

5.添加

z["key"]="value"

6.删除

1.del

del z["key"]

print(z)

2.clear:清空字典里的内容

z.clear()

print(z)

7.长度

print(len(z))

8.字典循环

1.取出key

for i in z.keys():

   print(i)

2.取出value

for i in z.values():

   print(i)

3.取出key和value方法一

for i,j in z.items():

   print(i,j,sep=":")

4.取出key和value方法二

for i in z.keys():

   print(i,z[i],sep=":")

5.扩充的

for i,j in enumerate(z):

   print(i,j,z[j])

十二单元

一、集合

1.集合的特点:无序、唯一、去重

2.格式:j={元素,元素}

3.添加:

1.j.add(元素)

2.

j={1,"vfd",5,2,"vedfbrgb"}

i=["小何","真美",48]

j.update(i)

4.删除

1.remove:删除集合中的元素 如果有直接删除 如果没有程序报错

j.remove(元素)

2.pop:都是数字,删最小的,其余升序排序;

  都是非数字,随机删,其余随机排序;

数字和非数字,随机删,删数字的话就是最小的,删非数字的话,随机删

注意:如果集合中没有元素,则报错

j.pop()

3.discard:如果元素存在直接删除 如果元素不存在不做任何操作

j.discard(元素)

5.交集

连接多个集合,输出相同的元素(set可用)

    j={1,"vfd",5,2,"vedfbrgb"}

•      i={5,2,"小","美",48}

•      a=j&i

•      print(a)   #{5,2}

6.并集

去重,得到全部集合中全部的元素

    j={1,"vfd",5,2,"vedfbrgb"}

•      i={5,2,"小","美",48}

•      a=j|i

•      print(a)   #{1, 2, 5, 48, '真', '小', 'vfd', 'vedfbrgb'}

7.公共方法

1.加(列表和元祖可用)

j=(1,"vfd",5,)

i=(5,48)

print(j+i)  #(1, 'vfd', 5, 5, 48)

2.乘(列表和元祖可用)

j=(1,"vfd",5,)

i=(5,48)

print(j*2)  #(1, 'vfd', 5, 1, 'vfd', 5)

3.包含(in)(列表和元祖和字典可用)

j=(1,"vfd",5,)

print(1 in (j))   #True

j=(1,"vfd",5,)

print(6 in (j))   #False

4.不包含(no in)(列表和元祖和字典可用)

j=(1,"vfd",5,)

print(1 not in (j))   #False

j=(1,"vfd",5,)

print(6 not in (j))   #True

8.内置函数

长度:print(len(变量名))

最大值:print(max(变量名))

最小值:print(min(变量名))

del:第一种:del 变量名

第二种:del(变量名)

二、函数

1.什么是函数

其实就是方法、功能

2.函数的定义和调用

格式:

def函数名():

执行语句

函数名()

3.函数参数

1.正常的

defadd2num():

a=11

b=22

c=a+b

printc

2.位置参数

def函数名(参数1,参数2):

代码块

函数名(值1,值2)

3.关键字参数

def函数名(参数1,参数2):

代码块

函数名(参数1=值1,参数2=值2)

案例:deffun(a,b):

print("a:",a)

print("b:",b)

fun(a=2,b=3)

案例二:deffun(a,b):

print("a:",a)

print("b:",b)

fun(3,b=2)

注意:位置参数一定要在关键字参数之前

4.缺省参数(默认参数)

案例一:

defprintinfo(name,age=20):

print("name:",name)

print("age:",age)

printinfo(name="anfly")

#name: anfly

#age: 20

案例二:

defprintinfo(name,age=20):

print("name:",name)

print("age:",age)

printinfo(name="anfly",age=10)

#name: anfly

#age: 10

注意:缺省参数一定要位于位置参数的最后面

5.不定时参数

*args:为元组

**kwargs:为字典

defprintinfo(*args,**kwargs):

print("args:",args)

print("kwargs:",kwargs)

printinfo(1,2,3,a=5,b=6)

#args:1,2,3

#kwargs:a=5,b=6

6.参数位置顺序

deffun(位置参数,*args,缺省参数,**kwargs):

代码块

fun(参数值)

案例:

deffun(a,b,*args,c=6,**kwargs):

print("a=",a)

print("b=",b)

print("args=",args)

print("c=",c)

print("kwargs=",kwargs)

fun(1,2,3,4,5,9,c=1000,f=45,cf=65)

#a= 1

#b= 2

#args= (3, 4, 5, 9)

#c= 1000   如果下面的fun不给c=1000的话下面输出的c的值就为6

#kwargs= {'f': 45, 'cf': 65}

4.函数返回值

def fan(a,b):    

  return a+b

print(fan(1,2))   #3

5.函数类型

1. 无参数,无返回值

2. 无参数,有返回值

3. 有参数,无返回值

4. 有参数,有返回值

6.匿名函数

lambda函数也叫匿名函数,即函数没有具体的名称

案例一:

sum=lambda a,b:a+b

print(sum(1,2))  #3

案例二:

sum=lambda a,b:100

print(sum(1,2))  #100

三、变量

1.局部变量

# 局部变量

def jv():  

    a=3

    print(a)

def jv1():    

    a=99

    print(a)

jv()    #3

jv1()    #99

2.全局变量(就近原则)

a="全局变量"

def jv():      

    print(a)

def jv1():    

    a=99

    print(a)

jv()   #全局变量

jv1()  #99

3.局部变量升成全局变量

def jv():  

    a=3

    global b

    b="我也是全局变量"

    print(a)

def jv1():    

    a=99

    print(a)

    print(b)

jv()    #3

jv1()  #99 #“我也是全局变量”

十三单元 文件

一、文件的介绍

1.例如:HTML、TXT、File等

2.文件的作用:保存数据存放在磁盘

二、文件的打开与关闭

1.读文件:

1.

方式一:

f = open('文件', 'r',encoding='utf-8')    #,encoding='utf-8'解决读文件中文报错

    print(f.read())

方式二:

    readlines:一次性读出文件所有内容

f=open("a.txt",'r',encoding='utf-8')

print(f.readlines())  

方式三:

    readline:一行一行的读出文件内容

f=open("a.txt",'r',encoding='utf-8')

print(f.readline())

2.读取长度限制

content=f.read(8)

print(content)   #控制台只出现八个字符

2.写文件:

        方式一:

        f=open('文件名.txt','w')

               f.write("要写入的信息")

               f.close()

        方式二:

        f=open('b.txt','a')  #追加写入数据

               f.write("新的数据")

               f.close()

3.二进制读写

二进制读数据

with open("照片.jpg","rb") as 对象:

  变量名 = 对象.read()

   print(变量名)

三、文件和文件夹的操作

1.文件操作

1.文件重命名

import os

os.rename("要修改的文件.txt","新文件.txt")

2.删除文件

import os

os.remove("要删除的文件")

2.文件夹操作

1.创建文件夹

import os

os.mkdir("文件夹名")

2.获取当前目录

print(os.getcwd())

四、异常

1.什么是异常

其实就是正常运行的程序发生了一个错误

2.异常处理

    语法

一、

try:

<语句>#运行别的代码

except<名字>:

<语句>#如果在try部份引发了'name'异常

else:

<语句>#如果没有异常发生

二、

try:

异常的操作

except(Exception1[,Exception2[,...ExceptionN]]]):

发生以上多个异常中的一个,执行这块代码

  ......................

else:

如果没有异常执行这块代码

三、

try:

<语句>

finally:

<语句>#退出try时总会执行

五、模块

1.含义:是一个Python文件,以.py 结尾,包含了Python 对象定义和Python语句

2.模块的引入

1.import

importaa#aa是文件名,test2是aa文件里面的一个方法

aa.test2()

开平方根

importmath

print(math.sqrt(4))

#2

2.from...import

一、

from 要调用的文件 import 文件里面的方法

方法()

二、

from modname import *  #调用文件里的所有方法

六、Python中的包

简单地说其实包就是文件夹,文件夹下面必须存在init.py文件

十四单元 Python面向对象

一、面向对象

类. 类变量. 数据成员. 方法重写. 局部变量. 实例变量. 继承. 实例化. 方法. 对象

二、创建类

classClassName:

'类的帮助信息'#类文档字符串

class_suite#类体

三、创建实例对象

1、创建

"创建 Employee 类的第一个对象"

emp1=Employee("Zara",2000)

"创建 Employee 类的第二个对象"

emp2=Employee("Manni",5000)

2、访问属性

emp1.displayEmployee()

emp2.displayEmployee()

print"Total Employee %d"%Employee.empCount

3、增删改

emp1.age=7# 添加一个 'age' 属性

emp1.age=8# 修改 'age' 属性

delemp1.age# 删除 'age' 属性

也可以使用以下函数的方式来访问属性:

getattr : 访问对象的属性。

hasattr : 检查是否存在一个属性。

setattr : 设置一个属性。如果属性不存在,会创建一个新属性

delattr: 删除属性。

hasattr(emp1,'age')# 如果存在 'age' 属性返回 True。

getattr(emp1,'age')# 返回 'age' 属性的值

setattr(emp1,'age',8)# 添加属性 'age' 值为 8

delattr(emp1,'age')# 删除属性 'age'

四、Python内置类属性

dict : 类的属性

doc :类的文档字符串

name: 类名

module: 类定义所在的模块

bases : 类的所有父类构成元素

五、类的继承

1、继承介绍

通过继承创建的新类称为子类或派生类,被继承的类称为基类、父类或超类

2、语法

class派生类名(基类名)

   ...

3、可以继承多个类

classA:# 定义类 A

.....

classB:# 定义类 B

.....

classC(A,B):# 继承类 A 和 B

.....

六、方法重写

1、概念

如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法

七、基础重载方法

序号方法、描述、简单的调用

1*init* ( self [,args...] ) 构造函数 简单的调用方法: obj = className(args)

2*del*( self ) 析构方法, 删除一个对象 简单的调用方法 : del obj

3*repr*( self ) 转化为供解释器读取的形式 简单的调用方法 : repr(obj)

4*str*( self ) 用于将值转化为适于人阅读的形式 简单的调用方法 : str(obj)

5*cmp* ( self, x ) 对象比较 简单的调用方法 : cmp(obj, x)

八、运算符重载

九、类属性与方法

1、类的私有属性

__pri_attr:两个下划线开头,声明该属性为私有

在类内部的方法中使用时self.__pri_attr

2、类的方法

在类的内部,使用def关键字可以为类定义一个方法

3、类的私有方法 __pri_attr:两个下划线开头,声明该方法为私有方法

在类的内部调用__pri_attr

第十五单元 Python单元测试之unittest

一、单元测试、集成测试、功能测试

单元测试

颗粒度最小,一般由开发小组采用白盒方式来测试,主要测试单元是否符合“设计”;是指对软件中的最小可测试单元进行检查和验证

集成测试

介于单元测试和系统测试之间,一般由开发小组采用白盒+黑盒的方法来测试,即验证“设计”又验证“需求”。主要用来测试模板与模板之间的接口,同时还要测试一些主要的业务功能。

功能测试

颗粒度最大,一般由独立的测试小组采用黑盒的方式来测试,主要测试系统是否符合“需求规格说明书

白盒测试

主要应用于单元测试阶段,主要是对代码级别的测试,针对程序内部的逻辑结构

黑盒测试

测试系统的功能是否满足“需求规格说明书

二、Unittest重要组成

TestFixture

作用:用于一个测试环境的准备和销毁还原

功能:当测试用例每次执行之前需要准备测试环境,每次测试完成后还原测试环境

主要方法:

setUp():准备环境,执行每个测试用例的前置条件;

tearDown():环境还原,执行每个测试用例的后置条件;

setUpClass():必须使用@classmethod装饰器,所有case执行的前置条件,只运行一次;

tearDownClass():必须使用@classmethod装饰器,所有case运行完后只运行一次;

TestCase:测试用例

定义:一个类class继承 unittest.TestCase,就是一个测试用例

测试用例:就是一个完整的测试流程

包括测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)

测试用例命名规则

测试方法的名称要以test开头。只会执行以test开头定义的方法

十六单元 单元测试之pytest

前提:需要安装pytest和pytest-html(生成html测试报告)

一.命名规则

**Pytest单元测试中的类名和方法名必须是以test开头

importpytest

fromxml.domimportminidom

classTestPy01():

deftestPy001(self):

print("第一个pytest")

assert1==1

deftestPy002(self):

print("第二个pytest")

assert1==2

deftestPy003(self):

print("第三个pytest")

assert1==1

if__name__=='__main__':

pytest.main()

二、Pytest生成自带的html测试报告

前提条件:需要下载pytest-html模块(python自带的生成测试报告模块)

方式一:

pytest.main(["--html=./report.html","模块.py"])#运行该模块的所有测试用例

方式二:

pytest.main([‘--html=./report.html’,‘模块.py::类::test_a_001']) #指定运行的测试用例

方式三:

pytst.main(['-x','--html=./report.html','t12est000.py'])#填一个附加参数

方式四:

pytest.main(["--html=./report.html"])#无效        

-x:出现一条测试用例失败就退出测试

-v:丰富信息模式,输出更详细的用例执行信息

-s:显示print内容

-q:简化结果信息,不会显示每个用例的文件名



跳过该用例使用@pytest.mark.skip()

@pytest.mark.skip()

deftest001(self):

assert2==2

三、Pytest的运行方式

.点号,表示用例通过

F表示失败Failure

E表示用例中存在异常Error

四、文件读取

##读取csv文件

importcsv#导入csv模块

classReadCsv():

defread_csv(self):

item=[]#定义一个空列表

c=csv.reader(open("../commonDemo/test1.csv","r"))#得到csv文件对象

forcsv_iinc:

item.append(csv_i)#将获取的数据添加到列表中

returnitem


r=ReadCsv()

print(r.read_csv())

##读取xml文件

fromxml.domimportminidom

classReadxml():

defread_xml(self,filename,onename,twoname):

root=minidom.parse(filename)

firstnode=root.getElementsByTagName(onename)[0]

secondnode=firstnode.getElementsByTagName(twoname)[0].firstChild.data

returnsecondnode

五、Allure

Allure是一款轻量级并且非常灵活的开源测试报告框架,它支持绝大多数测试框架, 例如TestNG、Pytest、JUint等。它简单易用,易于集成

1.先下载Allure→配置Alluer环境变量→输入allure检验配置是否成功→安装allure,输入(pip install allure-pytest)

2.Allure常用的特性

@allure.feature# 用于描述被测试产品需求

@allure.story# 用于描述feature的用户场景,即测试需求

withallure.step():# 用于描述测试步骤,将会输出到报告中

allure.attach# 用于向测试报告中输入一些附加的信息,通常是一些测试数据,截图等

案例:

importpytest,allure,os

classTestClass005():

@allure.feature("用户登录功能")#用于定义被测试的功能,被测产品的需求点

@allure.story("登录成功")#用于定义被测功能的用户场景,即子功能点

deftest_success(self):

assert1==1

@allure.feature("用户登录功能")#用于定义被测试的功能,被测产品的需求点

@allure.story("登录失败")#用于定义被测功能的用户场景,即子功能点

deftest_fail(self):

assert1==2

if__name__=='__main__':

pytest.main(['--alluredir','report/result','test_06.py'])#生成json类型的测试报告

split='allure '+'generate '+'./report/result '+'-o '+'./report/html '+'--clean'#将测试报告转为html格式

os.system(split)# system函数可以将字符串转化成命令在服务器上运行

十七单元 requests接口测试

1.介绍:

Requests是一个很实用的Python HTTP客户端库,用来做接口测试

*做接口测试前需要pip install requests

2.get请求

一、无参请求

r=requests.get('http://www.baidu.com')

二、get传参

payload={'key1':'value1','key2':'value2','key3':None}

r=requests.get('http://www.baidu.com ',params=payload)

3.post请求

payload={'key1':'value1','key2':'value2'}

r=requests.post("http://httpbin.org/post",data=payload)

4.requests响应

r.status_code响应状态码

r.heards响应头

r.cookies响应cookies

r.text响应文本

r.encoding当前编码

r.content以字节形式(二进制)返回

5.requests扩充

1.添加等待时间

requests.get(url,timeout=1)#超过等待时间则报错

2.添加请求头信息

requests.get(url,headers=headers)#设置请求头

3.添加文件

requests.post(url,files=files)#添加文件

6.requests+pytest+allure

1.步骤如下:

读取文件中的数据

requests拿到数据请求接口返回状态码

通过断言验证返回状态码和200对比

生成allure的测试报告

也可以这样说:

dataDemo(存放数据)>> readDemo(读取数据)

useRequests(发送请求)>>testDemo(生成报告)

2.读取csv数据流程

1.通过excel另存为csv

2.读取

importcsv

classReadCsv():

defreadCsv(self):

item= []

rr=csv.reader(open("../dataDemo/123.csv"))

forcsv_iinrr:

item.append(csv_i)

item=item[1:]

returnitem

3.requests请求接口返回状态码

importrequests

fromreadDataDemo.readcsvimportReadCsv

r=ReadCsv()

ee=r.readCsv()

# print(ee)

classRequestCsv():

defrequestsCsv(self):

item= []

forcsv_iinee:

ifcsv_i[2] =="get":

rr=requests.get(csv_i[0],params=csv_i[1])

item.append(rr.status_code)

else:

rr=requests.post(csv_i[0],data=csv_i[1])

item.append(rr.status_code)

returnitem

4.生成测试报告

3.读取excel文件流程

1.新建excel文件

2.读取数据,安装pip install openpyxl

class ReadXlsx:    

def readXlsx(self):      

   wordbook=load_workbook("绝对路径")        

   sheet = wordbook["requests"]        

   testdata = []        

   for i in range(2, sheet.max_row + 1):            

       d = {}            

       for j in range(1, sheet.max_column + 1):                            d[sheet.cell(1, j).value] = sheet.cell(i, j).value                testdata.append(d)            

    return testdata

3.requests请求接口返回状态码

importrequests

fromrequestdemo.readexcelimportReadxcel

classGetStatusCode():

defgetStatusCode(self):

t=Readxcel()

f=t.getTestExcel()

item= []

forexcel_iinf:

ifexcel_i["method"] =="get":

rr=requests.get(excel_i["url"],params=excel_i["params"])

item.append(rr.status_code)

else:

rr=requests.post(excel_i["url"],data=excel_i["params"])

item.append(rr.status_code)

returnitem

print(GetStatusCode().getStatusCode())

4.生成测试报告

importallure,pytest,os

fromrequestdemo.getStatusCodeimportGetStatusCode

get=GetStatusCode()

statusCodes=get.getStatusCode()

classTestReadExcel():

deftestReadExcel(self):

forcodeinstatusCodes:

assertcode==200

if__name__=="__main__":

# 生成测试报告json

pytest.main(["-s","-q",'--alluredir','report/result','testreadexcel.py'])

# 将测试报告转为html格式

split='allure '+'generate '+'./report/result '+'-o '+'./report/html '+'--clean'

os.system(split)

十八单元 自动化持续继承

一、概念

互联网软件的开发和发布,已经形成了一套标准流程,最重要的组成部分就是持续集成(Continuous integration,简称CI)

1.持续继承:频繁地(一天多次)将代码集成到主干。

2.持续交付:频繁地将软件的新版本,交付给质量团队或者用户,以供评审。如果评审通过,代码就进入生产阶段

3.持续部署:是持续交付的下一步,指的是代码通过评审以后,自动部署到生产环境

二、Jenkins

1.概念:Jenkins 是一个开源软件项目,是基于Java开发的一种可拓展持续集成工具,主要用于持续、自动地构建 / 测试 / 集成软件项目以及监控一些定时执行的任务

2.目的:

1、持续、自动地构建/测试软件项目。 2、监控软件开放流程,快速问题定位及处理,提示开放效率。

3.特性:易于安装、易于配置、分布式构建、插件支持

4.产品发布流程:产品设计成型 → 开发人员开发代码 → 测试人员测试功能 → 运维人员发布上线

三、安装配置Jenkins

去官网下载jenkins.war包

3.1 两种方式开启Jenkins

方式1:在tomcat的bin目录下启动(最常用)

方式2:打开cmd,进入jenkins目录,然后运行命令:java -jar jenkins.war

四、搭建Jmeter+Jenkins+Ant持续化

<?xml version="1.0" encoding="UTF-8"?><projectname="ant-jmeter-test"default="run"basedir="."><!-- 需要改成自己本地的 Jmeter 目录--><propertyname="jmeter.home"value="G:\jmeter\apache-jmeter-3.0"/><!-- jmeter生成jtl格式的结果报告的路径--><propertyname="jmeter.result.jtl.dir"value="G:\jmeter\jmeter-ant-jenkins\testResult"/><!-- jmeter生成html格式的结果报告的路径--><propertyname="jmeter.result.html.dir"value="G:\jmeter\jmeter-ant-jenkins\testResult"/><!-- 生成的报告的前缀--><propertyname="ReportName"value="TestReport"/><propertyname="jmeter.result.jtlName"value="${jmeter.result.jtl.dir}/report.jtl"/><propertyname="jmeter.result.htmlName"value="${jmeter.result.html.dir}/index.html"/><!-- 接收测试报告的邮箱 --><propertyname="mail_to"value="barryli89@163.com"/><propertyname="lib.dir"value="${jmeter.home}/lib"/><pathid="xslt.classpath"><filesetdir="${lib.dir}"includes="xalan*.jar"/><filesetdir="${lib.dir}"includes="serializer*.jar"/></path><targetname="run"><antcalltarget="test"/><antcalltarget="report"/></target><targetname="test"><taskdefname="jmeter"classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask"/><jmeterjmeterhome="${jmeter.home}"resultlog="${jmeter.result.jtlName}"><!-- 声明要运行的脚本。"*.jmx"指包含此目录下的所有jmeter脚本--><testplansdir="G:\jmeter\jmeter-ant-jenkins"includes="*.jmx"/><propertyname="jmeter.save.saveservice.output_format"value="xml"/></jmeter></target><targetname="report"><!-- 因为上面生成报告的时候,不会将相关的图片也一起拷贝至目标目录,所以,需要手动拷贝 --></xslt><copytodir="${jmeter.result.html.dir}"><filesetdir="${jmeter.home}/extras"><includename="collapse.png"/><includename="expand.png"/></fileset></copy></target></project>


进行命令行模式后,进入刚才创建的xml文件存放目录,如:D:\build 输入ant即可

五、继承Jenkins

打开Jenkins,配置Ant环境

新建一个自由风格任务

构建触发器

构建配置

配置HTML插件

立即构建

针对报告中不显示聚合报告的情况

Jenkins执行自动化测试后发送测试报告邮件

第十九单元 web端自动化

1.什么是自动化

使用测试工具 或者其他手段对软件进行测试

2.自动化测试好处

1.缩短测试周期  2.避免人为出错  3.测试信息存储  4.轻易获取覆盖率  5.实现自动或者定时执行

3.使用自动化的前提条件

1)手动测试已经完成,后期再不影响进度的前提下逐渐实现自动化

2)项目周期长,重复性的工作都交给机器去实现

3)需求稳定,项目变动不大

4)自动化测试脚本复杂度比较低

5)可重复利用

4.使用自动化测试的场景

1)频繁的回归测试

2)冒烟测试

3)传统行业需求变化不大,应用频繁

4)性能测试

5.常用工具

QTP、Selenium、RFT

6.为什么要学习元素定位

1)计算机没有智能到人的程度。

2)计算机不能像手动测试人员一样通过眼看,手操作鼠标点击,操作键盘输入。

3)计算机通过一系列计数手段找到元素(按钮、输入框、模拟键盘等)

7.元素定位的工具或手段有哪些

css选择器、xpath

8.环境搭建

1. 下载浏览器插件

2. 菜单 → 添加附件 → 设置图标 → 从文件中添加附件

9.什么是xpath

XPath即为XML路径语言,它是一种用来(标准通用标记语言的子集)在 HTML\XML 文档中查找信息的语言

10.什么是xml

XML 指可扩展标记语言(EXtensible Markup Language)

XML 是一种标记语言,很类似 HTML

XML 的设计宗旨是传输数据,而非显示数据

11.xml和html 的区别

html是用来显示数据、xml是用来传输和存储数据

12.获取元素

①/:从根节点选取  #/html/head/meta[1]第一个;[last()]最后一个元素;[last()-1]倒数第二个元素;                    [position()<3] 前两个元素

②//:从匹配选择的当前节点选择文档中的节点 #//link

③.选取当前节点

④..选取当前节点的父节点

⑤@:选取属性 #//meta[@name] 或者//meta[@name="referrer"]

⑥//meta[@*]:所有带有属性的meta元素

⑦//head/meta | //head/title:选取head元素的所有meta元素和title元素

⑧//meta | //title:选取文档中的所有title和meta元素

13.css选择器

13.1什么是css选择器

CSS 中,选择器是一种模式,用于选择需要添加样式的元素

13.2css选择器语法

①.info: 选择class=“info”的所有元素

②#name: 选择id=“name”的所有元素

③* :选择所有的元素

④元素1,元素2: 选择元素1和元素2的所有元素

⑤元素1 元素2: 选择元素1内部的所有元素2的元素

⑥元素1>元素2: 选择父元素为元素1的元素的所有元素2的元素

⑦[target]: 选择带有target属性的所有元素

⑧[target=blank]: 选择target="blank"的所有元素

Web自动化测试进阶

什么是框架框架(framework)是一个框子 -- 指其约束性,也是一个架子 -- 指其支撑性,是一个基本概念上的结构,用于去解决或者处理复杂的问题。

为什么使用框架1)自己从头实现太复杂

  2)使用框架能够更专注于业务逻辑,加快开发速度

  3)框架的使用能够处理更多细节问题

  4)使用人数多,稳定性,扩展性好

selenium工作原理

  4.selenium对浏览器操作

1)库的导入

from selenium import webdriver

2)创建浏览器对象

必须为大写

driver = webdriver.Firefox()

driver = webdriver.Chrome()

3)浏览器尺寸相关操作

maximize_window() 最大化

get_window_size()    获取浏览器尺寸,打印查看

set_window_size()    设置浏览器尺寸,400*400

4)浏览器位置相关操作

get_window_position() 获取浏览器位置

set_window_position(x,y)    设置浏览器位置

5)浏览器的关闭操作

close()关闭当前标签/窗口

quit()关闭所有标签/窗口

6)页面请求操作

driver.get(url)请求某个url对应的响应

refresh()刷新页面操作

back()回退到之前的页面

forward()前进到之后的页面

fromselenium import webdriver

import time

driver = webdriver.Chrome()#不可以找到,必须导入对应的驱动器

driver=webdriver.Firefox()

url1="http://www.baidu.com"

url2="https://zhuanlan.zhihu.com/"

请求第一个接口

driver.get(url1)

time.sleep(3)

刷新

driver.refresh()

driver.get(url2)

回退

driver.back()time.sleep(3)

前进driver.forward()

time.sleep(3)

driver.close()

5.selenium获取断言信息1)什么是断言

断言是编程术语,表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真,可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言而在部署时禁用断言。

2)获取断言信息的操作

current_url 获取当前访问页面url

title 获取当前浏览器标题

page_source 获取网页源码

print(driver.current_url)

print(driver.title)

print(driver.page_source)

截图:

get_screenshot_as_png() 保存图片

data=driver.get_screenshot_as_png()

withopen("a.png","wb")asf:

f.write(data)

get_screenshot_as_file(file) 直接保存

driver.get_screenshot_as_file("b.png")

6.selenium八大元素定位from selenium import webdriver

driver=webdriver.Firefox()

url = "http://www.baidu.com"

driver.get(url)

第一种 id

ele = driver.find_element_by_id("kw")

ele.send_keys(12306) # 输入数据

from selenium.webdriver.common.by import By

ele = driver.find_element(By.ID,"kw")# ele.send_keys(12306) # 输入数据

第二种  标签名字

ele = driver.find_element_by_name("wd")

ele.send_keys(12306) # 输入数据

第三种  class

ele = driver.find_element_by_class_name("s_ipt")

ele.send_keys(12306) # 输入数据

第四种  Xpath

ele = driver.find_element_by_xpath("//*[@id='kw']")

ele.send_keys(12306) # 输入数据

第五种  css class

ele = driver.find_element_by_css_selector("#kw")

ele.send_keys(12306) # 输入数据

第六种  text

ele = driver.find_element_by_link_text("地图")

ele.click() # 输入数据

第七种:类似于模糊匹配

ele = driver.find_element_by_partial_link_text("地")

ele.click()

第八种:标签名定位,必须得保证只有一个这种名字的标签,使用下面这个搜索

url = "http://cn.bing.com/"

driver.get(url)# ele = driver.find_element_by_tag_name("input")

ele.send_keys(12306) # 输入数据

7.元素的操作对元素的相关操作,一般要先获取到元素,再调用相关方法

element = driver.find_element_by_xxx(value)

1)点击和输入

点击操作---------->element.click()

清空/输入操作:

element.clear()---------------------->清空输入框

element.send_keys(data)-------->输入数据

2)提交操作

element.submit()

8.多标签之间的切换场景:有的时候点击一个链接,新页面并非由当前页面跳转过去,而是新开一个页面打开,这种情况下,计算机需要识别多标签或窗口的情况。

1)获取所有窗口的句柄

handles = driver.window_handlers

调用该方法会得到一个列表,在selenium运行过程中的每一个窗口都有一个对应的值存放在里面。

2)通过窗口的句柄进入的窗口

driver.switch_to_window(handles[n])

driver.switch_to.window(handles[n])

通过窗口句柄激活进入某一窗口

案例:

58同城租房信息:http://bj.58.com

使用句柄driver.get("http://bj.58.com")

print("点击之前句柄:",driver.window_handles)

ele=driver.find_element_by_xpath(".//*[@id='fcNav']/em/a[1]")ele.click()

list_windowns=driver.window_handles

print("点击之后句柄:",driver.window_handles)

driver.switch_to.window(list_windowns[1])

eleDaxing=driver.find_element_by_link_text("大兴")

eleDaxing.click()

9.多表单

    el = driver.find_element_by_xxx(value)

    driver.switch_to.frame(el)/driver.switch_to_frame(el)

案例:

fromseleniumimportwebdriver

#打开游览器

driver=webdriver.Firefox()

#登录QQ

url="https://qzone.qq.com/"

driver.get(url)

#获取元素

#定位表单元素

ele_bd=driver.find_element_by_id("login_frame")

driver.switch_to.frame(ele_bd)

ele=driver.find_element_by_xpath(".//*[@id='switcher_plogin']")

ele.click()

#输入账号

ele2=driver.find_element_by_id("u")

ele2.send_keys()

#输入密码

ele3=driver.find_element_by_id("p")

ele3.send_keys("")

ele4=driver.find_element_by_id("login_button")

ele4.click()

弹出框操作

# 进入到弹出框中

driver.switch_to.alert

#接收警告

accept()

#解散警告

dismiss()

#发送文本到警告框

send_keys(data)

用法:driver.switch_to.alert.accept()

下拉框

案例:

fromseleniumimportwebdriver

importtime

driver=webdriver.Firefox()

driver.get("http://www.baidu.com")

ele=driver.find_element_by_id("s-usersetting-top")

ele.click()

ele1=driver.find_element_by_xpath(".//*[@id='s-user-setting-menu']/div/a[2]")

ele1.click()

time.sleep(2)

ele2=driver.find_element_by_xpath(".//*[@id='yadv-setting-gpc']/div/div[1]/i[1]")

ele2.click()

list_ele=driver.find_elements_by_class_name("c-select-item")

print(list_ele)

list_ele[2].click()

# for list_i in list_ele:

#     print(list_i.text)

#     if list_i.text =="最近一周":

#         list_i.click()

鼠标和键盘操作

鼠标

1.先导入动作链类:

fromselenium.webdriverimportActionChains

ActionChains(driver)

2.常用鼠标动作:

ActionChains(driver).context_click(ele).perform()点击鼠标右键

ActionChains(driver).double_click(ele).perform()点击鼠标左键

ActionChains(driver).move_to_element(el).perform()鼠标悬停

3.perform()对前面的方法执行

#案例:

fromselenium.webdriverimportActionChains

fromseleniumimportwebdriver

importtime

driver=webdriver.Firefox()

driver.get("http://www.baidu.com")

ele=driver.find_element_by_xpath(".//*[@id='s-top-left']/div/a")

# ele.click()

ActionChains(driver).double_click(ele).perform()

键盘

1.导入

fromselenium.webdriver.common.keysimportKeys

2.常用键盘操作

send_keys(Keys.BACK_SPACE)    删除键(BackSpace)

send_keys(Keys.SPACE)         空格键(Space)

send_keys(Keys.TAB)           制表键(Tab)

send_keys(Keys.ESCAPE)        回退键(Esc)

send_keys(Keys.ENTER)         回车键(Enter)

send_keys(Keys.CONTROL,‘a’)   全选(Ctrl+A)

send_keys(Keys.CONTROL,‘a’)   全选(Ctrl+A)

send_keys(Keys.CONTROL,‘x’)   剪切(Ctrl+X)

send_keys(Keys.CONTROL,‘v’)   粘贴(Ctrl+V)

send_keys(Keys.F1)            键盘F1

send_keys(Keys.F12)           键盘F12

浏览器等待

1.为什么要进行等待

1.网速慢 2.网站内容过多 3.如果不进行等待而直接定位元素,可能会抛出异常

2.selenium中等待的分类

1.固定等待

2.显示等待

WebDriverWait(driver,10,0.5).until(EC.presence_of_element_located(

(By.CLASS_NAME,"g-hu")))

3.隐式等待 

driver.implicitly_wait(n)

PO模型

1.介绍

在自动化中,Selenium自动化测试中有一个名字经常被提及PageObject(思想与 面向对象的特征相同),通常PO模型可以大大提高测试用例的维护效率

优点:重用,业务和对象分离,代码结构清晰,方便代码维护

2.核心要素

1.在PO模式中抽离封装集成一个BasePage类,该基类应该拥有一个只实现 webdriver实例的属性

2.每一个page都继承BasePage,通过driver来管理本page中元素,将page中 的操作封装成一个个方法

3.TestCase继承unittest.Testcase类,并依赖page类,从而实现相应的测试步 骤

3.实现BasePage

fromseleniumimportwebdriver

fromselenium.webdriver.common.action_chainsimportActionChains#鼠标操作

classBasePage():

'''BasePage封装所有界面都公用的方法。例如driver,find_element等'''

'''实例化BasePage类时,事先执行的__init__方法,该方法需要传递参数'''

def__init__(self,driver,url):

self.driver=driver

self.base_url=url

# 进入网址

defget(self):

self.driver.get(self.base_url)

#元素定位,替代八大定位

defget_element(self,*locator):

returnself.driver.find_element(*locator)

#点击

defleft_click(self,*locator):

ActionChains(self.driver).click(self.get_element(*locator)).perform()

#输入

defsend_text(self,text,*locator):

self.driver.find_element(*locator).send_keys(text)

#清除

defclear_text(self,*locator):

self.driver.find_element(*locator).clear()

实现SearchPage

'''

实现步骤:(1)继承basepage,(2)元素传参,(3)调取方法

'''

fromselenium.webdriver.common.byimportBy

frompomodel.Base.base_pageimportBasePage

classSearch(BasePage):

def__init__(self,driver,url):

BasePage.__init__(self,driver,url)

#进入百度

defopen_baidu(self):

self.get()

#输入搜索内容

definput_search_content(self,text):

self.send_text(text,By.ID,"kw")

#点击按钮

defclick_baidu_search(self):

self.left_click(By.ID,"su")

实现TestCase

importunittest

fromseleniumimportwebdriver

frompomodel.Pages.search_pagesimportSearch

classBaiBu(unittest.TestCase):

defsetUp(self)->None:

self.driver=webdriver.Firefox()

self.driver.implicitly_wait(10)

deftest_serach(self):

url="http://www.baidu.com"

s=Search(self.driver,url)

s.open_baidu()

s.input_search_content("jack")

s.click_baidu_search()

deftearDown(self)->None:

self.driver.quit()

if__name__=='__main__':

unittest.main()

4.总结

PO设计模式中的BasePage基类对应案例中的BasePage.py文件 PO模式中的pages中的案例显示Search.py PO模式设计中TestCase对应案例中的TestCase.py

5.po模式的优点

1.PO提供了一种业务流程与页面元素操作分离的模式,这使得测试代码变得更加清晰

2.页面对象与用例分离,使得我们更好的复用对象

3.可复用的页面方法代码会变得更加优化

4.更加有效的命令方式使得我们更加清晰的知道方法所操作的UI元素

Android开发、adb、monkey测试

1.手机测试概念

传统手机测试 VS 手机应用软件测试

传统手机测试:指测试手机本身比如抗压,抗摔,抗疲劳,抗低温高温等。也包括手机本身功能、性能等测试。

手机应用软件测试 C/S Client/Server

手机应用软件是基于手机操作系统之上开发出来的软件,做这样的测试就叫做手机应用软件测试。

2.手机端常规测试

Android后缀apk,ios后缀是IPA(iPhoneApplication)

13大测试:

UI测试,功能,性能测试,兼容性测试,安装卸载测试,软件升级测试,登陆测试,安全性测试,消息推送,前后台切换,网络环境测试,monkey测试,异常测试

3.Android介绍

介绍:Android是一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑

四层:Android分为四个层,从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和Linux内核层

4.ADB

1.简介:ADB全称Android Debug Bridge, 是android sdk里的一个工具, 用这个工具可以直接操作管理android模拟器或者真实的andriod设备(如G1手机)

它的主要功能有:

运行设备的shell(命令行)

管理模拟器或设备的端口映射

计算机和设备之间上传/下载文件

将本地apk软件安装至模拟器或android设备

2.配置ADB环境变量

打开:adt-bundle-windows-x86_64_20140101文件找到adb.exe所在路径配置ADB_HOME环境变量

3.ADB常用指令

查看设备:adb devices

安装软件:adb install -r (APK路径)

卸载软件 adb uninstall <软件名> adb uninstall -k <软件名>

登录设备shell adb shell adb shell <command命令>

查看手机内存情况    adb shell dumpsys cpuinfo

查看内存情况 adb shell getprop | findstr dalvik 本机内存的使用情况

查看应用内存使用情况 adb shell dumpsys meminfo +包名:应用的内存使用情况

列出手机装的所有app的包名: adb shell pm list packages

列出系统应用的所有包名: adb shell pm list packages -s

列出除了系统应用的第三方应用包名: adb shell pm list packages -3

adb logcat 查看手机日志

Android 的日志分为如下几个级别:

V —— Verbose(最低,输出得最多)

D —— Debug

I —— Info

W —— Warning

E —— Error

F —— Fatal

S —— Silent(最高,啥也不输出

5.APK牢固性

应用加固防篡改:通过完整性保护和签名校验保护,能有效避免应用被二次打包,杜绝盗版应用的产生;防逆向:通过对代码进行隐藏以及加密处理,使攻击者无法对二进制代码进行反编译,获得源代码或代码运行逻辑;防调试:通过反调试技术,使攻击者无法调试原生代码或Java代码,阻止攻击者获取代码里的敏感数据。

6.Monkey测试

1.简介

顾名思义,Monkey就是猴子, Monkey测试,就像一只猴子, 在电脑面前,乱敲键盘在测试

Monkey 主要用于Android 的压力测试自动的一个压力测试小工具, 主要目的就是为了测试app 是否会Crash

2.Monkey前提条件

1.环境配置:把adb加入系统环境,手机开启开发者模式

2.连接手机,获取测试的包名。获取包名的方法

3.Monkey编写测试命令,并运行。[monkey操作命令

7.Monkey命令 基本参数介绍

1.-p <允许的包名列表>:adb shell monkey -p com.example.login 100

2.显示日志详细程度

1.adb shell monkey -p com.example.login -v 100 // 缺省值,仅提供启动提示、测试完成和最终结果等少量信息

2. adb shell monkey -p com.example.login -v  -v 100          // 提供较为详细的日志,包括每个发送到Activity的事件信息

3.adb shell monkey -p com.example.login -v  -v  -v 100    // 最详细的日志,包括了测试中选中/未选中的Activity信息

3..Monkey日志分析

将log信息写到文档中:adb shell monkey 100 >c:/log/b.txt

4.--throttle <毫秒>

adb shell monkey -p com.example.login --throttle 300 100

表示执行100个伪随机用户事件流,事件间隔为300毫秒。

5.-pct-touch 调整触摸事件的百分比

6.--pct-motion  调整motion事件百分比

7.--ignore-crashes 通常,应用发生崩溃或异常时Monkey会停止运行

8.--ignore-timeouts 通常,应用程序发生任何超时错误(如“Application Not responding”对话框)Monkey将停止运行

Monkey实例:monkey -p com.tencent.mtaexample -s 23  --throttle2000 --ignore-crashes --ignore-timeouts -v -v -v 100000>/data/local/tmp/log.txt 2>&1 &

9.Monkey异常分析

日志中可能的错误:

1.程序异常退出,uncausedexception (ctrl+f搜索‘Fatal’)

2.程序强制关闭,ForceClosed (简称FC) (同上)

3.程序无响应,ApplicationNo Response(ctrl+f搜索‘ANR ’,加空格是为了屏蔽掉一些无效信息)

4.手动生成。

8.手机兼容性测试

  App云测试平台:Testin、贯众云测试、百度MTC、阿里MQC等

9.真机测试

手机打开开发者选项→勾选USB调试→输入adb devices监测连接设备

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350