软件测试进阶篇----Python

Python

python语言的学习技巧:多写多敲

要求能够掌握基础知识,能够使用python实现自动化脚本的开发即可!!!

一、python语言的特点

  • python是一种胶水语言:python需求和其他的行业结合在一起才能发挥更大的作用
    • 现在主流的自动化测试python/java栈
    • java/vb(qtp、uft)/JavaScript(selenium)
  • python是一种高级语言:语法越来越简单了、更好理解了、支持面向对象了
  • python是一门弱类型语言:给变量传什么数据,该变量就是什么类型的
  • python是跨平台的语言:一处编码、处处可用(不同的OS)
  • python是一门解释型语言:逐行解释执行
  • python是一门面向对象语言:一切皆是对象
  • python是一门简单易学的自动化脚本开发语言

二、python开发环境(熟练掌握)

要求熟练掌握环境搭建

  1. python软件包的安装

    python分为python2版本和python3版本

    1. 在D盘创建一个文件夹:python、python38,注意不要有空格,不要有中文字符
    2. python安装时候选择自定义安装(以免后面找不到安装目录)、勾选添加python到环境变量path(在任何cmd路径下都可以执行python命令)
    3. 注意:安装的软件,不允许对路径中目录名称进行修改、删除、移动
    4. 直接点下一步直到完成。

    环境变量配置:

    1. 我的电脑—属性—高级属性设置—环境变量
    2. 系统环境变量—path—点击编辑,将python安装目录粘贴到path中即可
  2. 安装集成开发环境(IDE)工具—pycharm

  3. 使用pycharm创建一个工程目录。。

  4. python代码三种执行方式

    1. 命令行交互式执行
    2. 通过命令行直接运行py文件
    3. 通过IDE工具开发并运行代码
  5. pip的使用

    pip工具是python语言中的一个包管理(第三方软件管理)工具,负责第三方软件的安装、卸载、更新等。

    和Linux系统下yum命令、nodejs的npm命令功能相似

    安装python是自带pip工具

    • pip帮助信息

      软件测试进阶篇----Python_第1张图片

    • pip安装第三方包

      selenium:是做web的自动化测试的工具

      pymysql:是在python中处理数据库的包,连接数据库、对数据库进行增删改查等操作

      基本命令1:默认安装最新版本:pip install 包名

      ​ pip install selenium

      ​ pip install pymysql

      基本命令2:指定版本进行安装:pip install 包名==x.y.z

      ​ pip install pymysql==1.0.2

      基本命令3:临时指定指定镜像服务器下载:pip install 包名-i http://mirrors.aliyun.com/pypi/simple/

      国内常用的镜像源服务器有:

      • 清华:https://pypi.tuna.tsinghua.edu.cn/simple

      • 阿里云:http://mirrors.aliyun.com/pypi/simple/

      • 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/

      • 华中理工大学:http://pypi.hustunique.com/

      • 山东理工大学:http://pypi.sdutlinux.org/

      • 豆瓣:http://pypi.douban.com/simple/

      基本命令4:永久配置镜像源服务器下载

      ​ 在C:\Users\用户名目录下创建pip的文件夹。

      ​ 在pip文件夹下创建一个txt文本文件,重命名为pip.ini文件

      ​ 编辑文件内容:

      ​ [global]
      ​ index-url = https://pypi.tuna.tsinghua.edu.cn/simple
      ​ [install]
      ​ trusted-host=pypi.tuna.tsinghua.edu.cn

      基本命令5:批量安装包

      提前准备一个reqirement.txt的文件。格式要求如下

      pymysql==1.1.0
      selenium==4.12.0
      

      pip install -r reqirement.txt

      软件测试进阶篇----Python_第2张图片

    • pip查看安装的包

      基本命令:pip list

    • 卸载包

      基本命令:pip uninstall 包名

      ​ pip uninstall pymysql

三、Python运行原理

  1. 编译型语言

    • 需要对高级语言的源代码(.java.c等)进行一次完整的编译,如果编译通过就生成计算机可识别字节码,可以运行字节码;如果失败就不能运行。

      常见的编译型语言有:java,C,C++语言。

  2. 解释型语言

    由解释器对源代码(.py)进行逐行解释、并运行的过程。

    常见的解释型语言:python\php\ruby语言等。

  3. 运行原理

    • 先创建一个xx.py结尾的python源码文件
    • cmd—》python xx.py:由python解释器解释源码为字节码
    • 执行字节码输出结果
  4. Python字符集

    Python源文件是utf-8字符集格式。

    utf-8是一种可变长度的unicode编码。

Python基础语法

一、关键字

在python语言中,给特定的单词赋予了特定的功能、含义,这些单词就称为关键字。

在高级IDE编译器中,关键字会以不同的颜色标注。
软件测试进阶篇----Python_第3张图片

  • 数值类型的关键字:False、True、None
  • 逻辑控制类:if、elif、else、for、while、break、continue、return
  • 类、方法创建:class、def
  • 异常处理:try、except、finally
  • 导包:import、from、as

二、标识符

标识符是给python中的变量、方法、类等取的名字。

标识符定义的要求:

  • 见名知意:age、name、gender等
  • 通过下划线连接多个单词:student_name、studentAge
  • 必须是由数字、字母、下划线组成,不能以数字开头
  • 标识符不能是关键字
  • 标识符大小写敏感的:age、Age

三、python中的注释

注释是python中的不可执行代码,有三种注释类型

  • 单行注释:对变量或每一行代码做注释,方便理解,使用#号进行单行注释

  • 多行注释:使用的是’‘’xxxx‘’‘或者”“”dddd“”“

  • 文档注释:在方法中的第一行位置使用‘’‘xxxxx’‘’,“”“xxxxx”“”作为文档注释

    文档注释,也叫文档字符串,是python特有的一种用法。

    可以通过方法名**.__ doc __**来获取文档注释的内容。

四、行和缩进

  1. 缩进

    缩进是python中特有的一种确定代码块、作用域范围的用法。

    相同缩进的代码属于同一代码块,具有相同的作用域范围。

    缩进一般采用4个、8个空格,也可以是一个tab键

  2. 一行内建议写一条语句,python中的语句是不需要分号结尾的。

    一条语句是可以写在多行的,多行语句写法,通过反斜杠\实现多行。

    对于python中带了{}、[]、()数据类型,直接多行显示不用反斜杠也可以

五、输入输出方法

  1. 输入方法

    从键盘输入数据到代码中,使用input()方法,返回的是字符串格式的数据。

  2. 输出方法

    使用print()将数据输出到控制台

  3. 导包

    import 包名/模块

    from 包名/模块 import方法名

六、数据类型

python是一种弱类型语言,指的是定义变量的时候不需要指定数据类型。

  1. 变量

    代码运行过程中,其值会发生改变的量,称之为变量。

    在python中使用“”,‘’定义字符串数据类型。

    name=“red”
    name=“blue”
    
    • name是变量,是标识符。

    • “red”和“blue”是字符串常量(不会变),一般存储在常量池中,每个常量都有自己独立的首地址

    • name=“blue”:变量name指向常量blue的首地址;给变量name赋值blue

变量的定义格式:变量名=初始化值

  • 变量不需要声明(不需要指定数据类型),给什么数据就是什么类型(其类型是变量指向的初始化值的类型)
  • 创建变量必须进行初始化。初始化才能创建
  • =是一个运算符号,赋值、指向
  • 一般一行内创建一个变量,也允许一行创建多个变量
