最近换了新工作,公司让使用python写自动化测试脚本,紧急学习中
课程体系
基础入门:语法、常用数据类型、条件语句、异常处理、类与对象、单元测试
接口自动化:P2P业务+unittest+request+ddt+excel+mysql+smtp+loging+jenkins
+svn
Web自动化:UI层+pytest+selenium+PageObject+jenkins
APP自动化:UI层+pytest+appium+jenkins
RF:RF+接口 RF+web RF+app RF+jenkins
编码工具
- python 3.x --->解释器
- pycharm社区版--->编辑器
- 认识编辑器
- pycharm中常用的文件类型
基础语法
标识符
-
标识符:写代码过程中自己取的名字
- 项目名:project name
- 包名:package name
- 模块名:.py python文件名
-
命名规范:
1.数字、字母、下划线组成,不能以数字开头,区分大小写
2.见名知意
3.不同的字母、数字最好用下划线隔开,提高可读性
class_0901
4.不能使用关键字
数据类型
-
数字类型number:整型 浮点型
- 整型 int
- 浮点型 float
布尔类型 bool boolean
只有两个值 True False,首字母必须大写-
字符串 str
成对的单引号、双引号、三引号
''
""
''' '''
单个字母、数字、汉字、单个符号都称之为一个元素
使用
len(数据)
统计数据的长度-
字符串取值:
字符串名[索引值]
- 正序(从0开始) 0 1 2 3 4 5
- 倒序 -6 -5 -4 -3 -2 -1 (从-1开始)
-
字符串取多个值:(又叫切片)
字符串名[索引头:索引尾:步长]
- 步长默认为1
- 取头不取尾
字符串倒序输出
print(a[::-1])
-
字符串分割
字符串.split(可以指定切割符,可以指定切割次数)
- 返回一个列表类型的数据,列表中的元素都是字符串类型
a='hello!' print(a.split("l")) #输出:['he', '', 'o!'] print(a.split("l",1)) #输出:['he', 'lo!']
- 返回一个列表类型的数据,列表中的元素都是字符串类型
-
字符串替换
字符串.replace(替换值,新值,替换次数)
a='hello!' print(a.replace("l","@",1)) #输出:he@lo! print(a.replace("l","@",2)) #输出:he@@o!
-
字符串的去除指定字符
字符串.strip(指定字符)
- 不指定字符时,默认去掉空格
b=' hello!' print(len(b)) #输出:7 print(b.strip()) #输出:hello! print(len(b.strip())) #输出:6
- 只能去掉首和尾的指定的字符
b='hel lo!' print(len(b)) #输出:7 print(b.strip()) ##输出:hel lo! print(len(b.strip())) #输出:7 c='hel!lo!' print(len(c)) #输出:7 print(c.strip("!")) #输出:hel!lo print(len(c.strip("!"))) #输出:6
- 不指定字符时,默认去掉空格
-
字符串拼接 使用
+
进行拼接- 保证
+
左右两边的变量类型要一致 - 强制转换
str(数字)
,将数字转化为str类型age=18 name="Andy" print("今天是"+name+"的"+str(age)+"岁生日,祝他快乐") # 输出:今天是Andy的18岁生日,祝他快乐
- 保证
-
字符串的格式化输出 format
- 第一种format:使用
{}
占坑age=18 name="Andy" print("今天是"+name+"的"+str(age)+"岁生日,祝他快乐") print("今天是{}的{}岁生日,祝他快乐".format(name,age)) #同一个效果 print("今天是{0}的{1}岁生日,祝他快乐".format(name,age)) #同一个效果 #format后面可以填n个参数,通过在{}中加入索引,打印不同的变量值
- 第二种format:使用
%
占坑,%s字符串 %d整数 %f浮点数 %2.f保留2位小数age=18 name="Andy" print("今天是"+name+"的"+str(age)+"岁生日,祝他快乐") print("今天是%s的%d岁生日,祝他快乐".format(name,age)) #同一个效果 print("今天是%s的%s岁生日,祝他快乐".format(name,age)) #同一个效果 #format后面只能按顺序赋值,%s可以填任何数据类型
- 第一种format:使用
-
列表 list 符号
[]
- 可以存在空列表
a=[]
- 列表可以包含任何数据类型
- 列表里的元素,通过逗号来分割
- 列表里面的元素也是有索引值的,从0开始
- 获取列表里的单个值:
列表[索引值]
- 列表的切片:同字符串切片
列表名[索引头:索引尾:步长]
- 往列表中添加数据
列表名.append(要加的数据)
追加在列表的末尾,有序,且一次只能追加一个元素 - 往列表中插入数据
列表名.insert(插入位置的索引,插入的数据)
- 删除
列表名.pop(索引值)
不传值,默认删除最后一个元素。pop()
返回值是删除的那个值 - 指定删除
列表名.remove(要删除的值)
- 修改值
a[索引值]=赋值
- 什么时候用列表?存储的数据属于同一个类型的时候,建议使用列表
- 可以存在空列表
-
元组 tuple 符号()
- 可以存在空元组
a=()
- 可以包括任何的数据类型
- 元组的元素通过逗号分割
- 元组的元素也是有索引值的,从0开始
- 获取元组里的单个值:
元组[索引值]
- 元组的切片:同字符串切片
元组名[索引头:索引尾:步长]
- 元组不支持任何修改,即增删改,但是如果元组中有列表,是可以修改列表中的元素的
- 什么时候使用元组?保护数据不被修改,如数据库操作
a=(1,'0.02','hello',[1,2,3],True) a[3]="中国" # 会报错 a[3][1]="China" print(a) # 输出:(1, '0.02', 'hello', [1, 'China', 3], True)
- 如果元组只有一个元素,要加一个逗号
a=("happy") print(type(a)) #<class 'str'> b=(12) print(type(b)) #<class 'int'> c=("happy",) print(type(c)) #<class 'tuple'> d=(12,) print(type(d)) #<class 'tuple'>
- 可以存在空元组
-
字典 dict 符号
{}
- 可以存在空字典
a={}
- 字典中数据的存储方式:
key:value
- 字典中的value可以包括任何数据类型
- 字典的元素通过逗号分割
- 字典是无序的,没有索引值,可以通过key找value
- 字典取值
字典[key]
- 字典删除
pop(key)
因为是无序的,所以必须指定key,返回值是删除的值 - 新增值
字典名[新key]=value
- 修改值
字典名[已存在key]=value
- 什么时候使用字典?每个数据类型不一样,代表的内容也不一样,用键值对方式表示时
a={"class":"python01","gender":"女","age":12,"score":[98,99,92]} print(a["class"]) #python01 print(a) #{'class': 'python01', 'gender': '女', 'age': 12, 'score': [98, 99, 92]} a.pop("age") print(a) #{'class': 'python01', 'gender': '女', 'score': [98, 99, 92]} a["name"]="Tom" print(a) #{'class': 'python01', 'gender': '女', 'score': [98, 99, 92], 'name': 'Tom'} a["age"]=18 print(a) #{'class': 'python01', 'gender': '女', 'score': [98, 99, 92], 'name': 'Tom', 'age': 18}
- 可以存在空字典
- 判断数据类型
type(数据)
运算符 (常用5大类)
-
算术运算符
+ - * / %
- 模运算 取余
%
- 模运算 取余
-
赋值运算符
= += -=
a=5
-
a+=5
相当于a=a+5
-
a-=5
相当于a=a-5
-
比较运算符
> >= < <= == !=
- 比较结果返回值是布尔值:True False
-
逻辑运算符
and or not
- 返回结果是布尔值:True False
-
成员运算符
in、 not in
s="hello" print("e" in s) #True print(("e" not in s)) #False a={"class":"python01","gender":"女","age":12,"score":[98,99,92]} print("女" in a) #False print("class" in a) #True #对于字典 in 和not in判断的是key,不能判断value
if语句
控制语句:顺序从上到下、 分支if 、循环for while
- 判断语句 关键字
if...elif...else
-
语法
# 语法1 if 条件语句: 子语句 ###### 分割线 ###### # 语法2 if 条件语句: 子语句 else: 子语句 ###### 分割线 ###### #语法3 if 条件语句: 子语句 elif 条件语句: 子语句 else: 子语句
靠缩进来分级
-
if后的条件语句:
1.比较/逻辑/成员运算均可
2.如果是空数据,其结果为False;如果是非空数据,其结果为True
3.直接使用True或False,但是这种方式很鸡肋
if 和elif后面可以加条件语句,else后面不能加条件语句
-
示例:接收用户输入年龄的功能,根据年龄展示不同的欢迎语
age=input("请输入你的年龄") #接收输入 if age.isdigit(): #如果字符串只包含数字则返回 True 否则返回 False age=int(age) if age>=18: print("恭喜你,成年了") elif age<0: print("别闹,妖怪,请输入正确的年龄") else: print("还是个小屁孩") else: print("不是数字,请重新输入")
-
循环语句
-
for循环
- 语法
for item in sequence:#遍历sequence的元素,赋值给item,所以这里的item不用提前赋值 代码块
- sequence可以是字符串、列表、元组、字典、集合等……
- 字典数据遍历的是key,如果要遍历value,使用
字典名[key]
a={"name":"xiaofang","age":18} for i in a: print(i) #输出: #name #age for i in a: print(a[i]) #输出: #xiaofang #18
- 字典里可以获取字典的key或value
字典名.values()
字典名.keys()
a={"name":"xiaofang","age":18} #循环value for item in a.values(): print(item) #循环key for item in a.keys(): print(item)
- 循环中常涉及的一个函数
range(m,n,k)
m头 n尾 k步长,k不写默认为1,m不写,默认为0,取头不取尾
- 嵌套循环
#把列表中的每个元素都单独打印出来 L=[["monica","xiaohua","dave"],["helen","san"]] for item in L: #每循环一次,拿到一个子列表 for a in item: #每循环一次,拿到子列表中的元素 print(a) #打印直角三角形 for i in range(1,6): for a in range(1,i+1): print("*",end='') #内循环不换行 print("") #外循环换行
- 语法
-
while循环
-
语法
while 条件表达式:#逻辑表达式、成员运算、比较运算、空数据、布尔值等 代码块
- 执行顺序:首先判断条件表达式,如果为True,就执行代码块,否则不进入代码块;执行完毕后,继续判断条件表达式,继续执行代码块,直到条件表达式结果为False结束循环。
- 防止进入死循环,需要加一个变量来控制循环次数
a=0 while a<10: print("这是第{}次循环".format(a+1)) a=a+1
-
while和if语句搭配使用 break continue
- break 结束循环,跳出循环
- continue 跳出本次循环,开始下一次循环
-
练习
#练习 #passwd={"admin":"123321","user1":"123456"} #1.设计一个程序,不同的用户名和对应的密码存在字典中,输入正确的用户名和密码可以登录系统 #2.首先输入用户名,如果用户名不正确或者为空,则一直提示输入正确的用户名 #3.当用户名正确时,提示输入密码,如果密码跟用户名不对应,则提示密码错误重新输入 #4.当密码输入错误三次时,中断程序,密码输入错误时,提示还有几次机会 #5.用户名、密码都正确时,提示登录成功 passwd={"admin":"123321","user1":"123456"} username=input("请输入用户名: ") count_err=0 #记录密码输入错误的次数 while username not in passwd.keys(): username=input("请输入用户名: ") password=input("请输入密码: ") while True: if password != passwd[username]: count_err+=1 if count_err==3: print("密码错误3次,中止交易") break else: print("密码错误,剩余次数{}".format(3 - count_err)) password = input("请输入密码: ") continue else: print("登录成功") break
-
python内置函数
函数的特点:重复使用
为了提高程序员的开发效率,Python提供了很多可以直接拿来用的函数,每个函数都可以帮助程序员实现某些具体的功能。
如:
print input len type str int list range pop append insert keys split replace remove clean
python函数
-
语法
def 函数名(参数1,参数2……): #此处参数为形参,形式参数,不是具体的值 函数体 #希望这个函数实现什么功能
调用函数:
函数名(参数1,参数2……)
,这里的参数为实参,实际参数,具体的值return 值
函数返回值,表示调用函数时,这次调用会返回一个return后面的值,return后面的语句不会执行默认参数
def 函数名(class,name="monica"):
,name="monica"
就是默认参数,如果调用时,不传name的值,默认name="monica",如果name传了值,name就等于传入的值,默认参数要放在形式参数的后面-
调用函数传参时两种方式,按形参的顺序或者指定形参对应的值
# 求1-100的加和 # 函数 def add(start,end): sum=0 for item in range(start,end+1): sum+=item return sum # 调用函数两种方式 add(1,100) #按顺序赋值 add(end=100,start=1) #指定赋值
-
动态参数,又叫不定长参数
def 函数名(*args):
不限制参数的长度、个数,在函数内部以元组来传递def make_sanwich(*args): all='' num=0 print(len(args)) for item in args: all+=item #最后一个不要"、" while num!=len(args)-1: all+='、' num+=1 break print("您的三明治包含了"+all) make_sanwich("花生","培根","火腿","菜叶子") make_sanwich("花生","菜叶子")
-
关键字参数 key-value keyword
def 函数名(**kwargs):
kwargs在函数中体现为字典def kw_func(**kwargs): print(kwargs) kw_func(x=7,classname="进阶班") #输出:{'x': 7, 'classname': '进阶班'}
形式参数、默认参数、动态参数、关键字参数可以混用
-
写函数的思路
1.先用代码实现功能,可以选取一组数据来证明自己的代码是否正确
2.变成函数,加def
3.提高复用性,如加入参数
-
变量的作用域
a=1 # 全局变量 def add_1(b): print(a+b) def add_2(b): a=5 # 局部变量 print(a+b) add_1(10) # 11 add_2(10) # 15 print(a) # 1
-
全局变量和局部变量区别:
1.作用域不同:全局变量,在模块里都可以调用;函数的局部变量,只能作用于函数
2.当全局和局部变量同名且同时存在时,函数优先调用局部变量
3.当没有局部变量,函数优先调用全局变量
4.global关键字,声明这是一个全局变量
a=1 # 全局变量 def add_3(b): global a #声明a是全局变量 a=10 #给a赋值 print(a+b) add_3(10) print(a) # 10
-
怎么看函数
按住command键(win是ctrl键),鼠标点击要查看的函数,就可以跳转到该函数定义的模块-
怎么引入不同的模块
-
安装模块
-
a.在线安装:
1.终端-->
pip install 模块名
(国外源,安装慢,可能超时)2.国内源: 终端-->
pip install -i 国内源url 模块名
3.file-setting-project interpreter-点击+-搜索模块名-勾选-install package(通过旁边的manage repositories添加国内镜像源)
-
b.离线安装:
在python官网或者网上找到离线安装包
解压--拷贝解压后的文件到python的安装目录下
python setup.py install
包一般都被安装在
lib
或lib-->sitepackage
下
-
-
使用模块
-
a.python自带的、第三方库怎么导入
1.import
package的结构是
lib>email>mime>base.py
导入模块base.py:
improt email.mime.base
使用base.py中的方法:
email.mime.base.方法名()
如果是lib下的模块,可以直接
import os
2.from...import (推荐用法)
导入模块base.py:
from email.mime import base
使用base.py中的方法:
base.方法名()
-
b.自己写的怎么导入
package的结构是
项目名(python11)>package(first_demo)>basic_01>add.py
导入模块:
import first_demo.basic_01 from add
(除了顶级目录不用写,一层一层写下来)使用add.py中的方法:
add.方法名()
-
-
-
理解
if __name__ == '__main__':
#add.py文件,自己写的模块 def add_two(a,b): print(a+b) print("这是一个开始,add.py模块") add_two(10,20) print("这是一个结束,add.py模块")
#demo.py,需要导入自己写的模块add.py from py_0906 import add add.add_two(12,12)
此时,虽然我们在demo.py中只是调用add.py中的add_two方法,但是add.py中的所有代码都会运行,输出的结果是:
这是一个开始,add.py模块 30 这是一个结束,add.py模块 24
怎样避免这种情况呢?只调用我们想要调用的函数,使用
if __name__ == '__main__':
#add.py文件 def add_two(a,b): print(a+b) if __name__ == '__main__': print("这是一个开始,add.py模块") add_two(10,20) print("这是一个结束,add.py模块")
if __name__ == '__main__':
表示主程序的执行入口,只有当你在当前模块下执行时,代码才会执行,别人调用时,不会执行。一般用于写一些自测代码。__name__
是当前模块名,当模块被直接运行时模块名为__main__
。这句话的意思就是,当模块被直接运行时,以下代码块将被运行,当模块是被导入时,代码块不被运行。现在运行add.py结果是:
这是一个开始,add.py模块 30 这是一个结束,add.py模块
运行demo.py结果是
24
冒泡排序
a=[11,29,53,6,7,0,3]
for i in range(0,len(a)): #第一轮
for j in range(1,len(a)):
if a[j-1]>a[j]:
a[j-1],a[j]=a[j],a[j-1] #python中互换位置的写法
print(a)