【软件测试】自动化测试战零基础教程——Python自动化从入门到实战(四)

整理不易,希望对各位学习软件测试能带来帮助这里是引用

第十一节 对话框处理

页面上弹出的对话框是自动化测试经常会遇到的一个问题;很多情况下对话框是一个 iframe,如上一
节中介绍的例子,处理起来稍微有点麻烦;但现在很多前端框架的对话框是 div 形式的,这就让我们的处理变得十分简单。

图为百度首页的登录对话框,下面通过脚本对百度进行登录操作:

#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.baidu.com/")
#点击登录链接
driver.find_element_by_name("tj_login").click()
#通过二次定位找到用户名输入框
div=driver.find_element_by_class_name("tang-content").find_element_by_name("userName")
div.send_keys("username")
#输入登录密码
driver.find_element_by_name("password").send_keys("password")
#点击登录
driver.find_element_by_id("TANGRAM__PSP_10__submit").click()
driver.quit()

本例中并没有用到新方法,唯一的技巧是用到了二次定位,这个技巧在层级定位中已经有过使用。

driver.find_element_by_class_name(“tang-content”).find_element_by_name(“userName”)

第一次定位找到弹出的登录框,在登录框上再次进行定位找到了用户名输入框。

第十二节 浏览器多窗口处理

有时候我们在测试一个 web 应用时会出现多个浏览器窗口的情况,在 selenium1.0 中这个问题比较难
处理。webdriver 提供了相关相方法可以很轻松的在多个窗口之间切换并操作不同窗口上的元素。

在这里插入图片描述

要想在多个窗口之间切换,首先要获得每一个窗口的唯一标识符号(句柄)。通过获得的句柄来区别分不同的窗口,从而对不同窗口上的元素进行操作。

#coding=utf-8
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("http://www.baidu.com/")
#获得当前窗口
nowhandle=driver.current_window_handle
#打开注册新窗口
driver.find_element_by_name("tj_reg").click()
#获得所有窗口
allhandles=driver.window_handles
#循环判断窗口是否为当前窗口
for handle in allhandles:
if handle != nowhandle:
driver.switch_to_window(handle)
print 'now register window!'
#切换到邮箱注册标签
driver.find_element_by_id("mailRegTab").click()
time.sleep(5)
driver.close()
#回到原先的窗口
driver.switch_to_window(nowhandle)
driver.find_element_by_id("kw").send_keys(u"注册成功!")
time.sleep(3)
driver.quit()

处理过程:
这个处理过程相比我们前面的元素操作来说稍微复杂一些,执行过程为:首选通过 nowhandle 获得当
前窗口(百度首页)的句柄;然后,打开注册窗口(注册页);通过 allhandles 获得所有窗口的句柄;对所有句柄进行循环遍历;判断窗口是否为 nowhandle(百度首页),如果不是则获得当前窗口(注册页)的句柄;然后,对注册页上的元素进行操作。最后,回返到首页。

为了使执行过程更多更容易理解,在切换到注册页时,打印了’now register window!'一条信息;切换回百度首页时,我们在输入框输入了“注册成功!”。注意,我们在切换到注册页时,只是切换了一下邮箱注
册标签,如果要直执行注册过程还需要添加更多的操作步骤。
在本例中所有用到的新方法:

current_window_handle
获得当前窗口句柄

window_handles
返回的所有窗口的句柄到当前会话

switch_to_window()
用于处理多窗口操作的方法,与我们前面学过的 switch_to_frame() 是类似,switch_to_window()用于
处理多窗口之前切换,switch_to_frame() 用于处理多框架的切换。

close()
如果你足够细心会发现我们在关闭“注册页”时用的是 close()方法,而非 quit();close()用于关闭当前窗口,quit()用于退出驱动程序并关闭所有相关窗口。

第十二节 alert/confirm/prompt 处理