aa=bb=cc=12
a,b=12,23
print(a)
print(b)

a,b=b,a
print(a)
print(b)
# 输出
12
23
23
12

python中有几大数据类型:

  • 数值类型
    • 整数
    • 小数
    • 复数
    • 布尔类型:True、False
  • 序列类型
    • 字符串类型
    • 元组
    • 集合
  • 字典类型

1、数值类型

  1. 整数类型

python整数没有长度限制,想存多大就多大,而且数据都是准确的。

  1. 浮点型数据

浮点型数据是保留17位的精度,17位以后数据不再准确

# 定义一个浮点型数据
salary = 12000.12
print(salary)
输出:12000.12


# 浮点型数据是保留17位的精度,17位以后数据不再准确
salary2 = 1.12345678901234567890
print(salary2)
输出:1.1234567890123457


# 使用科学计数法来写:2*e^2
salary3 = 2e2
print(salary3)
输出:200.0
  1. 布尔值

    只有True和False

# 定义布尔类型数据
flag=False
print(flag)
  1. type()方法的使用
# 使用type()方法可以识别变量的数据类型
# python一切皆是对象,数据类型也是对象
print(type(age))
# 
print(type(salary))
# 
print(type(flag))
# 

score = int(input("请输入你的成绩:"))
# 
# 数字类型的字符串是可以强转为整数的
print(type(score))
# 
  1. 进制和进制转换(了解)

    进制:进位的方式,逢几进一就是几进制数据。

    常见的进制有:

    • 二进制:是由0、1组成,逢2进1,是由0b开头
    • 八进制:由0、1、2、3、4、5、6、7组成,逢8进1,是0o开头
    • 十进制:由0、1、2、3、4、5、6、7、8、9组成,逢10进1
    • 十六进制:由0、1、2、3、4、5、6、7、8、9、a、b、c、d、e、f组成,逢16进1,由0x开头

其他进制转10进制的算法:8421码转化

二进制转十进制::01010101=1+0+4+0+16+0+64+0=85

八进制转十进制:image-20230907225049912

十进制转其他进制:十进制数据除以2,整除取余数,直到除尽,余数反转就是二进制

25对应的2进制数据为:11001

  • python中提供了由10进制转为其他进制的方法:

    bin():转二进制(B)

    oct():转八进制(O/Q)

    hex():转十六进制(X)

    int():转十进制

  1. 常见数值数据处理的方法

    主要讲了math模块和random中的方法使用

# math模块实现算术运算
import math

# 查math模块的用法,有哪些方法可以用
print(abs(-12))  # 绝对值
print(math.floor(12.3))  # 向下取整数
print(math.ceil(12.3))  # 向上取整数
print(math.pi)  # 圆周率
print(math.sqrt(4))  # 开根号
print(math.sin(math.pi / 6))	#求sin30°的值

import random
# 用于处理随机数的
randzhengshu=random.randint(1,9999)
print(randzhengshu)

2、字符串

  1. 字符串的定义

    '''
    1、python3中的字符串都是unicode编码的
    2、字符串是以""或者''来定义的
    3、字符串是不可变的一种数据类型
    4、python的字符串中可以通过\实现转义
    5、在字符串前面添加r或R起到取消转义的功能(也称之为自然字符串)
    '''
    
    name = "测试王同学"
    teacher_name = 'alle\n'
    teacher_name = 'alle\tn'
    teacher_name = 'alle\\tn'
    print(teacher_name)
    
    teacher_name4 = r'alle\n'
    teacher_name5 = R'alle\n'
    print(teacher_name4)
    print(teacher_name5)
    
  2. 编码、解码和乱码的概念

    编码:采用指定字符集将字符转为字节码的过程,使用的方法是encode()

    解码:采用指定的字符集将字节码转为字符的过程,使用的decode()

    乱码:同一个字符,采用不同的编码和解码字符集进行操作,就会出现乱码的情况,建议编码和解码使用相同字符集

    # 将好这个中文使用gb2312编码为字节码:b'\xba\xc3'
    print("好".encode("gb2312"))
    # 将好这个中文使用utf-8编码为字节码:b'\xe5\xa5\xbd'
    print("好".encode("utf-8"))
    
    a = b'\xba\xc3'
    # 将a变量对应的整数,解码成汉字
    print(a.decode('gb2312'))
    
    b = b'\xe5\xa5\xbd'
    # 将a变量对应的整数,解码成汉字
    print(b.decode('utf-8'))
    
    # 使用gb2312编码“小”这个汉字
    print("小".encode("gb2312"))
    c = b'\xd0\xa1'
    print(c.decode("gb2312"))
    print(c.decode("utf-8"))    # С
    
  3. 字符串的格式化输出

    %s:字符串占位符

    %d:整数占位符

    %f:浮点数占位符

    %m.nf:限制宽度和精度的浮点数占位符

# 字符串的格式化输出
print("软件测试")
# %s:表示字符串的占位符
name = input("输入课程姓名:")
age = int(input("请输入课程号:"))
price = float(input("请输入价格:"))
print("我的课程是:%s,课程号是:%d,价格是:%10.2f元" % (name, age, price))

print("我的老师的名字:{}".format(age))

  1. 常见的字符串处理方法
# 字符串处理的常见方法(函数)
# 可以通过索引号取每个字符,有正向索引(0~总长度-1)和反向索引(-1到-总长度)的使用
# 取值的格式:字符串变量名[索引号]
# 索引号不能越界
teacher_name="   测试blue老师          "
name="bluE"
print(teacher_name[-2])
# 获取a字符所在字符串中的索引号
print(teacher_name.index("a"))
#去除字符串中空格的用法
print(teacher_name.rstrip())
print(teacher_name.lstrip())


# 将name的值首字母大写
print(name.title())
print(name.upper())
print(name.lower())

#按照固定的格式拆分字符串
phone="186-1234-4567"
print(phone.split("-"))

数值和字符串是属于最基础的两种类型,是属于最终的数据展示格式。

3、序列

序列是多个相同特点数据类型的统称,包括字符串类型、列表和元组类型

序列类型特点:

  • 有序,按照存入的顺序取出数据
  • 可索引,通过下标获取指定索引对应的元素
  • 可切片,从大的字符串切出多个子串的用法
  • 可重复,元素是可以重复的

序列通用的运算符:

  • in/not in:成员运算符,格式:xxx in序列
  • not in
  • +:拼接序列
  • *:复制序列
  • [索引号]:通过索引获取数据
  • [start:end:step]:切片
# 定义一个字符串序列
name = "blue"
# 有序
print(name)

# 可索引
print(name[0])

# in/not in:成员运算符号
print("a" in name)
print("aa" in name)
print("ll" in name)


# + : 作为序列拼接功能使用
role = "老师"
shenfen = name + role
print(shenfen)

# * : 复制序列
print("blue" * 2)
print(name * 2)

# 都可以切片,格式:序列名[start:end:step],step默认是1,start和end指的是索引号
# []中至少出现一个:才叫切片
# start和end是左闭右开[1,10),可以取到start对应的值,但是取不到end对应的值
print(shenfen[0:3])
print(shenfen[0:7])
print(shenfen[0:8])
print(shenfen[:]) # 切所有

