2022年6月28日面试题

python基础

一. python怎么连接数据库

答案:

  1. 安装pymysql:pip install pymysql
  2. 连接数据库,创建游标
# 连接数据库:cursorclass = pymysql.cursors.DictCursor 指定返回数据为字典格式
conn = pymysql.Connect(host, port, db, user, passwd,cursorclass = pymysql.cursors.DictCursor)

# 创建游标
cursor = conn.cursor() 
  1. 准备好增删改查的sql语句,执行sql语句

# 使用格式化的方法构造sql语句
# 列表和元组 %s。字典%(键名)s
# eg1:列表
data = [14, 'xiaojian']
insert_sql = "insert into test1(id, name) values(%s, %s)"

# eg2:字典
data = {'id': 14, 'name': 'xiaojian'}
insert_sql = "insert into test1(id, name) values(%(id)s, %(name)s)"


# 执行execute方法
cursor.execute(insert_sql, data)

# 提交
conn.commit()

# 回滚
conn.rollback()

# 使用格式化的方法构造sql语句
data = 1
delete_sql = "delete from items where id = %s"

# 执行execute方法
cursor.execute(delete_sql, data)

# 提交
conn.commit()

# 回滚
conn.rollback()

# 使用格式化的方法构造sql语句
data = ("beck", 1)
update_sql = "update userinfo set name = %s where id  = %s"

# 执行execute方法
cursor.execute(update_sql, data)

# 提交
conn.commit()

# 回滚
conn.rollback()

# 构造sql语句
query_sql = "select * from userinfo"

# 执行execute方法
cursor.execute(query_sql, data)

# 获取一条数据
data_one = cursor.fetchone()

# 获取所有数据
data_all = cursor.fetchall()

#查询是没有提交和回滚的方法的
  1. 对于查询到的数据做处理
  2. 关闭游标
cursor.close()
  1. 关闭连接
conn.close()

二. python是怎么获取当前系统时间

方法一:使用datetime模块

from datetime import datetime
datetime.now()

运行结果:datetime.datetime(2022, 6, 28, 21, 32, 14, 702706)

# 格式化输出
datetime.now().strftime('%Y-%m-%d %H:%M:%S')

运行结果:'2022-06-28 21:34:26'

方法二:使用time模块

import time
time.localtime(time.time())

运行结果:time.struct_time(tm_year=2022, tm_mon=6, tm_mday=28, tm_hour=21, tm_min=37, tm_sec=49, tm_wday=1, tm_yday=179, tm_isdst=0)

# 格式化输出
time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))

运行结果:'2022-06-28 21:44:32'

三. python中的数据类型有哪一些

总共有六大类:
Numbers(数字)
String(字符串)
List(列表)
Tuple(元组)
Dictionary(字典)
Set(集合)

按照可变不可变分类有两种:
不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组)
可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)

数字类型细分
int(长整型)
float(浮点型)
complex(复数)
bool(布尔型)

四. python中怎么设置定时任务

  1. 安装轻量级的定时任务调度的库: pip install schedule
  2. 代码
import schedule
import time
 
def run():
    print("I'm testing...")
 
schedule.every(10).minutes.do(run)
schedule.every().hour.do(run)
schedule.every().day.at("10:30").do(run)
schedule.every(5).to(10).days.do(run)
schedule.every().monday.do(run)
schedule.every().wednesday.at("13:15").do(run)
 
while True:
    schedule.run_pending()
    time.sleep(1)

schedule本身是个定时器。在while True死循环中,schedule.run_pending()是保持schedule一直运行,去查询上面那一堆的任务,在任务中,就可以设置不同的时间去运行

五. python中元组和列表的区别

相同点

  • 都是序列
  • 可存储任何数据类型
  • 可通过索引访问
  • 都支持切片
  • 可以随意嵌套

不同点

  • 写法上不同,列表: [], 元组()
  • 是否可变。列表上可变的,可随意的增加、删除、修改元素,元组上不可变的,不可增加、删除、修改元素
  • 是否可作为字典的key。由于列表是可变的,不能作为字典的key,而元组是不可变的,可以作为字典的key
  • 大小不同。存储同样的元素,与列表相比,元组内存更小,速度更快
>>> my_list = ['http://www.baidu.com', 'http://www.google.cn']
>>> my_tuple = ('http://www.baidu.com', 'http://www.google.cn')
>>> my_list.__sizeof__()
56
>>> my_tuple.__sizeof__()
40

