欢迎进行python技术交流,博主微信:jiaotengfei1016
1、自动化代码,用了什么设计模式?
主要是PO设计模式,其核心是分层思想,代码逻辑层分为Common、outputs、pageobject、reports、testcase、
2、selenium的原理?
python的第三库,当前是3.0版本,是操作浏览器的一个框架,包含了3个模块:IDE(录制和回放UI自动化)、grid(结合docker实现分布式自动化)、webdriver(操作浏览器的api)就像出租车司机等待我们给它发布指令去操作浏览器。
3、selenium熟悉的类
webdriver、
driver = webdriver.Chrome()
driver.get()
driver.maximize_windows()
driver.switch_to.windows()
driver.switch_to.frame()
driver.find_elenment_by_id().click()
driver.find_elenment_by_link_text().clear()
driver.find_elenment_by_xpath().sendkey()
driver.find_elenment_by_css().get_attribute()
driver.find_elenment_by_css().is_select()
driver.find_elenment_by_css().is_enabled()
driver.find_elenment_by_css().is_displayed()
driver.quit()
4、元素定位常用方式?
先顺便总结下常用定位的优先级:
(1)有id点id
(2)有文本值用文本值
xpath=“//a[text()=‘新闻’]” > 文本值是新闻的元素
xpath=”//a[contains(text(),‘新闻’)]” > 文本值包含新闻的元素
(3)link_text()
(4)CSS定位
(5)定位半天不出来??? >>> 右键xpath试下
(6)还不出来??? >>> js定位试下
5、说下CSS定位
单一属性定位("#id")(".s_class")(’[name=“wd”]’)
组合属性定位,模糊匹配很少用^=,~=,$=,
("[name1=‘wd’][name2=‘xd’]")、
(“input#kw”)(“input.s_class”)
6、如何处理弹框?
(1)div伪弹框,直接find_elenment就可以了
(2)win弹框(上传地图),标签是input类型,直接send_keys(),非input类型的挺麻烦
(3)alert、confirm、prompt弹框。driver.switch_to.alert(),driver.accept() driver.dismiss()
7、鼠标操作:
(1) def move_offset_click(self, canvas, *element):
return ActionChains(self.driver).move_to_element(canvas).move_by_offset(*element).release().click().perform()
8、下拉框如何处理?
(1)是select标签的,直接find_elenemt就可以
(2)有select标签的,Select类。注意:需要将用js改变值为display,才能定位到
def select_value(self, id, value):
return Select(self.findele(By.ID, id)).select_by_value(value)
9、class有空格,怎么定位?
不管是否空格,直接前面加点号就行:(“input.s_class.x_class”)
10、如何处理任意数据的位置实参、关键字实参?
# --*--coding=utf-8--*--
# 工作示例1:定义了查找元素的操作
def findele(self, *element): # 打包了2个变量By.Id,"xx",然后return解包。实现了自由传入多个变量。
return self.driver.find_element(*element)
# 工作示例2:定义了鼠标的单击操作
def click(self, *element):
return self.driver.findele(*element).click()
l = [1, 2, 3]
t = [4, 5, 6]
d = {"a": 7, "b": 8, "c": 9}
def f(str1, *args, **kwargs): # *args是为了接受任意数据的实参而设置的形参,**kwargs是为了打包任意数据的关键字实参而设置的形参
print(str1, args, kwargs)
if __name__ == '__main__':
# python优先匹配位置实参和关键字实参, *args会打包剩余的参数
f(1, 2, 3, "python", t="tfjiao")
# **kwargs将任意数量的“关键字实参”打包成了字典。
f("python", q="winning", **d)
#输出
C:\Python39\python.exe D:/se_frame/script/tfjiao_02.py
1 (2, 3, 'python') {'t': 'tfjiao'}
python () {'q': 'winning', 'a': 7, 'b': 8, 'c': 9}
11、关于列表深度拷贝和浅拷贝的区别?这玩意用的少呀
# --*--coding=utf-8--*--
import copy
lis = [12,39,10,5,11,66] #一维列表
lis.append(['I','like','python']) #添加 ['I','like','python']
li = copy.copy(lis) #浅拷贝
li2 = copy.deepcopy() #深拷贝
print(lis) #输出:[12,39,10,5,11,66,['I','like','python']] 变成一个二维列表
lis[6][2] = 'you'
lis[1]=0
print(lis) #[12,0,10,5,11,66,['I','like','you']] 原列表
print(li) #[12,39,10,5,11,66,['I','like','you']] 浅拷贝后得到的列表
print(li2) #[12, 39, 10, 5, 11, 66, ['I', 'like', 'python']] 深度拷贝后得到的列表
12、等长的两个列表合并到一个字典?
运用zip函数打包列表,并使用dict转换成字典。
keys = ["A", "B", "C"]
values = ["1", "2", "3"]
b = dict(zip(keys, values))
c = dict(zip(keys, [int(x) for x in values])) # 这里用了推导式,对values的值进行了化整
print(b)
#
C:\Python39\python.exe D:/se_frame/script/tfjiao_02.py
{'A': '1', 'B': '2', 'C': '3'}
13、合并两个列表并消除重复值?
利用列表函数自动去重的原理
li1 = ["a", "b", "c"]
li2 = ["a", "tfjiao", "tong"]
a = set(li1 + li2)
print(a)
#
C:\Python39\python.exe D:/se_frame/script/tfjiao_02.py
{'tong', 'b', 'a', 'c', 'tfjiao'}
14、已知一个列表,根据字典中的x ,由大到小排序这个列表?
sorted()排序列表:列表、用匿名函数提取列表中x值,从大到小排序
li = [{"x": 1, "y": 2}, {"x": 2, "y": 3}, {"x": 3, "y": 4}]
li1 = sorted(li, key=lambda i: i["x"], reverse=True)
print(li1)
15、
<html lang="en">
<head>
<meta charset="UTF-8">
<title>焦腾飞</title>
</head>
<body>
<h1>This is heading</h1>
<h2>This is heading</h2>
<h3>This is heading</h3>
<h4>This is heading</h4>
<h5>This is heading</h5>
<h6>This is heading</h6>
<p>这里是一个段落paragraph</p>
<p>
p代表一个段落
<br>br代表着换行符号;
</br>
<b>b</b>代表把文本加粗,<i>I</i>代表文本斜体,
<br>a代表超链接:<a href="https:www.baidu.com">百度搜索</a>
a代表超链接:<a href="https:www.baidu.com" target="_blank">百度搜索</a>
</br>
</p>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>张彤</title>
<style>
h1.title{text-align:center;}
#p1{text-align:center;color:red;}
p.class1{text-align:center;color:red;}
#p3{text-align:center;}
</style>
</head>
<body>
<h1 class="title">h1代表1级标题</h1>
<p id="p1">
第一、这里说的是基础_001
p代表一个段落
<br>br代表着换行符号;tr是table里面的换行
</br>
<b>b</b>代表把文本加粗,<i>I</i>代表文本斜体,
<br>a代表超链接:<a href="https:www.baidu.com">百度搜索</a>
a代表超链接:<a href="https:www.baidu.com" target="_blank">百度搜索</a>
</br>
</p>
<p class="class1">
第二、下面是我制作的表格:
<table>
<tr>
<td>td代表的是列1</td>
<td>td代表的是列2</td>
</tr>
<tr>
<td>第二行列1</td>
<td>第二行列2</td>
</tr>
</table>
</p>
<p id="p3">
第三、这里是排序列表,无序的了解了就行:
<ol>
<li>这是第一行</li>
<li>这是第二行</li>
<li>这是第三行</li>
</ol>
</p>
<frameset cols="40%,60%">
<frame src="./test_001.html">
<frame src="./test_002.html">
</frameset>
16、随机生成10个数,并写入文件?
打开文件,fs = open(“num.txt”, “a”)
写入文件,fs.write() 【写入文件,以,号隔开,join()将列表中的元素以字符串形式插入,Example: ‘.’.join([‘ab’, ‘pq’, ‘rs’]) -> ‘ab.pq.rs’】
关闭文件,fs.close()
import random
fs = open("num.txt", "a")
fs.write(",".join([str(random.randint(0, 10)) for i in range(10)]))
fs.close()
17、什么是session(会话)?
会话就是sessions(翻译:一段时间。场景:i think we have learned a lot about one another in this session)
session是服务器的一个缓存,用来存储用户的信息。DIS使用session机制进行鉴权,session中包含了多个变量:TGC、genex_session、fusgis、cosmosgis等。
场景:header里面有2个鉴权变量:cookies的多个session值、token的值。
鉴权cookies的变量都会以利用session机制传递下去。httprunner接口框架本身就是基于requests.session(),所以我们后续的请求没必要担心cookies鉴权不通过,只需在headers里面传递token值。token值进入界面的时候会有个接口来获取,我通常将各种获取token的请求放在登录用例中。
18、什么是token?
token是客户端请求后服务器后返回的字符串。该字符串代表了该账户的用户名密码。后续访问,header带上token值就可以访问了。
场景:登录到平台界面,进入地图管理界面,
(1)首先,触发一个接口返回了gis服务器token值,接口/cosmosgis/_csrf返回token值(一长随机字符串),
(2)然后,请求该页面其他接口,header只需带上token即可,如:.with_header(“CSRF-TOKEN”, “$token_cosmosgis”),token传错了会报403。
19、用的单元测试框架有unnittest,pytest?
unitest1年前用过,后来研究pytest,关于pytest框架做了十几篇博客,涉及框架设计、搭建、运行、allure报告继承、装饰器等。
20、什么是接口?
前台来看是功能点的实现,数据传输的通道,后台来看:是一个实现了http协议和映射机制的函数。接口参数就是:前台传入的数据,接口的响应:函数的返回值
21、常用的接口工具有?
使用httprunner接口测试框架做的自动化
22、为什么是使用代码实现自动化?
(1)我喜欢python,喜欢用它去解决我工作中面试的一切效率上的问题
(2)代码是灵活的,是底层的,更容易满足我的自动化需求
23、get与post的区别?
(1)get的参数是以?开头放在url里面的,项目中界面获取token的接口用到了get请求
(2)post请求占大多数,入参放在了body中,数据量比较大。
(3)从python的request库中看,get请求的源码也是基于post请求去实现的,当然他们都是基于request的类
24、都有哪些等待?
说下龟兔赛跑的故事,龟是页面加载(页面有的地方有很多js脚本,加载起来很慢的,有的地方很快),兔是代码。预备跑:页面加载刚走了一步,代码已经到终点了。有的地方代码要想执行下一步:必须等页面加载出来才能继续。等太久,代码就抛了个异常。
(1)强制等待,time.sleep()【代码在这里必须等3秒】
(2)隐形等待:driver.implicitly_wait(10)【如果在10s内网页加载完成,则执行下一步】
(3)显性等待:【每0.5秒检查一次元素能不能被点击】WebDriverWait(self.driver,20,0.5).until(EC.element_to_be_clickable(By.XPATH,’[]’))
def wait_click(self, *element):
"""
每0.5秒检查一次元素,元素能被点击,则执行。
示例:wait_click(By.Xpath, '[xxx]')
"""
return WebDriverWait(self.driver, 20, 0.5).until(EC.element_to_be_clickable(element))
25、你是怎么做接口自动化的
基于测试平台,直接从业务测试用例里面进行选择,按照界面基本功能,组合场景、异常场景逐步覆盖测试用例。
26、webdriver进行鼠标右键点击操作
def move_click(self, canvas, *args):
ActionChains(driver).move_to_element(canvas).move_by_offset(990, 123).release().click().perform()
# 使用场景:
# 定义了画布
canvas = driver.find_element_by_xpath("//canvas[@id='#canvas']")
# move_click()是上面封装的操作:鼠标移动到画布的坐标位置,且单击。
driver.move_click(canvas, 990, 110)
27、你在写自动化框架的时候,测试用例保存到哪里?用什么去读取?
不用读取,httprunner接口框架是转换fiddler抓取的接口数据为pytest形式的用例,只需要做参数化和关键字驱动等就可以,也可以直接用来跑接口的性能。
28、计算1-1000以内能被7整除,除以5余3的整数。
# 实现1:推导式:加if条件判断的模板:[i for i in range() if i%2==0]
li1 = [i for i in range(1, 1000) if i%5==3 and i%7==0]
print(li1)
# 实现2:一般实现方法
li2 = []
for i in range(1, 1000):
if i%5==3 and i%7==0:
li2.append(i)
print(i) # 逐行打印
print(li2)
# 实现3:匿名函数:加if条件判断的模板:list(filter(lambda i:i>2, range(1, 1000))),其中list()将迭代器转列表,filter(fun, 迭代器),将迭代器进行fun函数的过滤,下面的fun是匿名函数
li3 = list(filter(lambda i: i%5==3 and i%7==0, range(1, 1000)))
print(li3)
29、有100元,打算买100本书,A类书5元一本,B类书3元一本,C类书1元2本,共有多少种买法?。
n = 0
for i in range(21):
for j in range(34):
for k in range(201):
if 5 * i + 3 * j + k * 0.5 <= 100 and i + j + k == 100:
n += 1
print(n)
30、Python中自定义的函数如何传递动态参数(任意数量的实参)?。
args,**kwargs
31、什么是lambda函数?它有什么好处?。
lambda表达式可以让函数更加简洁,它是匿名函数,没有函数名称,常用模板:
# 过滤1000以内,整除7且除5余3的数字,
list(filter(lambda i: i%5==3 and i%7==0, range(1, 1000)))
32、Python语言中子类如何调用父类的构造函数?
如果子类没有定义构造函数,则子类默认会调用父类的构造函数;
如果子类定义了构造函数,那么在子类的构造函数中,调用父类的构造函数: python3中,使用super()._ init _()
33、列表常用方法?
list = [a,2,3,4,5,6,7,8]
切片:
list[::-1] # 反转列表
list[:] # 复制列表
list[::2] # 输出索引值为0的元素、为0+2元素,为0+2+2的元素 > [a,3,5,7]
list[1:3] # 输出索引值为1-5的元素 > [2,3,4]
list[:5] # 输出索引值为0-5之间的元素
list[5:] # 输出索引值5之后的元素
list[-3:] # 输出最后三个元素
list[0] # 访问列表元素, 第一个元素
list[6].title() # 列表元素首字母大写
list[0]=“tengfei” # 修改元素值:
添加:
list.append(“zh”) # 末尾添加元素
list.insert(0,“tengfei”) # 中间添加元素
删除:
del list[0] # 删除第一个元素
list.pop(x) # 按索引值x删除元素,且该元素可被使用。
list.remove(“jiao”) # 按列表的值删除元素
排序:
list.reverse() # 反转列表== list[::-1]
list.sort() # 永久排序
list.sorted() # 临时排序
list.copy() # 复制列表 ==list[:]【这里涉及深拷贝和浅拷贝,暂时用不到,再说】
***数字列表:***长度、最小值、最大值、求和
range(1,10,2) # 输出数字1,第二数字加2后输出,依次类推 直到9截止。
len(list) # 列表长度
min(list) # 列表最小值
max(list) # 列表最大值
sum(list) # 列表求和
34、列表常用方法?
表达式sum(range(1, 10, 2)) 的值为25
求1,3,5,7,9的和,sum函数的入参是个迭代器,所以直接可以list(range(1,10))
35、基于Web端呈现的产品可以如何做自动化测试,谈谈你的思路和方向。
接口层、UI层
接口层的自动化:
(1)先实现界面的接口基本功能覆盖
(2)再逐步实现组合场景、异常场景的用例覆盖
(3)实现升级场景测试数据的准备及升级后的校验
(4)辅助手工测试,进行各种测试环境的数据准备,提高测试效率
UI层的自动化:
(1)主要用来没有新需求的界面,界面功能稳定不变。
(2)pytest+selenium的conftest.py实现登录,结合allure实现测试报告等
(3)测试套件,直接使用pytest的main方法基本覆盖的日常需要
36、相关接口总结。
https://blog.csdn.net/PYTHONwuyou/article/details/113351714
https://blog.csdn.net/waitingwww/article/details/115256061
http://www.51testing.com/html/26/n-4476126.html?nomobile=1
https://www.jianshu.com/p/212ac9310074
https://www.tqwba.com/x_d/jishu/392523.html
37、python基础面试题
https://www.bilibili.com/read/cv10575915?ivk_sa=1024320u
https://www.jianshu.com/p/212ac9310074
https://www.cnblogs.com/zxmt/p/10808364.html
https://blog.csdn.net/qq_16633405/article/details/88354065
https://www.cnblogs.com/xiugeng/p/9712775.html
https://blog.csdn.net/qq_27695659/article/details/88532966
https://www.xin3721.com/pythonTech/python16863.html
https://blog.csdn.net/chenchen5152/article/details/117709815