print(shenfen[::1])
print(shenfen[::2])
print(shenfen[::-1])

print(shenfen[-7:-1])
print(shenfen[-7:])

序列通用的方法:

序列类型也叫容器类型,其中有多个元素!!

  • len(序列名):计算一个序列的长度、元素的个数
  • 序列名.index(x)
  • max(序列名)
  • min(序列名)
  • 序列名.count(x)
# shenfen变量元素个数是多少?
print("shenfen变量的元素个数(长度):%d个"%len(shenfen))
# 序列中的最大值和最小值
print(max(shenfen))

aa = "aAbB"
print(max(aa))
print(min(aa))

# 将字符转为整数
print(ord("a"))
# 将整数转为字符串
print(chr(65))
print(ord("老"))
print(ord("师"))

bb = "123456"
print(max(bb))
print(min(bb))

# index(x)获取指定子串x在大串中的索引号,找不倒指定的子串就会报错
shenfen = "blue老师"
print(shenfen.index("b"))
print(shenfen.index("老"))
print(shenfen.index("老师"))

# index(x,start,end) : 在指定的范围内查找指定子字符串x的索引号
print(shenfen.index("老",4,7))


# count(): 统计序列中指定元素的个数
print(shenfen.count("a"))
print(shenfen.count("l"))
print(shenfen.count("ll"))

4、序列—字符串

  • 字符串是序列,有序、可索引、可切片、可重复、不可被改变
  • 在查询字符索引的find()方法–对比index()方法。
  • 在查不到指定的元素的时候返回-1,查到就返回索引,其他的用法和index()相同
# find()的使用--只能使用于字符串类型(序列和元组不能用)
print(shenfen.find("a"))
print(shenfen.find("l"))
print(shenfen.find("ll"))
print(shenfen.find("老师"))
print("~~~~~~~~~~~~~~~~~~~~~~~~~~")
print(shenfen.find("abc"))
print(shenfen.find("老",4,7))

5、序列–列表

  • 列表是一个容器类型,通过[]和,来定义,其元素可以是任意类型(数字、列表、字符串、字典、元组等)。

  • 列表的特点:有序、可索引、可切片、可重复、可改变

  • 列表的index和remove方法在找不到元素时,运行时会报错,而不是像其他语言一样返回-1,或者什么也不做。因此,使用index和remove方法,更好的方式是像下面这样。

    a = [10, 20, 30]
    index = a.index(66) if 66 in a else -1
    # 输出:-1
    print(index)
    if 20 in a:
        a.remove(20)
    # 输出:[10, 30]
    print(a)
    
  1. 定义列表

    list=[1,2,3,4,5,6]

    list2=[“blue”,’王同学’,’rourou’]

    info=[[“blue”,28],[“王同学”,25],[‘rourou’,23]]

list1 = [1,2,3,3,4,5,6]
list2 = ["blue",'王同学',"rourou"]
info = [["blue",28],["王同学",25],["rourou",23]]

# 列表是有序的
print(list1)
# 列表可索引(正向和反向索引)
print(list1[0])
print(list1[-1])
print(info[2][0])

# 可切片
print(info[:])
print(info[1:])
print(info[::-1])

# 可改变:改变变量中元素
# print(id(list1))
# list1[0] = 12
# print(list1)
# print(id(list1))


# str1 = "abc"
# print(id(str1))
# str1 = "cba"
# print(id(str1))

# + *
print(list1+list2)
print(list1*2)
print("-----------------------------------")
print("-"*30)
  1. 列表的常见方法

    1. 给列表追加元素,追加在列表的最后位置-append()

      list2 = ["blue",'王同学',"rourou"]
      list2.append("张同学")
      print(list2)
      
    2. 给列表插入元素,按照指定的位置插入一个元素-insert()

      list2.insert(2,"张同学")
      print(list2)
      list2.insert(0,"张同学")
      # print(list2)
      list2.insert(2,["张同学",20])
      # ['blue', '王同学', ['张同学', 20], 'rourou']
      print(list2)
      
    3. 将一个列表中的所有元素加到另外一个列表中-extend()

      #['blue', '王同学', 'rourou', '张同学', 20]
      list2.extend(["张同学",20])
      print(list2)
      
    4. 给列表删除元素

      1. 删除最后一个元素-pop(),给参数,给哪个索引号,就删除哪一个值

        print(list2.pop(4))
        # 不带参数的话默认删除最后一个元素
        print(list2.pop())
        print(list2)
        
      2. 根据指定的值删除元素-remove(x)

        print(list2.remove(20))
        print(list2)
        print(list2.remove("blue"))
        print(list2)
        
      3. 使用del 删除指定索引号的元素

        del list2[4]
        print(list2)
        
      4. 使用切片删除元素

        list2[3:]=[]
        print(list2)
        
    5. 修改列表元素

      list2[0] = "blue老师"
      print(list2)
      
    6. 查列表元素\元素索引

      print(list2[1])
      print(list2.index("王同学"))
      
    7. 其他方法:

      index()
      count()
      reverse():逆序
      info.reverse()
      print(info)
      print(info[::-1])
      print(info)
      

6、序列–元组

元组是一种序列类型,有序、可索引、可切片、可重复、不可被改变(和字符串类似)

  1. 元组定义:(),但是括号中至少要有一个逗号

    # 定义元组
    tuple1 = (12,)
    # 定义一个空的元组
    tuple2=tuple()
    print(type(tuple2))
    print(tuple2)
    
  2. 元组的特点

    # 元组的特点
    tuple3 = (12,23,4,5,5,6,7,8,[66,88])
    # 有序、可重复
    print(tuple3)
    # 索引和切片
    print(tuple3[0])
    print(tuple3[-1])
    print(tuple3[:])
    print(tuple3[0:5])
    
    # 不可变
    tuple3[0]=1
    # ‘tuple' object does not support item assignment
    # tuple3[-1][0]=12
    print(tuple3)
    
  3. 元组的运算符和方法

    print(tuple3+tuple1)
    print(tuple3*2)
    print(len(tuple3))
    print(tuple3.index(23)) # 求数据的索引
    
  4. 注意事项

    列表可用于需要进行数据动态维护的场景;元组用于敏感型数据的存储(不能随便改)

    字符串是最常用的数据载体,是数据的最终载体,用于数据的磁盘存储、网络传输等

    列表和元组是容器存储的能力,

    不管是列表、元组还是字符串,都可以通过索引偏移获取元素、切片。

7、set集合

  1. set集合特点:无序、不可重复

  2. set集合的创建

    # 定义set集合
    # 使用{}来定义
    set1 = {12, 23, 34, 5, 6, 6}
    set2 = {"a", "aaa", "sds"}
    print(set1)
    print(set2)
    # 定义一个空的set集合
    set3 = {}
    set4=set()
    print(type(set3))
    print(type(set1))
    print(type(set4))
    
  3. 集合运算

    set5={1,2,3,4,5}
    set6={4,5,6,7}
    
    # 差集运算
    print(set5-set6)
    # 并集
    print(set5 | set6)
    # 交集
    print(set5 & set6)
    

8、字典

字典是python中以键值对作为元素的一种数据类型。

其中的键是无序的,不能重复,值可以是任意其他的数据类型