webdriver 中处理 JavaScript 所生成的 alert、confirm 以及 prompt 是很简单的。具体思路是使用switch_to.alert()方法定位到 alert/confirm/prompt。然后使用 text/accept/dismiss/send_keys 按需进行操做。

  • text 返回 alert/confirm/prompt 中的文字信息。
  • accept 点击确认按钮。
  • dismiss 点击取消按钮,如果有的话。
  • send_keys 输入值,这个 alert\confirm 没有对话框就不能用了,不然会报错。
    在这里插入图片描述

图所给出的是百度设置页面,在设置完成后点击“保存设置”所弹的提示框。下面通过脚本来
处理这个弹窗。

#coding=utf-8
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("http://www.baidu.com/")
#点击打开搜索设置
driver.find_element_by_name("tj_setting").click()
driver.find_element_by_id("SL_1").click()
#点击保存设置
driver.find_element_by_xpath("//div[@id='gxszButton']/input").click()
#获取网页上的警告信息
alert=driver.switch_to_alert()
#接收警告信息
alert.accept()
dirver.quit()

switch_to_alert()
用于获取网页上的警告信息。我们可以对警告信息做以下操作:

#接受警告信息
alert = driver.switch_to_alert()
alert.accept()
#得到文本信息并打印
alert = driver.switch_to_alert()
print alert.text()
#取消对话框(如果有的话)
alert = driver.switch_to_alert()
alert.dismiss()
#输入值(如果有的话)
alert = driver.switch_to_alert()
alert.send_keys(“xxx”)

第十三节 下拉框处理

下拉框也是 web 页面上非常常见的功能,webdriver 对于一般的下拉框处理起来也相当简单,要想定
位下拉框中的内容,首先需要定位到下拉框;这样的二次定位,我们在前面的例子中已经有过使用,下面通过一个具体的例子来说明具体定位方法。
drop_down.html

<html>
<body>
<select id="ShippingMethod" onchange="updateShipping(options[selectedIndex]);"
name="ShippingMethod">
<option value="12.51">UPS Next Day Air ==> $12.51</option>
<option value="11.61">UPS Next Day Air Saver ==> $11.61</option>
<option value="10.69">UPS 3 Day Select ==> $10.69</option>
<option value="9.03">UPS 2nd Day Air ==> $9.03</option>
<option value="8.34">UPS Ground ==> $8.34</option>
<option value="9.25">USPS Priority Mail Insured ==> $9.25</option>
<option value="7.45">USPS Priority Mail ==> $7.45</option>
<option value="3.20" selected="">USPS First Class ==> $3.20</option>
</select>
</body>
</html>

保存并通过浏览器打开,如下:

在这里插入图片描述

图中是最常现在我们来通过脚本选择下拉列表里的$10.69

#-*-coding=utf-8
from selenium import webdriver
import os,time
driver= webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('drop_down.html')
driver.get(file_path)
time.sleep(2)
#先定位到下拉框
m=driver.find_element_by_id("ShippingMethod")
#再点击下拉框下的选项
m.find_element_by_xpath("//option[@value='10.69']").click()
time.sleep(3)
driver.quit()

需要说明的是在实际的 web 测试时,会发现各种类型的下拉框,并非我们我们上面所介绍的传统的下
拉框。如图 ,对这种类型的下拉框一般的处理是两次点击,第一点击弹出下拉框,第二次点击操作元素。当然,也有些下拉框是鼠标移上去直接弹出的,那么我们可以使用 move_to_element()进行操作。
在这里插入图片描述

第十四节 分页处理

对于 web 页面上的分页功能,我们一般做做以下操作:

  • 获取总页数
  • 翻页操作(上一页,下一页)
    对于有些分页功能提供上一页,下一页按钮,以及可以输入具体页面数跳转功能不在本例的讨论范围。
<select id="pageElm_a74e_ce2c" class="yem" action="page" data-page="5">
<option value="1">1/5</option>
<option value="2">2/5</option>
<option value="3">3/5</option>
<option value="4">4/5</option>
<option value="5">5/5</option>
</select>

…上面代码为分页功能的代码片断,显示效果如下:
在这里插入图片描述

