一、Python介绍
Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。
Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。
Python 是一种解释型语言: 这意味着开发过程中没有了编译这个环节。类似于PHP和Perl语言。
Python 是交互式语言: 这意味着,您可以在一个Python提示符,直接互动执行写你的程序。
Python 是面向对象语言: 这意味着Python支持面向对象的风格或代码封装在对象的编程技术。
Python 是初学者的语言:Python 对初级程序员而言,是一种伟大的语言,它支持广泛的应用程序开发,从简单的文字处理到 WWW 浏览器再到游戏。
二、Python的特点
1.易于学习:Python有相对较少的关键字,结构简单,和一个明确定义的语法,学习起来更加简单。
2.易于阅读:Python代码定义的更清晰。
3.易于维护:Python的成功在于它的源代码是相当容易维护的。
4.一个广泛的标准库:Python的最大的优势之一是丰富的库,跨平台的,在UNIX,Windows和Macintosh兼容很好。
5.互动模式:互动模式的支持,您可以从终端输入执行代码并获得结果的语言,互动的测试和调试代码片断。
6.可移植:基于其开放源代码的特性,Python已经被移植(也就是使其工作)到许多平台。
7.可扩展:如果你需要一段运行很快的关键代码,或者是想要编写一些不愿开放的算法,你可以使用C或C++完成那部分程序,然后从你的Python程序中调用。
8.数据库:Python提供所有主要的商业数据库的接口。
9.GUI编程:Python支持GUI可以创建和移植到许多系统调用。
10.可嵌入: 你可以将Python嵌入到C/C++程序,让你的程序的用户获得"脚本化"。
三、Python变量和数据类型
Python 的六个标准数据类型中:
不可变数据(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.格式:变量名={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}
1.文件的作用
保存数据放在磁盘中
2.打开文件
f=open(‘文件’,'w')或者f=open('文件','r')
3.文件操作
3.1?写数据(write)
如果文件不存在那么创建,如果存在那么就先清空,然后写入数据
对象=open("文件",w)
对象.write("写入数据")
对象.close
3.2读数据(read)
以读的方式打开文件,读取数据
对象 = open("文件",r)
变量 = 对象.read()? ? ? ------>全部读取
变量=对象.readlines()? ?------>全部读取,输出以列表格式
变量=对象.readline()? ? ------->只读第一行
print(变量)
如果用open打开文件时,如果使用的"r",那么可以省略,即只写open('test.txt')
如果没有文件,打开报错,存在该文件才能操作
如果文件中存在中文显示,会出现乱码需要添加encoding='utf-8'
open(‘test.txt’,”r”,encoding='utf-8')
3.3?读二进制数据(rb)
对象 = open("二进制文件",rb)
对象 = open("二进制文件",rb) as 变量
变量= 对象.read()
print(变量)
3.4写二进制数据(wb)
withopen("二进制文件","wb")as对象:
变量=对象.write()
print(变量)
备份:
with open("1.jpg","rb") as rf:
res=rf.read()
with open("textjpg.jpg","wb") as wf:
res=wf.write(res)
print(res)
四.文件和文件夹操作
4.1文件重命名
import os
os.rename("需要修改的文件名","新文件名")
4.2删除文件
os模块中的remove()可以完成对文件的重命名操作
import os
os.remove("文件名")
4.3创建文件夹
os模块中的mkdir()可以完成对文件的重命名操作
import os
os.mkdir("文件名")
4.4获取当前目录
os模块中的getcwd()可以获取当前目录
import os
os.getcwd()
五.异常
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
5.1异常处理
捕捉异常可以使用try/except语句。
try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。
如果你不想在异常发生时结束你的程序,只需在try里捕获它。
try:
<语句>? ? #运行别的代码
except<名字>:
<语句>? ? #如果在try部份引发了'name'异常
else:
<语句>? ? ?#如果没有异常发生
5.2.try-finally 语句
try-finally语句无论是否发生异常都将执行最后的代码
try:
<语句>
finally:
<语句>? ?#退出try时总会执行
5.3触发异常
可以使用raise语句自己触发异常
def functionName(score):
if score<0? or? score>100:
raise? ? Exception("Invalid score!",score)# 触发异常后,后面的代码就不会再执行
functionName(200)
六.模块
Python 模块(Module),是一个Python文件,以.py 结尾,包含了Python 对象定义和Python语句
6.1.模块的引入
6.1.1:import
import module1[,module2[,...moduleN]]
6.1.2:开平方根
import math?
print(math.sqrt(4))
?#2
6.1.3:from…import * 语句
把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:
from? modname? import? *
一、?自动化持续集成
一、概念
互联网软件的开发和发布,已经形成了一套标准流程,最重要的组成部分就是持续集成(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持续化
请看Anfil的简书
五、继承Jenkins
打开Jenkins,配置Ant环境
新建一个自由风格任务
构建触发器
构建配置
配置HTML插件
立即构建
针对报告中不显示聚合报告的情况
Jenkins执行自动化测试后发送测试报告邮件
Python 面向对象、
面向对象技术简介:
类(Class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
局部变量:定义在方法中的变量,只作用于当前实例的类。
实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
实例化:创建一个类的实例,类的具体对象。
方法:类中定义的函数。
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
self:它们必须有一个额外的第一个参数名称
self 代表的是类的实例,代表当前对象的地址,而?self.class?则指向类。
添加,删除,修改类的属性
emp1.age=7# 添加一个 'age' 属性
emp1.age=8# 修改 'age' 属性
delemp1.age# 删除 'age' 属性
可以使用以下函数的方式来访问属性:
getattr(obj, name[, default]) : 访问对象的属性。
hasattr(obj,name) : 检查是否存在一个属性。
setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
delattr(obj, name) : 删除属性。
Python内置类属性
dict: 类的属性(包含一个字典,由类的数据属性组成)
doc:类的文档字符串
name: 类名
module: 类定义所在的模块(类的全名是'main.className',如果类位于一个导入模块mymod中,那么className.module等于 mymod)
bases: 类的所有父类构成元素(包含了一个由所有父类组成的元组)
通过继承创建的新类称为子类或派生类,被继承的类称为基类、父类或超类。
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时?self.__private_attrs。
单下划线、双下划线、头尾双下划线说明:
foo: 定义的是特殊方法,一般是系统定义名字 ,类似init()之类的。
_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于from module import *
__foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。
Python单元测试之unittest
单元测试
颗粒度最小,一般由开发小组采用白盒方式来测试,主要测试单元是否符合“设计”;是指对软件中的最小可测试单元进行检查和验证
集成测试
介于单元测试和系统测试之间,一般由开发小组采用白盒+黑盒的方法来测试,即验证“设计”又验证“需求”。主要用来测试模板与模板之间的接口,同时还要测试一些主要的业务功能。
功能测试
颗粒度最大,一般由独立的测试小组采用黑盒的方式来测试,主要测试系统是否符合“需求规格说明书
白盒测试:针对与代码内部的逻辑结构去做的测试
黑盒测试:不考虑程序内部结构和逻辑结构,做的功能测试
Unittest重要组成
Python中有一个自带的单元测试框架是unittest模块,用它来做单元测试,它里面封装好了一些校验返回的结果方法(断言)和一些用例执行前的初始化操作。
unittest中最核心的部分是:TestFixture、TestCase、TestSuite、TestRunner
TestFixture
作用:用于一个测试环境的准备和销毁还原。
主要方法:
setUp():准备环境,执行每个测试用例的前置条件;
tearDown():环境还原,执行每个测试用例的后置条件;
setUpClass():必须使用@classmethod装饰器,所有case执行的前置条件,只运行一次;
tearDownClass():必须使用@classmethod装饰器,所有case运行完后只运行一次;
TestCase:测试用例
定义:一个类class继承 unittest.TestCase,就是一个测试用例
命名规则:测试方法的名称要以test开头。且只会执行以test开头定义的方法(测试方法),测试用例执行的顺序会按照方法名的ASCII值排序。
?单元测试之pytest
前提:需要安装pytest和pytest-html(生成html测试报告)
一.命名规则
**Pytest单元测试中的类名和方法名必须是以test开头
impor tpytest
from xml.dom import minidom
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'])
-x:出现一条测试用例失败就退出测试
-v:丰富信息模式,输出更详细的用例执行信息
-s:显示print内容
-q:简化结果信息,不会显示每个用例的文件名
跳过该用例使用@pytest.mark.skip()
@pytest.mark.skip()
def test001(self):
assert2==2
三、Pytest的运行方式
.点号,表示用例通过
F表示失败Failure
E表示用例中存在异常Error
四、文件读取
##读取csv文件
import csv#导入csv模块
classReadCsv():
def read_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文件
from xml.dom import minidom
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# 用于向测试报告中输入一些附加的信息,通常是一些测试数据,截图等
案例:
import pytest,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)#添加文件
? ? requests+pytest+allure
????????1.步骤如下:
????????????读取文件中的数据
????????????requests拿到数据请求接口返回状态码
????????????通过断言验证返回状态码和200对比
????????????生成allure的测试报告
????????也可以这样说:
????????????dataDemo(存放数据)>> readDemo(读取数据)
????????????useRequests(发送请求)>>testDemo(生成报告)
????????2.读取csv数据流程
????????????1.通过excel另存为csv
????????????2.读取
????????????????import csv
????????????????classReadCsv():
????????????????defreadCsv(self):
????????????????item= []
????????????????rr=csv.reader(open("../dataDemo/123.csv"))
????????????????????forcsv_iinrr:
????????????????????????item.append(csv_i)
????????????????????????item=item[1:]
????????????????????????returnitem
????????????3.requests请求接口返回状态码
????????????????import requests
????????????????fromreadDataDemo.readcsvimportReadCsv
????????????????r=ReadCsv()
????????????????????????ee=r.readCsv()
????????????????????????# print(ee)
????????????????????????classRequestCsv():
????????????????????????def requestsCsv(self):
????????????????????????????item= []
????????????????????????????????forcsv_iinee:
????????????????????????????????if csv_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
????????????3.requests请求接口返回状态码
????????????4.生成测试报告
第十九单元 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"的所有元素
image-20210131110106391.png
4)通过父子关系
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
实现SearchPage
实现TestCase
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 查看手机日志
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将停止运行
9.Monkey异常分析
8.手机兼容性测试
? App云测试平台:Testin、贯众云测试、百度MTC、阿里MQC等
9.真机测试
手机打开开发者选项→勾选USB调试→输入adb devices监测连接设备
移动端测试知识概览
1.移动端测试是什么
移动端测试是指对移动应用进行的测试,即实体的特性满足需求的程度
2.移动端测试分类
1.app功能测试
兼容性测试、异常测试、升级安装卸载测试、健壮性测试
2.App自动化测试
? ? 优点
1.高效数据绝对正确
2.不需要人工干预
3.回归测试
3.主流的移动端自动化工具
1.Robotium:支持java,仅支持Android系统,不支持跨应用
2.Macaca:支持java,Python,Node,js,支持Android和ios系统,支持跨应用
3.Appium:支持java,c#,php,perl,rubyPython,Node,js,支持Android和ios系统,支持跨应用
4.UIAutomatorviewer手机控件查看工具
1.工具简介:用来扫描和分析Android应用程序的UI控件的工具
2.how使用
1.进入SDK目录下的tools目录,打开uiautomatorviewer
2.电脑连接真机或打开android模拟器
3.启动待测试app
4.点击uiautomatorviewer的左上角Device Screenshot,会生成app当前页面的UI控件截图
5.选择截图上需要查看的控件,即可浏览该控件的id,class,text,坐标等信息
APP移动端测试高级
1.Appium介绍
Appium是一个移动端的自动化框架,可用于测试原生应用、移动网页应用和混合型应用,且是跨平台的
2.环境搭建
需准备:jdk1.6.0、android-sdk_r24.3.4-windows、python2.7、appium1.4.13.1、Node.js、Appium-Python-Client
Appium库安装:
3.Appium使用
1.打开模拟器或者真机的应用
2.脚本内启动其他app:driver.start_activity(appPackage,appActivity)
3.关闭app:driver.close_app()? # 关闭当前操作的app,不会关闭驱动对象
4.关闭驱动对象:driver.quit()
4.App基础操作API
1.前值代码
2.安装APK到手机:driver.install_app(app_path)
3.手机中移除App:driver.remove_app(app_id)
4.判断APP是否已安装:driver.is_app_installed(bundle_id)
5.从手机中拉取文件:
????6.获取当前屏幕内元素结构:driver.page_source
5.手机空间查看工具uiautomatorviewer
1.工具简介:用来扫描和分析Android应用程序的UI控件的工具
2.how使用:1.进入SDK目录下的tools目录,打开uiautomatorviewer
2.电脑连接真机或打开android模拟器
3.启动待测试app
4.点击uiautomatorviewer的左上角Device Screenshot,会生成app当前页面的UI控件截图
5.选择截图上需要查看的控件,即可浏览该控件的id,class,text,坐标等信息
6.App元素定位操作
1.Appium常用元素定位方式
id→id属性值 :find_element/s_by_id(id_value) # id_value:为元素的id属性值
class→class属性值:find_element/s_by_class_name(class_value) # class_value:为元素的class属性值
xpath→xpath表达式:find_element/s_by_xpath(xpath_value) # xpath_value:为可以定位到元素的xpath语句