六. json和str类型转换

import json

json.loads().  #str转python dict对象(json)
json.dumps(). #python dict(json)对象转str

七. Excel文件操作

  1. 安装openpyxl库:pip install openpyxl
  2. 代码:
# 引入库
from openpyxl import load_workbook

# 加载一个excel文件,进入到工作簿
wb = load_workbook("testdata.xlsx")

# 获取指定的表单
sh = wb["Sheet1"]

# 获取表单中数据
name = sh.cell(row=2, column=1).value
print(name)

# 修改表单中的数据--修改数据,注意在写操作时,必须先关闭excel文件
sh.cell(row=2, column=3).value = 18

# 保存修改数据的操作--保存数据
wb.save("testdata.xlsx")

# 获取总行数、总列数
print(sh.max_row)
print(sh.max_column)
print(sh.cell(row=3, column=3).value)
sh.cell(row=3, column=3).value = 25
print(sh.cell(row=3, column=3))

# 读取所有数据,按行读取
for index in range(1, sh.max_row + 1):
    print("行号: ", index)
    for sub_i in range(1, sh.max_column + 1):
        print("列号: ", sub_i, "内容: ", sh.cell(row=index, column=sub_i).value)


结果:
小翟
3
3
18
<Cell 'Sheet1'.C3>
行号:  1
列号:  1 内容:  name
列号:  2 内容:  sex
列号:  3 内容:  age
行号:  2
列号:  1 内容:  小翟
列号:  2 内容:  男
列号:  3 内容:  18
行号:  3
列号:  1 内容:  瑛子
列号:  2 内容:  女
列号:  3 内容:  25

八. 多线程、进程和协程

可以看这一篇:《Python的多线程、多进程及协程》

九. 如何提取json中的内容

  1. 正则表达式
  2. 使用json.loads() 转为python 字典,再通过key获得值
  3. jsonpath

接口用例和自动化

一. 淘宝中购买的接口测试,如何设计测试用例

二. 微信支付的接口测试,如何设计测试用例

所有的接口测试,都涉及到这样的原则:

  1. 业务功能测试:正常场景、异常场景
  2. 边界值分析测试:业务规则边界分析、输入输出参数边界值分析(覆盖必选、组合可选、参数有无、参数顺序个数类型、参数类型数值大小,数值范围、参数字符串长短、特殊字符等等)
  3. 参数组合测试
  4. 异常情况测试:幂等、并发、事务、分布式、环境异常、大数据量测试
  5. 性能测试:响应时间、吞吐量、并发数、服务器资源使用率(CPU、内存、IO、网络)
  6. 安全测试:敏感信息是否加密、SQL注入等

三. 框架如何设计?自动化的目的?达到的效果?框架分层的目的?用例的参数化?数据驱动的实现?

  1. 框架如何设计
    设计思想:数据和用例分离
    如何实现:数据存储在excel中,通过openpyxl读取数据,封装成一个字典列表的形式,列表中的每一个字典都对应着一条case,通过ddt.data进行拆包,将每个元素分别传给封装好的request方法去做请求,拿到响应之后,将结果提取出来和期望结果做断言,最后通过unittest的loader方法,来收集测试用例,生成html报告

  2. 自动化的目的:
    (1). 基于接口层面实现脱离手工的方式高效执行测试
    (2). 接口自动化目的是提升效率
    (3). 通过适当的验证来获得控制反馈,对系统变更有把握
    (4). 方便回归测试
    (5). 提高回归测试效率,保证质量
    (6). 控制住接口质量,终端问题可以少很多
    (7). 更早的发现问题
    (8). 缩短测试周期
    (9). 发现更底层的问题

  3. 达到的效果:
    (1). 灵活高效。灵活指的是可以通过编码的方式为接口自动化框架新增功能,高效指的是通过代码实现接口自动化,可以提高接口测试效率
    (2). 可复用性。通过数据和用例分离,配置和用例分离,实现了一次配置,运行多次,代码复用性高,接口变动时,只需要修改相关配置和数据就行
    (3). 可维护性。不懂代码的同学也能快速上手,维护测试数据,扩展测试用例
    (4). 可扩展性。如果要在自动化框架的基础上扩展测试平台,需要可扩展性比较强
    (5). 可追溯性。接口运行有相关的日志和报告,出现问题可以溯源
    (6). 持续集成。可以部署到jenkins上实现持续集成

  4. 框架分层的目的
    (1). 能够管理系统公共的数据,系统发生变化后方便切换
    (2). 能够实现接口层级的复用,提高接口自动化脚本的可维护性
    (3). 能够实现接口之间的关联,也就是需要结果提取器
    (4). 能够操作数据库处理数据(预制数据、清理垃圾数据)
    (5). 能够实现测试用例的前置后置步骤(类似 unittest 的 setup 和 teardown)
    (6). 各种灵活的预期结果比较器
    (7). 测试脚本和框架代码完全分离,懂接口测试但是不懂代码的人一天即可完全掌握,超低的学习使用成本
    (8). 支撑 http/https 协议的接口测试
    (9). 灵活的扩展能力(自定义函数和自定义比较器)

  5. 用例的参数化
    (1). 随机数:使用${}的形式,在公共目录common下定义了一些随机数的方法,如果请求数据中有出现这样的形式,会调用替换函数做替换
    (2). 关联接口:使用{{}}的形式,在公共目录common下的context.py中定义了一个公共类Context,在接口请求后,如果excel的用例中有response_extract字段,那么就分割这个字段对应的值,将=前的值作为Context的key、将=后的jsonpath表达式从响应结果里提取出来作为value,反射给Context类,在接口请求前,如果请数据里有{{}}的形式,会调用替换函数做替换

