UI自动化
一、web 自动化
1.自动化
1.1概念
由机器设备代替人工,自动完成制定目标的过程
1.2优点
- 减少人工劳动力
- 提高工作效率
- 产品规格统一标准
- 规模化(批量生产)
- 安全
2.自动化测试
2.1 概念
用程序代替人工去执行测试的过程
软件测试:对程序进行操作,以发现程序错误,并验证其是否满足需求过程
2.2 应用场景
- 解决:冒烟测试
- 冒烟测试:每个版本提测时,验证其是否达到可测标准
- 解决:回顾测试
- 回归测试:可以理解多用户同时去操作软件,统计软件服务进行验证
- 解决:压力测试
- 压力测试:可以理解多用户同时去操作软件,统计软件服务器处理多用户请求的能力
- 解决:兼容性测试
- 兼容性测试:不同浏览器
- 提高测试效率吗,保证产品质量
2.3正确认识
优点
- 较少的时间内运行更多的测试用例
- 自动化脚本可重复运行
- 较少人为的错误
- 克服手工测试的局限性
误区 - 自动化测试可以完全替代手工测试
- 自动化测试一点比手工测试厉害
- 自动化测试可以挖掘更多的bug
- 自动化测试适用于所有功能
2.4 分类
- web-自动化测试
- 移动-自动化测试
- 接口-自动化测试
- 单元测试-自动化测试
3.web自动化测试
概念
用程序代替人工去执行web测试的过程
什么样的项目适合去做web自动化测试?
- 需求变动不频繁
- 项目周期长
- 项目需要回归测试/冒烟测试/兼容性测试/压力测试
web自动化测试什么时候开始
- 对于自动化冒烟测试,一般是手工测试开始前
- 对与其他目的的自动化测试,一般是手工测试结束后
web自动化测试所属分类
属于功能测试(黑盒)
4.Selenium
4.1 web自动化工具简介
主流工具
- QTP:一个商业化的功能测试工具,收费,支持web、桌面自动化测试
- Selenium:开源的web自动化测试工具,主要做功能测试
#- robot framework:一个基于python可扩展的关键字驱动的自动化测试框架
Selenium特点
- 开源软件:源代码开放可以根据需要来增加工具的某些功能
- 跨平台:Linux、Windows、Mac
- 支持多种浏览器
- 支持多种语言
- 成熟稳定
- 功能强大
4.2环境搭建
1. 搭建步骤
前提:基于python搭建
- python开发环境
- 安装 Selenium包
- 安装浏览器
- 安装浏览器驱动
2.安装Selenium包
pip install selenium
3.安装浏览器驱动
4.3 入门示例
1.需求
2.实现步骤
3.示例代码
# 1.导包
import time
from selenium import webdriver
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.打开百度首页
driver.get("http://www.baidu.com")
# 4.暂停3s
time.sleep(3)
# 5.关闭浏览器
driver.quit()
二、selenium-API
1.元素定位基础
1.1 为什么进行元素定位
让程序操作指定元素,就必须先找到此元素
1.2 如何进行元素定位
通过元素的信息或元素层级结构来定位元素
1.3 浏览器开发工具
概念
浏览器开发者工具就是给专业的web应用和网站开发的人员使用的工具,包含了对html查看和编辑,Javascript控制台,网络状况监视等功能,是开发Javascript、css、html和Ajax的得力助手
作用
定位元素,查看元素信息
1.4 元素定位方式
1.4.1总体介绍
Selenium提供了八种定位元素方式
- id
- name
- class_name
- tag_name
- link_text
- partial_link_text
- XPath
- css
1.4.2 id定位
说明:id定位就是通过元素的id属性来定位元素,html规定id属性在整个html文档中必须是唯一的;
前提:元素有id属性
方法
driver.find_element(by=By.ID, value="id")
案例
# 1.导包
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
driver.find_element(by=By.ID, value="userA").send_keys("admin")
driver.find_element(by=By.ID, value="passwordA").send_keys("123456")
# 4.暂停5s
time.sleep(3)
# 5.关闭浏览器
driver.quit()
1.4.3 name定位
说明:name定位就是根据元素name属性来定位,html文档中name的属性值可以重复
前提:元素有name属性
方法
driver.find_element(by=By.NAME, value="id")
代码
# 1.导包
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
driver.find_element(by=By.NAME, value="userA").send_keys("admin")
driver.find_element(by=By.NAME, value="passwordA").send_keys("123456")
# 4.暂停5s
time.sleep(5)
# 5.关闭浏览器
driver.quit()
1.4.4 class_name定位
说明:class_name定位就是根据元素class属性值来定位元素,html通过class来定义元素的样式
前提:元素有class属性
注意:如果class有多个属性值,只能使用其中一个
方法
driver.find_element(by=By.CLASS_NAME, value="class_name")
代码
# 1.导包
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
driver.find_element(by=By.CLASS_NAME, value="telA").send_keys("13111111111")
driver.find_element(by=By.CLASS_NAME, value="emailA ").send_keys("123456@qq.com")
# 4.暂停5s
time.sleep(5)
# 5.关闭浏览器
driver.quit()
1.4.5 tag_name定位
说明:tag_name定位就是通过标签名来定位;
html本质就是由不同的tag组成,每一种标签一般在页面中会存在多个所以不方便进步精确定位,一般很少使用
如何获取第二个标签
方法
driver.find_element(by=By.TAG_NAME, value="telA")
实现
1.4.6 link_text定位
说明:是专门用来定位超链接元素的<a>连接</a>并且是通过超链接的文本来定位元素
方法
driver.find_element(by=By.LINK_TEXT, value="LINK_TEXT")
# LINK_TEXT:为超链接全部文本内容
实现
# 1.导包
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
driver.find_element(by=By.LINK_TEXT, value="访问 新浪 网站").click()
# 4.暂停5s
time.sleep(5)
# 5.关闭浏览器
driver.quit()
partial_link_test 定位
说明:partial_link_test 定位是对link_test定位的补充,
link_text使用全部文本内容匹配元素,
而partial_link_test 可以使用局部来匹配元素,也可以全部文本内匹配元素
方法
driver.find_element(by=By.PARTIAL_LINK_TEXT, value="PARTIAL_LINK_TEXT")
# PARTIAL_LINK_TEXT 可以传入a标签局部文本-能表达唯一性
实现
# 1.导包
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
driver.find_element(by=By.PARTIAL_LINK_TEXT, value="访问 新浪 网站").click() # 全部文本点击
driver.find_element(by=By.PARTIAL_LINK_TEXT, value="访问").click() # 局部文本点击
# 4.暂停5s
time.sleep(5)
# 5.关闭浏览器
driver.quit()
1.5 定位一组元素
说明:
方法
driver.find_elements(by=By.TAG_NAME, value="input")
#作用:
# 1.查找定位所有符合条件的元素
# 2.返回值是一个列表
#说明:列表数据格式的读取需要指定下标(下标从0开始)
实现
# 1.导包
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
element = driver.find_elements(by=By.TAG_NAME, value="input")
element[2].send_keys("123456")
# 4.暂停5s
time.sleep(5)
# 5.关闭浏览器
driver.quit()
2.元素定位-XPath/CSS
2.1 总体介绍
1. 如果id,name,class属性,该如何定位?
2. 如果通过name,class等无法定位到唯一元素,该如何进行定位?
2.2 XPath定位方式
2.2.1 什么是XPath
1. XPath即为xml,path的简称,他是一门在xml文档中查找元素信息的语言
2. html可以看做是xml的一种实现,所以Selenium用户可以使用这种强大的语言在web应用中定位元素
2.2.2 xpath定位方式
2.2.2.1总体介绍
四种定位方式
1. 路径-定位
2. 利用元素属性-定位
3. 属性与逻辑结合-定位
4. 层级与属性结合-定位
方法
driver.find_element(by=By.XPATH, value="XPATH")
2.2.2.2 路径
绝对路径: 从最外层元素指定元素之间所有经过元素层级的路径
1.绝对路径以/html根节点开始,使用/来分割元素层级
如:/html/boby/div/fields/p[1]/input
2.绝对路径对页面结构要求比较严格,不建议使用
相对路径: 匹配任意层级的元素,不限制元素的位置
1.相对路径以//开始
2.格式://input或者//*
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 定位用户名输入框 admin
driver.find_element(by=By.XPATH, value="/html/body/div/fieldset/form/p[1]/input").send_keys("admin")
# 暂停三秒
time.sleep(3)
driver.find_element(by=By.XPATH, value="//*[@id='passwordA']").send_keys("123")
# 暂停5秒
time.sleep(5)
driver.close()
使用谷歌浏览器获取xpath表达式的过程:
1.元素上邮件–>检查
2.在文档F12对应的元素上右键–>copy–>copy xpath或者copy full xpath
2.2.2.3 利用元素属性
说明:通过使用元素的属性信息来定位元素
格式://input[@id='userA'] 或者 //*[@id=''userA]
练习
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 定位用户名输入框 admin
# 利用元素属性通过XPath
driver.find_element(by=By.XPATH, value="//*[@id='userA']").send_keys("admin")
driver.find_element(by=By.XPATH, value="//*[@name='userA']").send_keys("admin")
driver.find_element(by=By.XPATH, value="//*[@placeholder='请输入用户']").send_keys("admin")
driver.find_element(by=By.XPATH, value="//*[@type='text']").send_keys("admin")
# 暂停三秒
time.sleep(3)
driver.find_element(by=By.XPATH, value="//*[@id='passwordA']").send_keys("123")
# 暂停5秒
time.sleep(5)
driver.close()
2.2.2.4 属性与逻辑结合
说明:解决元素之间存在相同属性值的问题
格式://*[@name="xxx" and @class='yyy']
练习
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 定位用户名输入框 admin
# 利用元素属性通过XPath
driver.find_element(by=By.XPATH, value="//*[@type='text' and @name='userA']").send_keys("admin")
# 暂停三秒
# 暂停5秒
time.sleep(5)
driver.close()
2.2.2.5 层级与属性结合
说明:如果通过元素自身的属性不方便直接定位该元素,则可以先定位到其父元素,然后再找到该元素的
格式://*[@id='p1']/input
练习
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 定位用户名输入框 admin
# 利用元素属性通过XPath
driver.find_element(by=By.XPATH, value="//*[@id='p1']/input").send_keys("admin")
# 暂停三秒
# 暂停5秒
time.sleep(5)
driver.close()
2.2.2.6 XPath 扩展
说明:不适用函数时://*[@id='xxx']
使用函数后:
//*[tesxt()='xxx']文本内容是xxx的元素
//*[contains[@(attribute,'xxx')]属性中含有xxx值的元素
//*[start-with(@attribute,'xxx')]属性以xxx开头的元素
练习
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 定位用户名输入框 admin
# 利用元素属性通过XPath
driver.find_element(by=By.XPATH, value="//*[text()='访问 新浪 网站']").click()
driver.find_element(by=By.XPATH, value="//*[contains(@placeholder,'用户名')]").send_keys("admin")
driver.find_element(by=By.XPATH, value="//*[starts-with(@placeholder,'请输入密')]").send_keys("1234")
# 暂停三秒
# 暂停5秒
time.sleep(5)
driver.close()
2.3 css定位
2.3.1 什么是css
- css是一种语言,它用来描述HTML元素的显示样式
- 在css中,选择器是一种模式,用于选择添加样式的元素
- Selenium中可以使用这种选择器来定位元素
提示
1.在Selenium中推荐使用css定位,因此他比XPath定位速度要快
2.css选择器语法非常强大,在这里我们只学习在测试中常用的几个
2.3.2 css定位方式
2.3.2.1总体介绍
常用定位方法
1. id选择器
2. class选择器
3. 元素选择器
4. 属性选择器
5.层级选择器
方法
driver.find_element(by=By.CSS_SELECTOR, value="CSS_SELECTOR")
2.3.2.2 id选择器
说明:根据元素的id属性来选择
格式:#id(值)
例如:#userA 选择id属性值为userA的元素
练习
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 定位用户名输入框 admin
# 利用元素属性通过XPath
driver.find_element(by=By.CSS_SELECTOR, value="#userA").send_keys("admin")
# 暂停三秒
# 暂停5秒
time.sleep(5)
driver.close()
2.3.2.3 class选择器
说明:根据元素的class属性来选择
格式:.class(值)
例如:.userA 选择class属性值为userA的元素
练习
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 定位用户名输入框 admin
# 利用元素属性通过XPath
driver.find_element(by=By.CSS_SELECTOR, value=".telA").send_keys("13111111111")
# 暂停三秒
# 暂停5秒
time.sleep(5)
driver.close()
2.3.2.4 元素选择器
说明:根据元素的标签名来选择
格式:标签名
例如:input 选择input元素
练习
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 定位用户名输入框 admin
# 利用元素属性通过XPath
driver.find_element(by=By.CSS_SELECTOR, value="button").click()
# 暂停三秒
# 暂停5秒
time.sleep(5)
driver.close()
2.3.2.5 属性选择器
说明:根据元素的属性名和值来选择
格式:[attribute=value]
例如:[type="password"]选择type属性名对应的属性值为password的元素
练习
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 定位用户名输入框 admin
# 利用元素属性通过XPath
driver.find_element(by=By.CSS_SELECTOR, value="[type='password']").send_keys("123456")
# 暂停三秒
# 暂停5秒
time.sleep(5)
driver.close()
2.3.2.6 层级选择器
说明:根据元素的父子关系来选择
格式:element1>element2 通过element1来定位element2,并且element2必须为element1的直接子元素
例如1:p[id='p1']>input 定位了指定p元素下的直接子元素
格式2:element1 element2 通过element1来定位element2,并且element2为element1的后代元素
例如2:p[id='p1'] input 定位了指定p元素下的后代元素
练习
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 定位用户名输入框 admin
# 利用元素属性通过css
driver.find_element(by=By.CSS_SELECTOR, value="p[id='pa']>input").send_keys("admin")
driver.find_element(by=By.CSS_SELECTOR, value="div[class='zc'] input").send_keys("admin")
# 暂停三秒
# 暂停5秒
time.sleep(5)
driver.close()
2.3.2.7 css扩展
格式1: input[type^='p'] type属性以p字母开头的元素
格式2: input[type$='d'] type属性以b字母结束的元素
格式3: input[type*='w'] type属性包含w字母的元素
练习
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 定位用户名输入框 admin
# 利用元素属性通过css定位扩展的方式
# 开头
driver.find_element(by=By.CSS_SELECTOR, value="input[type^='t']").send_keys("admin")
driver.find_element(by=By.CSS_SELECTOR, value="input[name^='u']").send_keys("admin")
# 结尾
driver.find_element(by=By.CSS_SELECTOR, value="input[type$='t']").send_keys("admin")
# 包含
driver.find_element(by=By.CSS_SELECTOR, value="input[type*='ex']").send_keys("admin")
# 暂停三秒
# 暂停5秒
time.sleep(5)
driver.close()
XPath 和CSS对比
定位方式 | XPath | css |
---|---|---|
元素名 | //input | input |
id | //*[@id=‘userA’] | #userA |
class | //*[@class=‘userA’] | .telA |
属性名 | 1.//input[@id=‘userA’ 2.//[text()=‘x’]] 3.//*[contains(@attribute,''x)] | 格式1: input[type^=‘p’] type属性以p字母开头的元素 格式2: input[type$=‘d’] type属性以b字母结束的元素格式3: input[type*=‘w’] type属性包含w字母的元素 |
3.元素定位总结
3.1.方法介绍
1. id,name,class_name:为元素属性定位
2. tag_name:为元素标签名称
3. link_text、partial_link_text:为超链接定位(a标签)
4. XPath:为元素路径定位
5. css:为css选择器定位
4.元素操作
4.1应用场景
1. 需要让脚本模拟用户给指定元素输入值
2. 需要让脚本模拟人为删除元素的内容
3. 需要让脚本模拟点击操作
4.2方法
1. click() 单击元素
2. send_keys(value)模拟用户输入
3. clear() 清除文本
5.浏览器操作
示例
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 定位用户名输入框 admin
# 浏览器最大化窗口
driver.maximize_window()
# 设置窗口的大小
driver.set_window_size(300, 300)
# 设置窗口位置
driver.set_window_position(300, 300)
# 前进
driver.back()
# 后退
driver.forward()
# 刷新
driver.refresh()
#
print("title为:", driver.title)
print("当前页面地址", driver.current_url)
driver.find_element(by=By.CSS_SELECTOR, value="input[type^='t']").send_keys("admin")
# 暂停5秒
time.sleep(5)
# 关闭当前浏览器窗口 ==>执行结果,留下留下新浪网站,关闭注册页
driver.close()
# 关闭浏览器驱动对象 ==>关闭所有窗口
driver.quit()
6.获取元素信息
6.1应用场景
1. 获取元素的文本
2. 获取元素属性值
3. 让程序判断元素是否可见状态
6.2 常用方法
1. size 返回元素大小
2. text 获取元素的文本
3. get_attribute("XXX") 获取属性值,传递参数元素的属性名
4. is_displayed() 判断元素是否可见
5. is_enabled() 判断元素是否可用
6. is_selected() 判断元素是否选中,用来检查复选框或单选按钮是否被选中
提示:size、text:为属性,调用时无括号;如:xxx.size
6.3案例
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 获取用户名输入框的大小
print(driver.find_element(by=By.ID, value="userA").size)
# 获取页面上第一个超链接的文本内容
print(driver.find_element(by=By.TAG_NAME, value="a").text)
# 获取页面上第一个超链接的地址
print(driver.find_element(by=By.TAG_NAME, value="a").get_attribute("href"))
# 判断页面中的span的标签是否可见
print(driver.find_element(by=By.TAG_NAME, value="span").is_displayed())
# 判断页面中的按钮是否可用
print(driver.find_element(by=By.ID, value="cancelA").is_enabled())
# 判断页面中的旅游对应的复选框是否为选中状态
print(driver.find_element(by=By.ID, value="lyA").is_selected())
time.sleep(5)
# 关闭当前浏览器窗口 ==>执行结果,留下留下新浪网站,关闭注册页
# driver.close()
# 关闭浏览器驱动对象 ==>关闭所有窗口
driver.quit()
7.鼠标操作
7.1 什么是鼠标操作
点击、右击、双击、悬停、拖拽
7.2 应用场景
现在web产品中存在丰富的鼠标交互方式,作为一个web自动化测试框架,需要对这些鼠标操作的应用场景
7.3 常用方法
#说明:在Selenium中将操作鼠标的方法封装在ActionChains类中
# 实例化对象:
from selenium.webdriver import ActionChains
action = ActionChains(driver)
#方法:
action.context_click(element) # 右击
action.click(element) # 双击
action.move_to_element(element) # 悬停
action.drag_and_drop(element) # 拖拽
action.perform(source,target) # 执行
# 为了更好的学习其他方法,我们先学习perfrom()执行方法,因为ActionChains所有方法需要执行才能生效
7.4 鼠标执行-perform()
说明:在ActionChains类中所有提供的鼠标事件方法,在调用的时候,所有行为都存储在Actionchains对象中,而perform()方法就去执行所有鼠标事件
强调:必须调用perform()方法才能执行鼠标事件
7.5 鼠标右键-context_click()
说明:对与鼠标右键,如果弹出的是浏览器默认的菜单,Selenium没有提供菜单选项的方法;
如果是自定义的右键菜单,则可以通过元素定位开操作菜单中的选项
练习
import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
# 2.创建驱动对象
driver = webdriver.Chrome()
# 3.业务操作
driver.get("file:///E:/pagetest/%E6%B3%A8%E5%86%8CA.html")
# 定位用户名输入框
element = driver.find_element(by=By.ID, value="userA")
# 执行右键点击操作
action = ActionChains(driver)
action.context_click(element).perform()
time.sleep(5)
# 关闭当前浏览器窗口 ==>执行结果,留下留下新浪网站,关闭注册页
# driver.close()
# 关闭浏览器驱动对象 ==>关闭所有窗口
driver.quit()
7.6 鼠标双击-double_click()
说明:模拟鼠标双击左键的操作
练习
7.7 鼠标拖动-drag_and_drop()
说明:
练习
7.8 鼠标悬停-move_to_elemet()
说明:
练习