使用{}定义,键:值组成其元素,多个键值对之间用逗号分隔。

  1. 字典的定义

    #字典的定义
    dict1={}
    # 键是不可变的数据类型,可以是字符串、整数、元组等
    dict2={"王同学":"张同学","文章":"马伊琍","邓超":"孙俪","张杰":"谢娜","文章":"姚笛"}
    print(dict2)
    
    # dict3={["aa","bb"]:12}
    dict3={(12,23):12}
    dict3={12:23}
    print(dict3)
    # unhashable type: 'list'
    
  2. 字典的常见用法

    • 查看字典中某个键的值

      print(dict2["文章"])
      print(dict2.get("文章"))
      print(dict2.get("鹿晗"))
      
      # 查看字典中的所有的键\值\键值对
      print(dict2.keys())
      print(dict2.values())
      print(dict2.items())
      
    • 修改和更新功能

      # 更新、增加键值对到字典中
      dict2["黄晓明"]="小海绵"
      print(dict2)
      
      # dict2["鹿晗"]="关晓彤"
      # print(dict2)
      
      dict2.update({"鹿晗":"关晓彤"})
      print(dict2)
      
    • 删除字典的键值对

      # 删除字典中的键值对-pop()
      dict2.pop("邓超")
      print(dict2)
      
    • 补充两个字典的创建方法(了解)

      # 补充两个创建字典fromKeys()
      dict6={}.fromkeys([1,2,3,4])
      print(dict6)
      
      #通过dict()
      a=[1,2,3,4]
      b=[5,6,7,8]
      dict7=dict(zip(a,b))
      print(dict7)
      

9、Python中的数据类型转换

# 定义两个字符串
x='12'
xx='12.23'

# 将x转为整数
a=int(x)
aa=float(xx)
print(type(a))
print(type(aa))

s=str(a)
ss=str(aa)
print(type(s))
print(type(ss))

# 字符串、列表、元组之间的转换
str1='abcdef'
# 字符串转列表
list1=list(str1)
print(list1)
print(type(list1))

#字符串转元组
tuple1=tuple(str1)
print(tuple1)
print(type(tuple1))

# 列表转元组
list2=[12,23,4,5,6,7,7,'aa',[12,4]]
tuple2=tuple(list2)
print(tuple2)
print(type(tuple2))


#eval()的用法
str3='1+1'
print(eval(str3))