反射类:common/context.py

class Context:
    pass

随机数类:common/random_generate.py

import time

class RandomGenerate:

    def __init__(self):
        self.timestamp = str(round(time.time_ns()))


    #随机生成手机号
    def random_phone(self):
        random_phone = "131" + self.timestamp[-8:]
        return random_phone

变量替换:common/replace_variable.py

from common.random_generate import *
from common.context import *
import re


class ReplaceVariable:

    def replace_variable(params):
        if params.find("${") != -1:
            replace_string = eval("RandomGenerate().random_{0}()".format(re.sub("\d+", "", re.findall("\${(\\w+)}", params)[0])))
            params = re.sub("\${\\w+}", replace_string, params)
        elif params.find("{{") != -1:
            replace_string = eval("Context.{0}".format(re.findall("{{(\\w+)}}", params)[0]))
            params = re.sub("{{\\w+}}", replace_string, params)
        return params

测试类:test_cases/test_my_request.py

           #替换请求参数
            request_data = json.loads(ReplaceVariable.replace_variable(case_data["request_data"][i]))
            logging.info("请求数据: {0}".format(request_data))


          #响应数据反射
            response_extract = case_data["response_extract"][i]
            if response_extract:
                key, express = response_extract.split("=")
                setattr(Context, key, str(jsonpath(result, express)[0]))
  1. 数据驱动的实现
    类上面加装饰器:@ddt.ddt
    方法上面加装饰器:@ddt.data(*all_case_data)

Linux

一. linux中的查看日志的命令

cat default.log

查询实时日志

tail -f default.log. 查看实时日志
tail -500f default.log  查看最后的500行的实时日志
tail -1000f default.log. 查看最后的1000行的实时日志

二. linux中查看文件中过滤关键字的命令

tail -f  default.log | grep 关键字 

三. 如何查看linux中日志关键字上下几行的日志

后10行

tail -f default.log | grep 关键字 -A 10

前10行

tail -f default.log | grep 关键字 -B 10

其他

一. redis的作用?怎么测试?

  1. redis的作用
    redis交换数据快,所以在服务器中常用来存储一些需要频繁调取的数据,这样可以大大节省系统直接读取磁盘来获得数据的I/O开销,更重要的是可以极大提升速度。redis 的应用场景包括:缓存系统(“热点”数据:高频读、低频写)、计数器、消息队列系统、排行榜、社交网络和实时系统

简而言之,就是加快访问速度,减少服务器和数据库压力

  1. 如何测试redis

二. kafka的作用?怎么测试?

  1. kafka的作用
  • 流量削峰
  • 系统节藕
  • 异步处理
  • 冗余存储
  • 顺序性保障及回溯消费的功能
  1. 如何测试kafka
    参考这一篇:《kafka测试方案》
posted @ 2022-06-28 23:38  cnhkzyy  阅读(65)  评论(0编辑  收藏  举报