#coding=utf-8
from selenium import webdriver
from time import sleep
driver = webdriver.Firefox()
driver.get("http://passport.kuaibo.com/login/?referrer=http%3A%2F%2Fvod.kuai
bo.com%2F%3Fly%3Ddefault")
#登录系统
driver.find_element_by_id("user_name").clear()
driver.find_element_by_id("user_name").send_keys("username")
driver.find_element_by_id("user_pwd").clear()
driver.find_element_by_id("user_pwd").send_keys("password")
driver.find_element_by_id("dl_an_submit").click()
sleep(2)
#获取所有分页的数量,并打印
total_pages=len(driver.find_element_by_tag_name("select").find_elements_by_t
ag_name("option"))
print "total page is %s" %(total_pages)
sleep(3)
#再次获取所分页,并执行循环翻页操作
pages=driver.find_element_by_tag_name("select").find_elements_by_tag_name("o
ption")
for page in pages:
page.click()
sleep(2)
sleep(3)
driver.quit()

len()方法在定位一组对象有时已经用过,用于获取对象的个数。

这里同样用到了二次定位,只是第二次定位用的是 find_elements 方法,获取的是一组元素。通过上
面的脚本可以看到,我们第一次获取到一组元素后,打印了所有分页的个数。第二次获取所有分页后, 通过 for 循环来翻阅每一页,每翻一页休眠 2 秒,当然,我们也可以在翻页后对列表的文件做更多操作。

第十五节 上传文件

文件上传操作也比较常见功能之一,上传功能操作 webdriver 并没有提供对应的方法,关键上传文
件的思路。
上传过程一般要打开一个系统的 window 窗口,从窗口选择本地文件添加。所以,一般会卡在如何操
作本地 window 窗口。其实,上传本地文件没我们想的那么复杂;只要定位上传按钮,通 send_keys 添加本地文件路径就可以了。绝对路径和相对路径都可以,关键是上传的文件存在。下面通地例子演示操作过程。
upload_file.html

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>upload_file</title>
<script type="text/javascript" async=""
src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css"
rel="stylesheet" />
<script type="text/javascript">
</script>
</head>
<body>
<div class="row-fluid">
<div class="span6 well">
<h3>upload_file</h3>
<input type="file" name="file" />
</div>
</div>
</body>
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
</html>

通过浏览器打开,得到下列页面:
在这里插入图片描述

操作上传脚本:

#coding=utf-8
from selenium import webdriver
import os,time
driver = webdriver.Firefox()
#打开上传文件页面
file_path = 'file:///' + os.path.abspath('upload_file.html')
driver.get(file_path)
#定位上传按钮,添加本地文件
driver.find_element_by_name("file").send_keys('D:\\selenium_use_case\upload
_file.txt')
time.sleep(2)
driver.quit()

从上面例子可以看到,send_keys()方法除可以输入内容外,也可以跟一个本地的文件路径。从而达
到上传文件的目的。
文件上传成功的效果如图:
在这里插入图片描述

第十六节 下载文件

webdriver 允许我们设置默认的文件下载路径。也就是说文件会自动下载并且存在设置的那个目录
中。
要想下载文件,首选要先确定你所要下载的文件的类型。要识别自动文件的下载类型可以使用 curl ,
如图:
在这里插入图片描述

curl 是利用 URL 语法在命令行方式下工作的开源文件传输工具。

Content-Type ,内容类型,一般是指网页中存在的 Content-Type ,用于定义网络文件的类型和
网页的编码,决定浏览器将以什么形式、什么编码读取这个文件。
另一种方法是使用 requests 模块来查找内容类型。Requests 是一个 Python 的 HTTP 客户端库,

默认下载的 python 环境包不包含这个类库,需要另外安装。使用方法如下:

import requests
print requests.head(’http://www.python.org’).headers[’content-type’]

一旦确定了内容的类型,就可以用它来设置 Firefox 的默认配置文件,具体实例如下:

#coding=utf-8
import os
from selenium import webdriver
fp = webdriver.FirefoxProfile()
fp.set_preference("browser.download.folderList",2)
fp.set_preference("browser.download.manager.showWhenStarting",False)
fp.set_preference("browser.download.dir", os.getcwd())
fp.set_preference("browser.helperApps.neverAsk.saveToDisk",
"application/octet-stream")
browser = webdriver.Firefox(firefox_profile=fp)
browser.get("http://pypi.python.org/pypi/selenium")
browser.find_element_by_partial_link_text("selenium-2").click()

browser.download.dir 用于指定你所下载文件的目录。

os.getcwd() 该函数不需要传递参数,用于返回当前的目录。

application/octet-stream 为内容的类型。

第十七节 调用 JavaScript

当 webdriver 遇到没法完成的操作时,笔者可以考虑借用 JavaScript 来完成,比下下面的例子,通过 JavaScript 来隐藏页面上的元素。除了完成 webdriver 无法完成的操作,如果你熟悉 JavaScript
的话,那么使用 webdriver 执行 JavaScript 是一件非常高效的事情。
webdriver 提供了 execute_script() 接口用来调用 js 代码。
js.html

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>js</title>
<script type="text/javascript" async=""
src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css"
rel="stylesheet" />
<script type="text/javascript">
$(document).ready(function(){
$('#tooltip').tooltip({"placement": "right"});
});
</script>
</head>
<body>
<h3>js</h3>
<div class="row-fluid">
<div class="span6 well">
<a id="tooltip" href="#" data-toggle="tooltip" title=" selenium-webdriver(python)">hover to see
tooltip</a>
<a class="btn">Button</a>
</div>
</div>
</body>
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
</html>

保存 js.html 文件并通过浏览器打开,效果如图:
在这里插入图片描述

执行 js 一般有两种场景:

  • 一种是在页面上直接执行 JS
  • 另一种是在某个已经定位的元素上执行 JS
#coding=utf-8
from selenium import webdriver
import time,os
driver = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('js.html')
driver.get(file_path)
#######通过 JS 隐藏选中的元素##########第一种方法:
#隐藏文字信息
driver.execute_script('$("#tooltip").fadeOut();')
time.sleep(5)
#隐藏按钮:
button = driver.find_element_by_class_name('btn')
driver.execute_script('$(arguments[0]).fadeOut()',button)
time.sleep(5)
driver.quit()

execute_script(script, *args)

在当前窗口/框架 同步执行 javaScript

script:JavaScript 的执行。

*args:适用任何 JavaScript 脚本。

关于JavaScript代码的解析不在本书的范围之内,请读者通过其它资料学习理解JavaScript的使用。
隐藏之后的效果如图
在这里插入图片描述

第十八节、控制浏览器滚动条

有时候 web 页面上的元素并非直接可见的,就算把浏览器最大化,我们依然需要拖动滚动条才能看到
想要操作的元素,这个时候就要控制页面滚动条的拖动,但滚动条并非页面上的元素,可以借助 JavaScript
是来完成操作。
一般用到操作滚动条的会两个场景:

  • 注册时的法律条文的阅读,判断用户是否阅读完成的标准是:滚动条是否拉到最下方。
  • 要操作的页面元素不在视觉范围,无法进行操作,需要拖动滚动条
    用于标识滚动条位置的代码
<body onload= "document.body.scrollTop=0 ">
<body onload= "document.body.scrollTop=100000 ">

如果滚动条在最上方的话,scrollTop=0 ,那么要想使用滚动条在最可下方,可以 scrollTop=100000 ,
这样就可以使滚动条在最下方。
在这里插入图片描述

图中百度搜索结果页且滚动条在页面底,下面通过脚本实现:

#coding=utf-8
from selenium import webdriver
import time
#访问百度
driver=webdriver.Firefox()
driver.get("http://www.baidu.com")
#搜索
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
time.sleep(3)
#将页面滚动条拖到底部
js="var q=document.documentElement.scrollTop=10000"
driver.execute_script(js)
time.sleep(3)
#将滚动条移动到页面的顶部
js_="var q=document.documentElement.scrollTop=0"
driver.execute_script(js_)
time.sleep(3)
driver.quit()

第十九节 cookie 处理

有时候我们需要验证浏览器中是否存在某个 cookie,因为基于真实的 cookie 的测试是无法通过白盒
和集成测试完成的。webdriver 可以读取、添加和删除 cookie 信息。
webdriver 操作 cookie 的方法有:

  • get_cookies() 获得所有 cookie 信息
  • get_cookie(name) 返回特定 name 有 cookie 信息
  • add_cookie(cookie_dict) 添加 cookie,必须有 name 和 value 值
  • delete_cookie(name) 删除特定(部分)的 cookie 信息
  • delete_all_cookies() 删除所有 cookie 信息
    通过 webdriver 操作 cookie 是一件非常有意思的事儿,有时候我们需要了解浏览器中是否存在了某个
    cookie 信息,webdriver 可以帮助我们读取、添加,删除 cookie 信息。

3.19.1 打印 cookie 信息

#coding=utf-8
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get("http://www.youdao.com")
# 获得 cookie 信息
cookie= driver.get_cookies()
#将获得 cookie 的信息打印
print cookie
driver.quit()

运行打印信息:

[{u'domain': u'.youdao.com', u'secure': False, u'value':
u'aGFzbG9nZ2VkPXRydWU=', u'expiry': 1408430390.991375, u'path': u'/',
u'name': u'_PREF_ANONYUSER__MYTH'}, {u'domain': u'.youdao.com', u'secure':
False, u'value': u'1777851312@218.17.158.115', u'expiry':
2322974390.991376, u'path': u'/', u'name': u'OUTFOX_SEARCH_USER_ID'},
{u'path': u'/', u'domain': u'www.youdao.com', u'name': u'JSESSIONID',
u'value': u'abcUX9zdw0minadIhtvcu', u'secure': False}]

3.19.2、对 cookie 操作

上面的方式打印了所有 cookie 信息,太多太乱,我们只想有真对性的打印自己想要的信息,看下面的例子:

#coding=utf-8
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("http://www.youdao.com")
#向 cookie 的 name 和 value 添加会话信息。
driver.add_cookie({'name':'key-aaaaaaa', 'value':'value-bbbb'})
#遍历 cookies 中的 name 和 value 信息打印,当然还有上面添加的信息
for cookie in driver.get_cookies():
print "%s -> %s" % (cookie['name'], cookie['value'])
##### 下面可以通过两种方式删除 cookie #####
# 删除一个特定的 cookie
driver.delete_cookie("CookieName")
# 删除所有 cookie
driver.delete_all_cookies()
time.sleep(2)
driver.close()

运行打印信息:

YOUDAO_MOBILE_ACCESS_TYPE -> 1
_PREF_ANONYUSER__MYTH -> aGFzbG9nZ2VkPXRydWU=
OUTFOX_SEARCH_USER_ID -> -1046383847@218.17.158.115
JSESSIONID -> abc7qSE_SBGsVgnVLBvcu
key-aaaaaaa -> value-bbbb # 这一条是我们自己添加的

第二十节 获取对象的属性

获取测试对象的属性能够帮我们更好的进行对象的定位。比如页面上有很多标签为 input 元素,而我
们需要定位其中 1 个有具有 data-node 属性不一样的元素。由于 webdriver 是不支持直接使用 data-node 来定位对象的,所以我们只能先把所有标签为 input 都找到,然后遍历这些 input,获取想要的元素。
例如,有下面一组元素:

<input type="checkbox" data-node="594434499" data-convert="1" data-type="file">
<input type="checkbox" data-node="594434498" data-convert="1" data-type="file">
<input type="checkbox" data-node="594434493" data-convert="1" data-type="file">
<input type="checkbox" data-node="594434497" data-convert="1" data-type="file">

通过 find_elements 获得一组元素,通过循环遍历打到想要的元素:

# 选择页面上所有的 tag name 为 input 的元素
inputs = driver.find_elements_by_tag_name('input')
#然后循环遍历出 data-node 为594434493的元素,单击勾选
for input in inputs:
if input.get_attribute('data-node') == '594434493':
input.click() ……

如果读者细心会发现,我们在前面定位一组对象时已经用到了这个方法,当时判断是具有一组相同属性的元素,对其进行操作。这里判断是属性值不同的元素对其进行操作。灵活的运用这个技巧,才会让我们面对各种对象和需求时变得游刃有余。

第二十一节 验证码问题

对于 web 应用来说,大部分的系统在用户登录时都要求用户输入验证码,验证码的类型的很多,有字
母数字的,有汉字的,甚至还要用户输入一条算术题的答案的,对于系统来说使用验证码可以有效果的防止采用机器猜测方法对口令的刺探,在一定程度上增加了安全性。但对于测试人员来说,不管是进行性能测试还是自动化测试都是一个棘手的问题。
在这里插入图片描述

下面笔者根据自己的经验来谈一下

处理验证码的几种方法。

去掉验证码

这是最简单的方法,对于开发人员来说,只是把验证码的相关代码注释掉即可,如果是在测试环境,
这样做可省去了测试人员不少麻烦,如果自动化脚本是要在正式环境跑,这样就给系统带来了一定的风险。

设置万能码

去掉验证码的主要是安全问题,为了应对在线系统的安全性威胁,可以在修改程序时不取消验证码,
而是程序中留一个“后门”—设置一个“万能验证码”,只要用户输入这个“万能验证码”,程序就认为验
证通过,否则按照原先的验证方式进行验证。

验证码识别技术

例如可以通过 Python-tesseract 来识别图片验证码,Python-tesseract 是光学字符识别 Tesseract OCR 引擎的 Python 封装类。能够读取任何常规的图片文件(JPG, GIF ,PNG , TIFF 等)。不过,目前市面上的验证码形式繁多,目前任何一种验证码识别技术,识别率都不是 100% 。

记录 cookie
通过向浏览器中添加 cookie 可以绕过登录的验证码,这是比较有意思的一种解决方案。我们可以在
用户登录之前,通过 add_cookie()方法将用户名密码写入浏览器 cookie ,再次访问系统登录链接将自
动登录。例如下面的方式:
.... #访问 xxxx 网站
driver.get("http://www.xxxx.cn/")
#将用户名密码写入浏览器 cookie
driver.add_cookie({'name':'Login_UserNumber', 'value':'username'})
driver.add_cookie({'name':'Login_Passwd', 'value':'password'})
#再次访问 xxxx 网站,将会自动登录
driver.get("http://www.xxxx.cn/")
time.sleep(3)
.... driver.quit()

使用 cookie 进行登录最大的难点是如何获得用户名密码的 name ,如果找到不到 name 的名字,就没办法向 value 中输用户名、密码信息。

笔者的建议是可以通过 get_cookies()方法来获取登录的所有的 cookie 信息,从而进行找到用户名、密码的 name 对象的名字;当然,最简单的方法还是询问前端开发人员。

第二十二节 weddriver 原理

webdriver 原理:

  1. WebDriver 启动目标浏览器,并绑定到指定端口。该启动的浏览器实例,做为 web driver 的 remote
    server。
  2. Client 端通过 CommandExcuter 发送 HTTPRequest 给 remote server 的侦听端口(通信协议: the
    webriver wire protocol)
  3. Remote server 需要依赖原生的浏览器组件(如:IEDriverServer.exe、chromedriver.exe),来转
    化转化浏览器的 native 调用。

总结:

通过本章的学习,我们比较全面的掌握了如何使用 webdriver 所提供的方法对页面上各种元素进行操作。不过在实际的自动化测试过程中,读者会遇到各种各样的问题,笔者建议读者从以下几个方面进行提高:

  1. 熟练掌握 xpath\CSS 定位的使用,这样在遇到各种难以定位的属性时才不会变得束手无策。
  2. 准备一份 python 版本的 webdriver API ,遇到不理解地方,及时查到 API 的使用
  3. 学习掌握 JavaScript 语言,掌握 JavaScript 好处前面已经有过阐述,可以让我们的自动化测试工作更加游刃有余。
  4. 自动化测试归根结底是与前端打交道,多多熟悉前端技术,如 http 请求,HTML 语言 ,cookie/session 机制等。

未完待续

软件测试打卡交流聚集地

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值