七、运算符

  • a=1+2
    • a=1+2:一条赋值语句
    • 1+2:加法表达式
    • 1、2:运算数
    • +、=:运算符
    • a:变量
  1. 算术运算符

    +:加法、正号、序列拼接

    # +
    print(4+6)
    print(+4)
    print('a'+'b')
    

    -:减法、减号

    *:乘法、序列复制

    /:除法、精确除法

    //:取整除法

    # *
    print(2*4)
    print("aaan"*2)
    
    # /
    print(4/2)
    print(3/2)
    
    # // : 取整
    print(4//2)
    print(3//2)
    

    %:取余、取模运算

    **:幂运算

    # %
    print(4%2)
    print(3%2)
    
    # **
    print(3**2)
    
  2. 比较运算符

    结果一定是True和False

    ==:判断是否等于

    >

    <

    >=

    <=

    !=

    a = 12
    b = 23
    c = 34
    print(a==b)
    print(a!=b)
    print(a>b)
    print(a<b)
    print(a>=b)
    print(a<=b)
    # python中的特殊用法
    print(a<b<c)
    
  3. 赋值运算符

    =

    +=:a+=2相当于a=a+2

    -=

    *=

    /=

    **=

    //=

    %=

    d = 12
    d += 2
    print(d)
    
  4. 逻辑运算符

    参与运算的运算数可以是布尔值,结果是布尔值

    and:x and y

    ​ x是True,y是True,结果是True

    ​ x是False,y是True,结果是False

    ​ x是True,y是False,结果是False

    ​ x是False,y是False,结果是False

    or:x or y

    ​ x是True,y是True,结果是True

    ​ x是False,y是True,结果是True

    ​ x是True,y是False,结果是True

    ​ x是False,y是False,结果是False

    not: not x

    ​ x是True,结果是False

    ​ x是False,结果是True

    print(True or False)
    print(False and False)
    print(not False)
    print(a>b and b<c)
    print(a<b and b<c)
    
  5. 位运算

    python的位运算(二进制位),整数都要转为二进制补码进行运算。

    二进制的最高位是符号位:0表正数、1表示负数

    • 原码:直接将整数转为二进制
    • 反码:正数反码和原码相同;负数原码转反码:除了符号位不变,其他位上0变1、1变0
    • 补码:正数的补码和原码也相同;负数反码转补码:除了符号位不变,反码最后一位加1,补码就可以参与运算了
    • 反码:正数的补码和原码相同;负数补码转反码:除了符号位不变,补码最后一位减1
    • 原码:正数的补码和原码相同;负数反码转原码:除了符号位不变,其他位上0变1、1变0,原码就可以在控制台显示了

    &:位于运算,x&y,60&13

    同为1,结果为1,否则结果为0

    60&13
    60的原码:00000000 00111100
    60的反码:00000000 00111100
    60的补码:00000000 00111100
    13的原码:00000000 00001101
    13的反码:00000000 00001101
    13的补码:00000000 00001101
    
    60的补码&13的补码:
    00000000 00111100&
    00000000 00001101
    60&13的补码:00000000 00001100
    60&13的反码:00000000 00001100
    60&13的原码:00000000 00001100--->12
    
    

    |:位或运算

    同为0,结果为0,否则结果为1

    60|13
    60的原码:00000000 00111100
    60的反码:00000000 00111100
    60的补码:00000000 00111100
    13的原码:00000000 00001101
    13的反码:00000000 00001101
    13的补码:00000000 00001101
    
    60的补码|13的补码:
    00000000 00111100|
    00000000 00001101
    60|13的补码:00000000 00111101
    60|13的反码:00000000 00111101
    60|13的原码:00000000 00111101--->61
    

    ^:异或运算

    相同为0,不同为1

    60^13
    60的原码:00000000 00111100
    60的反码:00000000 00111100
    60的补码:00000000 00111100
    13的原码:00000000 00001101
    13的反码:00000000 00001101
    13的补码:00000000 00001101
    
    60的补码^13的补码:
    00000000 00111100^
    00000000 00001101
    60^13的补码:00000000 00110001
    60^13的反码:00000000 00110001
    60^13的原码:00000000 00110001--->49
    

    ~:取反

    把补码数据按位取反,0变1,1变0

    60~13
    60的原码:00000000 00111100
    60的反码:00000000 00111100
    60的补码:00000000 00111100
    13的原码:00000000 00001101
    13的反码:00000000 00001101
    13的补码:00000000 00001101
    
    ~60的补码:11111111 11000011
    ~60的反码:11111111 11000010
    ~60的原码:10000000 00111101--->-61
    

    右移运算:>>

    ​ 把二进制数据整体向右侧移动指定的位数,右侧的数据直接删除,左侧补0

    ​ 往右侧移动一位,相当于除以2

    ​ 8/2=4

    ​ 8>>1

    左移运算:<<

    ​ 2<<3是2*8的最高效算法

    ​ 往左侧移动一位相当于乘以2,移动2位相当于乘以4

  6. 成员运算符

    一般用于序列数据中,检查元素是否是序列的成员

    in,not in

  7. 身份运算符

    判断两个变量的地址是否相同。

    is,is not

    相当于判断两个变量的**id()**值是否相同

    baobao = "blue"
    wang = "blue1"
    blue = wang
    print(baobao is wang)
    print(baobao is not wang)
    print(id(baobao))
    print(id(wang))
    print(id(allen))
    

八、控制语句

1、if语句

if是一种分支、选择语句,需要对指定的条件表达式的值确定具体选择哪一个分支。

python的分支语句中没有switch–case语句。

方法1:只有一个选择

if(条件表达式)if语句代码块
    ..
    ...
#if语句


choice=input("我选择了学科:")
if(choice=='软件测试'):
    print('学好软件测试,登上人生巅峰!')

print('if语句结束!')

方法2:有一个条件,但是有不同的选择

if(条件表达式):
	if语句代码块
    ...
    ...
elseelse语句的代码块
    ....

方法3:多条件选择

if(条件表达式1):
	if语句代码块1
elif(条件表达式2):
	if语句代码块2
elif(条件表达式3):
	if语句代码块3
elseelse语句代码块

方法4:if语句嵌套(了解)

if(条件表达式1):
	if代码块1
    if(条件表达式2):
    	if代码块
    elseelse代码块
elseelse代码块
    if(条件表达式3):
    	if代码块
    elseelse代码块

2、for循环语句

循环语句代码块是可以循环运行的,专门的条件来限制循环的次数。

可以使用序列作为循环次数控制的结构

for循环中可以跟序列或者字典、range()方法

for循环的语法结构:

for 变量 in 序列类型数据:
	循环代码块

for循环语句的作用:

  • 从字符串、列表、元组、字典中遍历取出元素
  • 利用序列的元素个数,来控制循环次数
  • range(start,end,step):效率比序列和字典要高

3、while循环

基本语法格式:

条件表达式为True,则执行代码块语句

条件表达式为False,则退出while循环语句

while(条件表达式):
    代码块(要有调整条件表达式值的雨具)
    ...
else:
    else代码块
# 当条件表达式为False的时候才能执行这一句    
print("结束while循环到此处了")

4、其他控制语句

break:跳出(结束)for、while循环,遇到break则直接结束后续所有循环

continue:继续,结束当次循环,继续进入下一次循环

九、函数与方法

一、函数的定义

  • 函数的作用:封装具有特定功能的代码块,提高代码的复用性
  • 使用关键字def来定义函数,后面跟函数名标识符()
  • Python中的返回值一般是通过return关键字带回的,如果不写返回None,可以返回一个值,也可以同时返回多个值,结束方法(后续的代码不在执行)
  • 函数是设计出来的,在拿到需求之后,动手写函数之前,要分析两个内容
    • 要不要参数?要几个参数?
    • 要不要返回值?返回什么?

不带参数:def 函数名():

​ 函数代码块

​ return 返回值

带参数:def 函数名(变量1,变量2….):

​ 函数代码块

​ return 返回值

二、方法的调用

方法不调用不执行,只有调用了才能执行其中的功能。

  1. 有返回值方法的调用

    三种调用方法的格式:方法名(参数列表)

    • 直接调用:直接写方法名(),没太大作用
    • 赋值调用:比较灵活,方法的返回值可以参与后续的运算
    • 输出调用:一般是返回值可能只会用到一次的情况
    def sum(num1, num2):
        c = num1 + num2
        return c
    print(sum(1, 2))
    # 赋值调用,把方法的返回值赋值到一个变量中,可以参与后续的运算了
    s = sum(12, 21)
    print(s + 1)
    
  2. 无返回值方法的调用

    建议直接调用方法即可:方法名(参数列表)

    # 控制台上打印99乘法表功能,设计成一个方法
    def ninenine():
        # 实现99乘法表的输出功能
        for row in range(1, 10):
            for col in range(1, row + 1):
                print(f'{row}*{col}={row * col}', end="  ")
            print()
    
    
    # 不建议使用输出调用\赋值调用
    # print(ninenine())
    # 直接调用即可
    ninenine()
    

作业1:定义一个方法,实现百钱买百鸡的案例
作业2:定义一个方法,输出n*n乘法表

# 作业1
def money():
    for x in range(0,101):
        for y in range(0,101):
            for z in range(0,101):
                if(x+y+z==100 and 5*x+3*y+z/3==100):
                    print(f'公鸡{x}只,母鸡{y}只,小鸡{z}只')
money()

# 作业1
def kun():
    count = 0
    for x in range(21):
        for y in range(34):
            z=100-x-y
            if(x*5+y*3+z/3==100):
                count+=1
                # print(f'公鸡{x}只,母鸡{y}只,小鸡{z}只')
    # print(f'共有{count}种购买方案')
    return count
print(kun())

# 作业2
n=int(input('输入一个数字:'))
def ninenine(n):
    for row in range(1, n+1):
        for col in range(1, row+1):
            print(f'{row}*{col}={row * col}', end="  ")
        print()
    return '-'*30
print(ninenine(n))

三、函数的参数类型

常见的参数类型:

  • 位置参数:按照在括号中顺序传参
  • 关键字参数:按照参数名=值的方式传参
  • 默认值传参:参数是有默认值的,可以不用给实参,自带值
  • 不定长参数:可以接受多个参数
  1. 位置参数

    位置参数使用的特点:

    • 必须按照函数定义时候的参数个数和参数顺序传参。
    • 多了、少了都会报错。
    • 顺序反了,虽然不报错,但是可能结果是不对的
  2. 关键字参数

    把形参名作为一个关键字在使用,实现指定名字传参

    • 关键字参数后面不允许出现位置参数(直接语法就是错误的)
    • 位置传参后面可以跟关键字参数,但是要注意别冲突
    • 建议按照每个关键字分别传参。解决了传参的顺序问题
      • getinfo(name=‘blue’,age=28)
      • getinfo(age=28,name=‘blue’)
  3. 默认值参数

    在定义函数的时候可以直接给形式参数赋值(guoji=‘中国’),在后续调用的时候:

    如果指定guoji参数,就以指定的实参为准

    如果不指定guoji参数,就以默认值为准

    # 定义一个方法,输出学生信息
    def printInfo(name,age,gender,guoji='中国'):
        print('学生的姓名为%s,年龄为%s,性别为%s,国籍为%s!!!'%(name,age,gender,guoji))
    printInfo('blue','28','男','china')
    printInfo('blue','28','男')
    
    # 这个是前面见过的典型的默认值参数的使用
    print('',end='\n')
    
  4. 不定长参数

    在定义函数的时候,不确定调用函数的时候会传几个实际参数进来,这种场景下可以使用不定长参数

    • *args

      args是将传入的多个实参先保存在一个元组中,如果想使用再从元组中遍历出来。

    # *args是将传入的多个实参先保存在一个元组中,如果想使用再从元组中遍历出来。
    # 定义一个方法,args是一个元组类型
    # 先存数据到元组中
    # 再取出来使用
    def sum(*args):
        # print(type(args))
        # 
        # print(args)
        aa=0
        for i in args:
            aa+=i
        return aa
    
    # 传一个值
    print(sum(12, 12, 2342, 3423, 9))
    
    • **kwargs

      kwargs是将传入的aa=bb格式的实参,保存在kwargs字典中,如果要使用就需要从字典中把数据遍历出来。

    # **kwargs:是以键值对的形式接收实参,然后存储在一个字典中
    def ssum(**kwargs):
        # print(type(kwargs))
        # 
        # print(kwargs)
        bb=0
        for ii in kwargs.values():
            bb+=ii
        return bb
    
    print(ssum(a=12, b=12))
    

十、面向对象

1、几个概念

  1. 面向对象和面向过程
    • 面向过程:一般是通过方法来封装固定功能代码块,C语言是一个面向过程的语言,不断写方法,方法之间相互调用实现某个复杂的功能
    • 面向对象:是对面向过程的再一次封装,包括方法和属性。不断地写类,通过类创建不同的对象,通过对象调用不同的方法
    • 面向对象的开发中把对象作为最基本的单位面向过程的最基本单位是方法
    • 面向对象中需要包含数据(属性)和处理数据的方法(行为)
  2. 类和对象
    • 类:是抽象的概念,是从大量的具体事务中抽象出来的,应该包括方法和变量
    • 对象:是具体的概念,是由类实例化出来的,都有自己特定的属性和行为。
    • 实例化:通过类创建对象的过程(抽象到具体的过程)
  3. 方法和变量
    • 方法和变量其实是对具体的对象的行为和属性的抽象
    • 实例方法:其实就是类中的方法
    • 实例变量:类中方法中定义的变量、而且以self.开头的变量就是实例变量,是每个对象独有的属性值
    • 类变量:类中方法外的变量,属于类的,类的所有实例(对象)都有这个属性
    • 局部变量:类中方法中定义的变量,作用域只能是在该方法中,出来方法代码块就被注销

2、类的创建

  1. 类的格式

    • class:是创建类的关键字

    • class 类名():

      ​ 类体

    • 类名:是一个标识符,便于调用、引用

    • 类体:

      • 方法:和前面讲过的方法差别不大,第一个参数必须有,而且必须是self
      • 变量(实例变量、类变量、局部变量)
  2. 创建一个类

    • 创建类从具体的事务、对象到抽象的类的过程。
    • 对班级内十位同学进行分析,共同的属性和行为:
      • 属性:年龄、姓名、国籍、性别、学号、身高、体重……
      • 行为:吃饭、睡觉、学习、玩游戏、看视频、唱歌…….
    • 将属性和行为定义为类中的变量和方法:
      • 实例变量:年龄、姓名、性别、学号、身高、体重……
      • 类变量:国籍
      • 局部变量:学习时间长度,是学习这个行为中的一个属性
      • 实例方法:吃饭、睡觉、学习、玩游戏、看视频、唱歌…….
  3. 对象的创建

    • 格式1:对象名=类名()
    • 格式1:对象名=类名(参数1,参数2……)
  4. 调用方法和变量

    1. 调类变量
      • 类名.类变量名=‘值’—>当前对象及使用该类定义类,其他对象的该值都发生了改变
      • 对象名.类变量名—>其实是该对象创建了一个自己的和类变量同名的实例变量,只改变的是自己的值,不影响其他对象的类变量值
    2. 调成员变量
      • 对象名.实例变量名
    3. 方法的调用
      • 对象名.方法名()
      • 对象名.方法名(参数1,参数2….)
  5. 构造方法

    Python中构造方法名_ _init _ _(self),是类中内置的一个方法,在创建对象的时候自动调用。可以无参,也可以有参数,通过参数实现对成员变量的初始化。

self:哪一个对象调用实例变量、方法,那self指的就是那个对象

  • print(xiaowang.name)
  • print(xiaozhang.name)

3、面向对象三大特性

三大特性:封装、继承、多态

  1. 封装

    什么时候会用到封装?在类中某些变量、方法不希望通过对象直接访问到。

    怎么实现封装?

    • 把不想别人看的东西隐藏起来:只需要在变量名或者方法名的前面加上_ _

      定义私有的属性age:self._ _age=20

      私有属性只能在类中的方法间调用,不能通过对象调用

    • 并且要提供公共访问的方法实现对变量的修改和查看

    封装的两个类型:

    • 私有化变量:self._ _age=20
    • 私有化方法:def _ _play()

  1. 继承

    父类:也叫基类、超类,把大量的类的共同/相同的属性和行为,提取出来,封装在另一个类中。这个类就是父类。

    子类:也叫派生类,上面所提的大量的类

    这种子类和父类之间就存在着一种继承的关系。

    重写:子类重新改写父类的同名方法,子类对象调用方法使用的是重写后的子类的。

    格式:

    class 子类名(父类名):

    ​ 子类的特有的属性和行为

    • Python中继承的特点

      • 支持单继承
      • 支持多继承
      • 支持多层继承
      # 单继承
      class yeye():
          piqi='脾气大'
          def play(self):
              print('下棋')
      
      class mu():
          yanzhi='温柔漂亮'
          def hobby(self):
              print('爱好逛街')
      
      class fu(yeye):
          zhangxiang='英俊潇洒'
          def play(self):
              print('父亲喜欢打篮球')
      
      class zi(fu,mu):
          pass
      
      z = zi()
      print(z.zhangxiang)
      z.play()
      print(z.piqi)
      z.hobby()
      print(z.yanzhi)
      
  2. 多态

    Python中的多态是鸭子多态。

    Python中的多态不要求有继承关系。

    多态是指一个对象在不同的时候展现不同的形态:

    ​ 一只小花猫对象是只猫

    ​ 一只小花猫对象是只动物

十一、模块

1、模块的概念

Python中以.py结尾的文件称之为模块。

  • 便于管理代码
  • 把相同、类似功能逻辑的代码封装在一个模块中,便于使用
  • 模块中可以封装方法、类、变量及可执行代码
  1. 创建模块
# 定义一个方法
def printInfo():
    print('热爱生活')

class phone():
    def call(self,phoneNo):
        print(f'打电话给{phoneNo}')

# 调试代码放在这
mate60 = phone()
mate60.call('15712345678')


# 整体作用:起到调试作用,只限制在本模块中执行
# __name__:是模块中内置的一个变量,在本模块中运行的值是__main__
if __name__=='__main__':
    # 调试代码都要放在这个位置
    print(__name__)
    printInfo()
    print('在当前模块中运行代码!!')

else:
    print(__name__)
    print('在其他模块中运行代码!!')
  1. 使用模块

    写了模块一般不是在本模块中使用的,也不是所有的功能都定义在一个模块中的,只有通过模块之间的相互调用才能形成一个复杂的程序

    使用两个关键字from、import

    通过导入模块,就可以使用模块中定义的功能了(方法和类了)

    包:是包括了_ _init _ _.py模块的一个文件夹,使用它带包导入模块:包名.模块名

    • import xx模块

    • from xx模块 import xx方法,xx类

  2. 理解if_ _name _ _==“ _ _main _ _”语法

    就是一个普通的if语句,重点是理解 _ _name _ _变量的值的变化。

    • _ _name _ _:在当前模块下运行等于 _ _main _ _

    • _ _name _ _:在导入到其他模块下运行等于模块名,判断条件就是False

  3. 导模块的原理

    Python在遇到import、from import的时候会做几件事:

    • 检查sys.path返回的列表有哪些目录,找到要导入的模块
      • 如果sys.path的列表中有一个目录,则该目录可以直接导入
      • 如果sys.path的列表中没有指定目录,则该目录下文件不能直接导入
      • 把指定的目录追加到sys.path中,就可以导了
    • 将模块解释成字节码文件(pyc)
    • 直接运行字节码文件了
    • 注意:后续再导入相同模块的时候就不需要前两步骤了,直接从内存加载字节码文件

2、常见的导入案例

软件测试进阶篇----Python_第4张图片

  1. 同一目录下的导入

    直接导模块即可?sys.path中有该目录

    test1中的代码

    class student():
        def add(self,a,b):
            return a+b
    
    if __name__=='__main__':
        s=student()
        print(s.add(12,23))
    

    test2中的代码

    from education.module1.test1 import student
    
    def func():
        print('我是func方法')
        s = student()
        print(s.add(12, 234))
    
    if __name__=='__main__':
        func()
    
  2. 同级别目录之间相互导入模块

    test3中的代码

    # 将module目录加载到sys.path列表,就可以直接导入其他的模块了
    # 不能给绝对值的路径
    # os模块,提供了大量的对文件夹目录处理的方法
    import os
    import sys
    
    # os.path.dirname():获取某个目录或者文件所在的目录,也是相对的值
    # os.path.abspath():将相对路径转为绝对值的表示法
    # __file__:当前文件的名字
    # D:\PycharmProjects\PythonDemo01\education\module2
    path1=os.path.abspath(os.path.dirname(__file__))
    path2=os.path.abspath(os.path.dirname(path1))+r'\module1'
    print(path1)
    print(path2)
    sys.path.append(path2)
    
    from test1 import student
    from test2 import func
    
    
    s=student()
    print(s.add(12,4))
    print('-'*30)
    func()
    

3、异常和异常处理

异常:在程序运行过程中,出现错误、异常会导致程序的终止,在控制台上显示异常信息

异常是Python语言中针对某些特定的错误,设计的一个专门的类,出现了某个错误,控制台就会抛出哪一个类信息。

三个常见异常处理的关键字

  • try

  • except

  • finally

    # a=1/0
    # try检查代码块中的代码是否会抛出异常
    try:
        ac=1/0
        a=[1,2,3,4]
        print(a[3])
        print('ssssssss')
    # 抓异常,如果抓到一个异常,则执行对应的代码块
    # 体现多态的特点
    # except IndexError as e:
    except Exception as e:
        # 异常处理
        print(e)
    finally:
        print('不管抛不抛异常,最终都要执行finally语句')
    

十二、IO处理

一、Python中的IO

Python中数据的输入和输出操作(i:input;o:output)

  1. input()输入方法

    input():监听键盘的输入,遇到回车键,则将数据返回到代码中来,返回的是字符串。

    结合一些工厂类方法进行数据类型的转换:int(input())、float(input()).

  2. print()输出方法

    print():输出数据到控制台,可以格式化输出

    • priint(“你好,%s”%name)

      • %s

      • %d

      • %f

      • %.4f

    • print(“你好,{}”.format(name))

    • print(“你好,{1},{2}”.format(name,age))

    • print(f“你好,{name}”)

  3. pprint()

    美化输出的方法。

    import pprint
    a = {"a":1,"b":2,"c":3,"d":4}
    b=['1','sss',1,2,3,4,5,6]
    print(a)
    
    pprint.pprint(b,indent=2)
    

二、文件IO的用法

对文件(文本文件、csv文件、json文件、excel文件、yaml文件等读写操作)

  1. 基本操作流程

    • 通过open()打开文件并创建文件对象
    • 将文件对象加载到内存(缓存区)
    • 对缓存区数据的操作
      • 读写
      • 对二进制文件进行读写
    • 将缓存区数据重新写回到磁盘
  2. 文本文件的读写

    创建文件对象的格式:f=open(文件的全路径,操作模式,文件的编码集合)

    • 文件的全路径:建议字符串的前面加一个R/r(取消转义)
    • 读写模式
      • r:只读模式
      • w:只写模式,覆盖写入
      • a:追加模式,在文件末尾处追加数据
      • r+\w+\a+都是读写模式,既能写也能读
      • b:二进制的读写模式(binary)
  3. 数据的读取操作

    • read(size):按照指定的字节读取数据
    • readline():读取行
    • readlines():读取多行
    import time
    
    # 打开并且创建对象
    f=open(r'd:\blue.txt','r',encoding='utf-8')
    # 读取数据
    # print(f.read(15))
    # print(f.read(70))
    
    # 按照行进行读取:不加参数就是读取一行、加上参数后按照字节长度读取
    # print(f.readline(5))
    
    # 一次性读取多行,返回是多行数据为元素的列表,包括每行结尾处的换行符
    # ['hello world1!\n', 'hello world2!\n', 'hello world3!\n', 'hello world4!']
    # print(f.readlines())
    
    
    # 获取文件数据的所有行数据的列表
    # for data in f.readlines():
    #     print(data)
    #     # 每隔开1s读取一行数据
    #     time.sleep(1)
    
    for i in range(10):
        print(f.readline())
        # 每隔开1s读取一行数据
        time.sleep(2)
    
    
    # 关闭文件对象
    f.close()
    
  4. 写入数据到文件-w

    如果文件不存在,创建文件并写入

    • write():写入一个指定的字符串

    • writelines():写入多行数据,参数格式是列表

    # 写入数据
    f=open(r'd:\blue.txt','w',encoding='utf-8')
    # 写入一行
    # f.write('你好,中国111')
    data=['hello world1!\n', 'hello world2!\n', 'hello world3!\n', 'hello world4!']
    f.writelines(data)
    
    # 关闭文件对象
    f.close()
    
  5. 推荐写法(必须掌握)

    with open()语法,这种语法不用去担心文件是否关闭的问题

    # f参数就是打开的文件对象
    with open(r'd:\blue.txt','r',encoding='utf-8')as f:
        print(f.read())
    
    
    with open(r'd:\red.txt','a',encoding='utf-8')as f:
        f.writelines(['你好\n','大家好!\n'])
    

三、csv文件的读写

csv文件是一种非常常见的用于数据存储的文件,按照‘,’分隔的多列数据

  1. 创建csv文件

    1. excel设计数据,另存为csv文件
    2. 直接创建文本文件,后缀名可以改为.csv,用超级记事本工具notepad++直接写
  2. 读取文件内容

    需要用到csv的模块,是python自带的,直接导入就可以使用了

  3. 写入到数据文件(掌握)

    # 先导包
    import csv
    
    # 打开文件
    with open(r'd:\aa.csv', 'r', encoding='utf-8') as f:
        # reader返回csv中的数据集合
        data = csv.reader(f)
        #<_csv.reader object at 0x000001C286C27BE0>
        # print(data)
    
        # 遍历读取文件后的数据对象
        for d in data:
            print(d[2])
            
            
    with open(r'd:\aa.csv', 'a', encoding='utf-8',newline='') as f:
        # 追加写入数据
        # 创建一个写入对象
        duixiangWrite = csv.writer(f,dialect='excel')
    
        # writerow():要求的参数是列表格式['xiaohei',23,'男','学生']
        # writerows()
    
        # duixiangWrite.writerow(['xiaohei',23,'男','学生'])
        name = [['xiaohei',23,'男','学生'],['xiaohei2',23,'男','学生'],['xiaohei3',23,'男','学生']]
        duixiangWrite.writerows(name)
    

四、json类型文件的读写(掌握)

json文件是一种可读性非常好的数据结构,具体数据都是以键值对的形式给出的。

json文件是一种不依赖于任何语言的一种数据结构,但是又能被任意语言处理。可以用于不同系统/语言之间的数据传递

json文件的数据组成:[]、{}、“”、:

使用json文件来存储一个班级的所有学员的基本信息:

[
    {
        "name":"张三",
        "age":28,
        "gender":"男"
    },
    {
        "name":"李四",
        "age":20,
        "gender":"男"
    },
    {
        "name":"王五",
        "age":38,
        "gender":"女"
    }
]


//另外一种写法
{
    "teacher":"blue老师"
    "data":[
                {
                    "name":"张三",
                    "age":28,
                    "gender":"男"
                },
                {
                    "name":"李四",
                    "age":20,
                    "gender":"男"
                },
                {
                    "name":"王五",
                    "age":38,
                    "gender":"女"
                }
    	]
}
  1. 创建json文件

    注意保存为UTF-8编码格式

  2. 在Python中进行读取

    使用json中的load()方法实现数据的读取

    # json是Python自带的模块,不需要安装
    import json
    import pprint
    
    # 打开文件
    with open(r'd:\blue.json','r',encoding='utf-8') as f:
        # 读取json数据有两个方法:load()\loads()
        data=json.load(f)
        print(data)
        print(type(data))
        for d in data:
            pprint.pprint(d)
    
  3. 写数据到json文件中

    使用json中的dump()方法。

    # 创建json文件并打开
    with open(r'd:\blue2.json', 'w', encoding='utf-8', newline='\r\n') as f:
        # 定义要写入的数据
        a = [
    
            {
                "name": "张三",
                "age": 28,
                "gender": "男"
            },
            {
                "name": "李四",
                "age": 20,
                "gender": "男"
            },
            {
                "name": "王五",
                "age": 38,
                "gender": "女"
            }
    
        ]
    
        # 将上面的列表写入到json文件中
        # indent:缩进,相当于tab(4个空格)
        json.dump(a,f,indent=1,ensure_ascii=False)
    

五、excel文件的读操作(了解)

使用xlrd模块对excel文件进行读操作,如果excel文件格式是xlsx文件的话,xlrd建议使用1.2.0版本。

安装时:pip install xlrd==1.2.0

  1. 创建xlsx文件

  2. 读取数据

    import xlrd
    
    # 打开文件
    f = xlrd.open_workbook(r'd:\aa.xlsx')
    #
    # print(f)
    
    # 获取excel工作簿中的指定sheet页对象
    # sheet=f.sheet_by_name('Sheet1')
    # sheet=f.sheet_by_index(0)
    
    # 获取第一个sheet列表
    sheet=f.sheets()[0]
    # 
    # print(sheet)
    
    # 获取数据的行数
    row = sheet.nrows
    col=sheet.ncols
    print(col)
    print(row)
    
    # 获取一行数据
    # print(sheet.row_values(0))
    # 获取所有行数据
    # for i in range(row):
    #     for j in range(col):
    #         print(sheet.row_values(i)[j])
    
    
    for i in range(row):
         # for j in range(col):
            print(sheet.cell_value(i,0))
    

十三、单元测试框架

一、单元测试案例

#作为单元测试的测试对象
class mathdemo():
    #实现加法运算
    def add(self,a,b):
        return a+b

    #实现减法运算
    def minus(self,a,b):
        return a-b
    #实现乘法运算
    def multi(self,a,b):
        return a*b
    #实现除法运算
    def devide(self,a,b):
        return a/b

单元测试:针对代码中最小单位进行的测试,验证其功能是否正确,覆盖率的测试类型,属于白盒测试范畴

在Python中最小的单元是类,我们要验证类中的方法的正确性

进行单元测试参考的依据是什么?详细设计文档,代码是测试对象

  • 做单元测试一定要引入单元测试的框架:(好处)
    • 提供了更好的、方便管理大量单元用例的方式
    • 有直接用于判断用例对错的方法
    • 还可以提供输出可视化的报告
  • Python中的单元测试框架:
    • unittest
    • pytest

二、unittest框架

  1. 框架的组成(从下往上)

    • TestCase:测试用例层,耗时最长最多的一层
    • TestSuite:测试集合层,可以将不同类型的用例放到同一个集合中统一运行
    • TestLoader:测试加载层,提供了大量的方法,将测试用例加载到测试集合中
    • TestRunner:测试运行器层,运行测试集合的
    • TestResult:测试结果层
  2. TestCase层

    测试用例层,一条测试用例包括三个方法组成:

    • setUp(self):只能有一个该方法,在每一个测试用例方法运行前执行,起到初始化的作用
    • test_xxx(self):测试用例方法,放的是用例步骤,可以有多个
    • tearDown(self):只能有一个该方法,在每一个测试用例方法运行后执行,起到资源释放的作用
    # 单元测试用例的模块:不需要安装,直接导入即可
    import unittest
    from danyuan.calcDemo import mathdemo
    
    
    # 创建一个单元测试类(一个普通类,继承unittest的测试类TestCase)
    class testCalc(unittest.TestCase):
        # 重写TestCase中的两个方法
        def setUp(self):
            print('我是setUp方法')
            self.md = mathdemo()
    
    
        def tearDown(self):
            print('我是tearDown方法')
            self.md = None
    
        # 单元测试用例方法1
        def test_add_01(self):
            '''加法的一条测试用例'''
            print('我是add_01方法')
            sj = self.md.add(1, 2)
            yq = 3
            # 断言:就是判断预期结果和实际结果是否一致
            # unittest框架中提供了很多断言的方法
            # 判断是否相等的方法
            # assert:断言
            self.assertEqual(yq, sj, '预期结果和实际结果不一致!!!')
    
        # 单元测试用例方法2
        def test_add_02(self):
            '''负数参与加法的一个测试用例'''
            print('我是add_02方法')
            sj = self.md.add(-1, 2)
            yq = 1
            self.assertEqual(yq, sj, '预期结果和实际结果不一致!!!')
    
        # 单元测试用例方法3
        def test_jian_03(self):
            '''乘法运算'''
            print('我是add_03方法')
            sj = self.md.minus(5, 4)
            yq = 1
            self.assertEqual(yq, sj, '预期结果和实际结果不一致!!!')
    
    
    if __name__ == '__main__':
        unittest.main()
    

    常见的断言方法

    • self.assertEqual()
    • self.assertIn(元素,序列)

    常见的装饰器:

    • @unittest.skip()
    • @unittest.expectedFailure
  3. TestSuite测试集合层

    discover()返回的就是一个测试集合对象。

    # 测试集合对象:TestSuite
    # discover:就是将指定目录下的py模块中的单元测试用例加载并返回到测试集合对象
    suite = unittest.defaultTestLoader.discover(r'./',pattern='test*.py')
    # print(suite)
    
  4. 运行器层

    采用BeautifulReport模块来运行测试集合。

    pip install BeautifulReport

    # 运行集合,生成可视化的报告
    # 安装第三方的模块:BeautifulReport
    # 创建运行器,和测试集合关联在一起
    runner = BeautifulReport(suite)
    runner.report("单元测试报告",'result',r'./')
    

你可能感兴趣的:(软件测试,1024程序员节,python,unit,testing,单元测试)