软件测试/测试开发丨用户端Web自动化测试学习笔记

点此获取更多相关资料

本文为霍格沃兹测试开发学社学员学习笔记分享
原文链接:https://ceshiren.com/t/topic/24826

一、SeleniumIDE用例录制

1、SeleniumIDE的下载以及安装

  1. 官网:https://www.selenium.dev/
  2. Chrome插件:https://chrome.google.com/webstore/detail/selenium-ide/mooikfkahbdckldjjndioackbalphokd
  3. Firefox插件:https://addons.mozilla.org/en-US/firefox/addon/selenium-ide/
  4. github release:https://github.com/SeleniumHQ/selenium-ide/releases
  5. 其它版本:https://addons.mozilla.org/en-GB/firefox/addon/selenium-ide/versions/
  • 注意:Chrome插件在国内无法下载,Firefox可以直接下载。

2、启动

  1. 安装完成后,通过在浏览器的菜单栏中点击它的图标来启动它:
  2. 如果没看到图标,首先确保是否安装了Selenium IDE扩展插件
  3. 通过以下链接访问所有插件
  • Chrome: chrome://extensions
  • Firefox: about:addons

3、SeleniumIDE常用功能

  1. 新建、保存、打开
  2. 开始和停止录制
  3. 运行8中的所有的实例
  4. 运行单个实例
  5. 调试模式
  6. 调整案例的运行速度
  7. 要录制的网址
  8. 实例列表
  9. 动作、目标、值
  10. 对单条命令的解释
  11. 运行日志

软件测试/测试开发丨用户端Web自动化测试学习笔记_第1张图片

4、SeleniumIDE脚本导出:Java和Python

软件测试/测试开发丨用户端Web自动化测试学习笔记_第2张图片

软件测试/测试开发丨用户端Web自动化测试学习笔记_第3张图片

二、自动化测试用例结构分析

1、标准的用例结构(功能)

  1. 用例标题
  2. 前提条件
  3. 用例步骤
  4. 预期结果
  5. 实际结果

2、自动化用例结构及作用

【结构:自动化测试用例:作用】

  1. 用例标题:测试包、文件、类、方法名称:【用例的唯一标识】
  2. 前提条件:setup、setup_class(Pytest;BeforeEach、BeforeAll(JUnit):【测试用例前的准备动作,比如读取数据或者driver的初始化】
  3. 用例步骤:测试方法内的代码逻辑:【测试用例具体的步骤行为】
  4. 预期结果:assert 实际结果 = 预期结果:【断言,印证用例是否执行成功】
  5. 实际结果:assert 实际结果 = 预期结果:【断言,印证用例是否执行成功】
  6. 后置动作:teardown、teardown_class(Pytest);@AfterEach、@AfterAll(JUnit):【脏数据清理、关闭driver进程】

3、IDE录制脚本

  1. 脚本步骤:
  • 访问百度网站
  • 搜索框输入“霍格沃兹测试开发”
  • 点击搜索按钮
# Generated by Selenium IDE
import pytest
import time
import json
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

class Test():
  def setup_method(self, method):
    self.driver = webdriver.Chrome()
    self.vars = {}
  
  def teardown_method(self, method):
    self.driver.quit()
  
  def test_sougou(self):
    # 打开网页,设置窗口
    self.driver.get("https://www.sogou.com/")
    self.driver.set_window_size(1235, 693)
    # 输入搜索信息
    self.driver.find_element(By.ID, "query").click()
    self.driver.find_element(By.ID, "query").send_keys("霍格沃兹测试开发")
    # 点击搜索
    self.driver.find_element(By.ID, "stb").click()
    element = self.driver.find_element(By.ID, "stb")
    actions = ActionChains(self.driver)
    actions.move_to_element(element).perform()
#优化后的代码,添加断言判断用例是否成功
# Generated by Selenium IDE
import pytest
import time
import json
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities


class Test(object):
    # 前提条件,webdriver的初始化
    def setup_method(self, method):
        self.driver = webdriver.Chrome()
        self.vars = {}

    # 后置操作,关闭网站
    def teardown_method(self, method):
        self.driver.quit()

    # 测试用例步骤
    def test_sougou(self):
        # 打开网页,设置窗口
        self.driver.get("https://www.sogou.com/")
        self.driver.set_window_size(1235, 693)
        # 输入搜索信息
        self.driver.find_element(By.ID, "query").click()
        self.driver.find_element(By.ID, "query").send_keys("霍格沃兹测试开发")
        # 点击搜索
        self.driver.find_element(By.ID, "stb").click()
        element = self.driver.find_element(By.ID, "stb")
        actions = ActionChains(self.driver)
        actions.move_to_element(element).perform()
        # 问题:无法确定用例执行成功或失败
        # 解决方案:添加断言信息,判断搜索列表中,是否会有"霍格沃兹测试开发"
        res_element = self.driver.find_element(By.CSS_SELECTOR, "#sogou_vr_30000000_0 > em")
        # 获取到定位的文本信息
        # 判断实际获取到的搜索展示的列表和预期是否一致
        assert res_element.text == "霍格沃兹测试开发"

三、web 浏览器控制

  • 模拟功能测试中对浏览器的操作
操作 使用场景
get 打开浏览器 web自动化测试第一步
refresh 浏览器刷新 模拟浏览器刷新
back 浏览器退回 模拟退回步骤
maximize_window 最大化浏览器 模拟浏览器最大化
minimize_window 最小化浏览器 模拟浏览器最小化
import time
from selenium import webdriver
# 打开网页
def open_browser():
    # 实例化chromedriver
    driver = webdriver.Chrome()
    # 调用get方法时需要传递浏览器的URL
    driver.get("https://ceshiren.com/")
    # 添加等待1秒
    time.sleep(2)
    # # 刷新浏览器
    # driver.refresh()
    # # 通过get跳转到百度
    # driver.get("https://www.baidu.com/")
    # # 回退操作,退回到测试人网页
    # driver.back()
    # 最大化浏览器
    driver.maximize_window()
    time.sleep(2)
    # 最小化浏览器
    driver.minimize_window()
    time.sleep(2)

if __name__ == '__main__':
    open_browser()

四、常见控件定位方法

1、HTML铺垫

  1. 标签:尖括号,如括起来的</code>等</li> <li>属性:a=b,如href</li> <li>类属性: class</li> </ol> <pre><code class="prism language-html"><span class="token doctype"><span class="token punctuation"><!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>html</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>utf-8<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>title</span><span class="token punctuation">></span></span>测试人论坛<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>title</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>head</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>a</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://ceshiren.com/<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>link<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>链接<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>a</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>body</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>html</span><span class="token punctuation">></span></span> </code></pre> <h4>2、Selenium八大定位方式</h4> <ol> <li>selenium 常用定位方式</li> </ol> <ul> <li>格式:</li> </ul> <p><code>driver.find_element_by_定位方式(定位元素)</code></p> <p><code>driver.find_element(By.定位方式, 定位元素)</code></p> <ul> <li>示例,两种方式作用一模一样</li> <li>官方建议使用下面的方式</li> </ul> <p><code>driver.find_element_by_id("su")</code></p> <p><code>driver.find_element(By.ID, "su")</code></p> <table> <thead> <tr> <th>方式</th> <th>描述</th> </tr> </thead> <tbody> <tr> <td>class name</td> <td>class 属性对应的值</td> </tr> <tr> <td>css selector(重点)</td> <td>css 表达式</td> </tr> <tr> <td>id(重点)</td> <td>id 属性对应的值</td> </tr> <tr> <td>name(重点)</td> <td>name 属性对应的值</td> </tr> <tr> <td>link text</td> <td>查找其可见文本与搜索值匹配的锚元素</td> </tr> <tr> <td>partial link text</td> <td>查找其可见文本包含搜索值的锚元素。如果多个元素匹配,则只会选择第一个元素。</td> </tr> <tr> <td>tag name</td> <td>标签名称</td> </tr> <tr> <td>xpath(重点)</td> <td>xpath表达式</td> </tr> </tbody> </table> <ol start="2"> <li>【方式:描述】</li> </ol> <ul> <li>class name:class 属性对应的值</li> <li>css selector(重点):css 表达式 <ul> <li>格式: <code>driver.find_element(By.CSS_SELECTOR, "css表达式")</code></li> <li>复制绝对定位</li> <li>编写 css selector 表达式</li> </ul> </li> <li>id(重点):id 属性对应的值 <ul> <li>格式: <code>driver.find_element(By.ID, "ID属性对应的值")</code></li> </ul> </li> <li>name(重点):name 属性对应的值 <ul> <li>格式: <code>driver.find_element(By.NAME, "Name属性对应的值")</code></li> </ul> </li> <li>link text:查找其可见文本与搜索值匹配的锚元素 <ul> <li>格式:<code>driver.find_element(By.LINK_TEXT,"文本信息")</code></li> </ul> </li> <li>partial link text:查找其可见文本包含搜索值的锚元素。如果多个元素匹配,则只会选择第一个元素。</li> <li>tag name:标签名称</li> <li>xpath(重点):xpath表达式 <ul> <li>格式: <code>driver.find_element(By.XPATH, "xpath表达式")</code></li> <li>复制绝对定位</li> <li>编写 xpath 表达式</li> </ul> </li> </ul> <p><a href="http://img.e-com-net.com/image/info8/76a3f4f1d36246789955a190c7f9a9ca.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/76a3f4f1d36246789955a190c7f9a9ca.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第4张图片" width="650" height="407" style="border:1px solid black;"></a></p> <pre><code class="prism language-python"><span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">def</span> <span class="token function">web_locate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token comment"># 首先需要实例化driver对象,Chrome一定要加括号</span> driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 打开一个网页</span> driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/#/ui_study/frame"</span><span class="token punctuation">)</span> <span class="token comment"># 1.ID定位,第一个参数传递定位方式,第二个参数传递定位元素,调用这个方法的返回值为WebElement</span> web_element <span class="token operator">=</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"locate_id"</span><span class="token punctuation">)</span> <span class="token keyword">print</span><span class="token punctuation">(</span>web_element<span class="token punctuation">)</span> <span class="token comment"># 2.NAME定位,如果没有报错,证明元素找到了</span> <span class="token comment"># 如果报错no such element,代表元素定位可能出现错误</span> <span class="token comment"># driver.find_element(By.NAME, "locate123") # 错误示例</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>NAME<span class="token punctuation">,</span> <span class="token string">"locate"</span><span class="token punctuation">)</span> <span class="token comment"># 3.CSS选择器定位</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">"#locate_id > a > span"</span><span class="token punctuation">)</span> <span class="token comment"># 4.xpath表达式定位</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">'//*[@id="locate_id"]/a/span'</span><span class="token punctuation">)</span> <span class="token comment"># 表达式里有双引号,建议用单引号</span> <span class="token comment"># 5.Link text,通过链接文本的方式,(1)元素一定是a标签;(2)输入的元素为标签内的文本</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>LINK_TEXT<span class="token punctuation">,</span> <span class="token string">"元素定位"</span><span class="token punctuation">)</span> <span class="token comment"># 通常会带一个点击的操作,在最后面添加.click(),可加可不加</span> <span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token punctuation">:</span> web_locate<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <h2>五、强制等待与隐式等待</h2> <h4>1、为什么要添加等待</h4> <p>避免页面未渲染完成后操作,导致的报错</p> <pre><code class="prism language-python"><span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">def</span> <span class="token function">wait_sleep</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" 如果直接执行,不添加任何等待,可能会报错 """</span> driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 不加等待,可能会因为网速等原因产生报错</span> <span class="token comment"># 报错:no such element: Unable to locate element</span> <span class="token comment"># 原因:页面未加载完成,就去查找元素,此时这个元素还未加载出来</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[text()='个人中心']"</span><span class="token punctuation">)</span> <span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token punctuation">:</span> wait_sleep<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <h4>2、强制(直接)等待</h4> <ol> <li>解决方案:在报错的元素操作之前添加等待</li> <li>原理:强制等待,线程休眠一定时间。time.sleep(3)</li> </ol> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>support <span class="token keyword">import</span> expected_conditions <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>support<span class="token punctuation">.</span>wait <span class="token keyword">import</span> WebDriverWait <span class="token keyword">def</span> <span class="token function">wait_sleep</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" 如果直接执行,不添加任何等待,可能会报错 """</span> driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 不加等待,可能会因为网速等原因产生报错</span> <span class="token comment"># 报错:no such element: Unable to locate element</span> <span class="token comment"># 原因:页面未加载完成,就去查找元素,此时这个元素还未加载出来</span> <span class="token comment"># 1.强制等待,让页面渲染完成,在报错的元素操作之前添加等待,没有报错,就证明是页面渲染速度导致,有报错则是其他问题,如定位错误等</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[text()='个人中心']"</span><span class="token punctuation">)</span> <span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token punctuation">:</span> wait_sleep<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <h4>3、隐式等待</h4> <ol> <li>问题:难以确定元素加载的具体等待时间。</li> <li>解决方案:针对于寻找元素的这个动作,使用隐式等待添加配置。</li> <li>原理:设置一个等待时间,轮询查找(默认0.5秒)元素是否出现,如果没出现就抛出异常</li> </ol> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>support <span class="token keyword">import</span> expected_conditions <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>support<span class="token punctuation">.</span>wait <span class="token keyword">import</span> WebDriverWait <span class="token keyword">def</span> <span class="token function">wait_sleep</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" 如果直接执行,不添加任何等待,可能会报错 """</span> driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 不加等待,可能会因为网速等原因产生报错</span> <span class="token comment"># 报错:no such element: Unable to locate element</span> <span class="token comment"># 原因:页面未加载完成,就去查找元素,此时这个元素还未加载出来</span> <span class="token comment"># 1.强制等待,让页面渲染完成,在报错的元素操作之前添加等待,没有报错,就证明是页面渲染速度导致,有报错则是其他问题,如定位错误等</span> <span class="token comment"># time.sleep(3)</span> <span class="token comment"># 强制等待的问题:(1)不确定页面加载时间,可能会因为等待时间过长,而影响用例的执行效率;(2)不确定页面加载时间,可能会因为等待时间过短,而导致代码依然报错</span> <span class="token comment"># 2.隐式等待</span> <span class="token comment"># 设置一个最长的等待时间,轮询查找(默认0.5秒)元素是否出现,如果没出现就抛出异常</span> <span class="token comment"># 注意:(1)在代码一开始运行时就添加隐式等待的配置,隐式等待是全局生效,即在所有find_element动作之前添加该配置即可;(2)隐式等待只能解决元素查找问题,不能解决元素交互问题</span> driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[text()='个人中心']"</span><span class="token punctuation">)</span> <span class="token comment"># driver.implicitly_wait(5) # 修改隐式等待的配置</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[text()='题库']"</span><span class="token punctuation">)</span> </code></pre> <h4>4、隐式等待无法解决的问题</h4> <ol> <li>问题:元素可以找到,使用点击等操作,出现报错</li> <li>原因:</li> </ol> <ul> <li>页面元素加载是异步加载过程,通常html会先加载完成,js、css其后</li> <li>元素存在与否是由HTML决定,元素的交互是由css或者js决定</li> <li>隐式等待只关注元素能不能找到,不关注元素能否点击或者进行其他的交互</li> </ul> <ol start="3"> <li>解决方案:使用显式等待</li> </ol> <h4>5、显式等待基本使用(初级)</h4> <ol> <li>示例: <code>WebDriverWait(driver实例, 最长等待时间, 轮询时间).until(结束条件)</code></li> <li>原理:在最长等待时间内,轮询,是否满足结束条件</li> </ol> <ul> <li>在初级时期,先关注使用</li> </ul> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>support <span class="token keyword">import</span> expected_conditions <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>support<span class="token punctuation">.</span>wait <span class="token keyword">import</span> WebDriverWait <span class="token triple-quoted-string string">"""显示等待"""</span> <span class="token keyword">def</span> <span class="token function">wait_show</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/#/ui_study/frame"</span><span class="token punctuation">)</span> <span class="token comment"># driver.implicitly_wait(3) # 问题:元素可以找到,但是点击效果没有触发</span> <span class="token comment"># 显示等待,第一个参数是driver,第二个参数是最长等待时间,轮询时间可加可不加,util方法内需要结合expected_conditions或者自己封装的方法进行使用</span> <span class="token comment"># expected_conditions的参数传入都是一个元组,即多一层小括号</span> WebDriverWait<span class="token punctuation">(</span>driver<span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">.</span>until<span class="token punctuation">(</span>expected_conditions<span class="token punctuation">.</span>element_to_be_clickable<span class="token punctuation">(</span><span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"success_btn"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"success_btn"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 添加点击操作.click(),点击"消息提示"</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token punctuation">:</span> wait_show<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <h4>6、总结</h4> <ol> <li>直接等待:</li> </ol> <ul> <li>使用方式:<code>time.sleep(等待时间))</code></li> <li>原理:强制线程等待</li> <li>适用场景:调试代码,临时性添加</li> </ul> <ol start="2"> <li>隐式等待:</li> </ol> <ul> <li>使用方式:<code>driver.implicitly_wait(等待时间)</code></li> <li>原理:在时间范围内,轮询查找元素</li> <li>适用场景:解决找不到元素问题,无法解决交互问题</li> </ul> <ol start="3"> <li>显式等待:</li> </ol> <ul> <li>使用方式:<code>WebDriverWait(driver实例, 最长等待时间, 轮询时间).until(结束条件)</code></li> <li>原理:设定特定的等待条件,轮询操作</li> <li>适用场景:解决特定条件下的等待问题,比如点击等交互性行为</li> </ul> <h2>六、常见控件交互方法</h2> <h4>1、元素操作</h4> <p>点击,输入,清空</p> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">def</span> <span class="token function">element_interaction</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" 元素操作:点击、输入、清空 :return: """</span> <span class="token comment"># 1.实例化driver对象</span> driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 2.打开一个网页</span> driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.sogou.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 3.定位到输入框进行输入操作,.send_keys()</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"query"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"霍格沃滋测试开发"</span><span class="token punctuation">)</span> <span class="token comment"># 强制等待2秒</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment"># 4.对输入框进行清空操作.clear()</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"query"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>clear<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment"># 5.再次输入</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"query"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"霍格沃滋测试开发学社"</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment"># 6.点击搜索.click()</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"stb"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token punctuation">:</span> element_interaction<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <h4>2、获取元素属性信息</h4> <ol> <li>原因:定位到元素后,获取元素的文本信息,属性信息等</li> <li>目的:根据这些信息进行断言或者调试</li> </ol> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token comment"># 获取元素属性</span> <span class="token keyword">def</span> <span class="token function">element_get_attr</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token comment"># 1.实例化driver对象</span> driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 2.打开网页</span> driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/#/ui_study/iframe"</span><span class="token punctuation">)</span> <span class="token comment"># 3.定位一个元素</span> web_element <span class="token operator">=</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"locate_id"</span><span class="token punctuation">)</span> <span class="token comment"># 4.打印这个元素信息</span> <span class="token comment"># 使用debug方式查看,断点打在想看的对象的下一行</span> <span class="token comment"># print(web_element)</span> <span class="token comment"># 5.获取元素的文本信息,不是每个元素都有文本信息的</span> <span class="token keyword">print</span><span class="token punctuation">(</span>web_element<span class="token punctuation">.</span>text<span class="token punctuation">)</span> <span class="token comment"># 6.获取元素的属性信息,如 id="locate_id", title="xxx"</span> res <span class="token operator">=</span> web_element<span class="token punctuation">.</span>get_attribute<span class="token punctuation">(</span><span class="token string">"class"</span><span class="token punctuation">)</span> <span class="token keyword">print</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span> <span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token punctuation">:</span> <span class="token comment"># 获取元素属性</span> element_get_attr<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <p><a href="http://img.e-com-net.com/image/info8/a5c7161ddd1246b1be5af067eff2d7ed.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/a5c7161ddd1246b1be5af067eff2d7ed.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第5张图片" width="650" height="348" style="border:1px solid black;"></a></p> <h4>3、获取元素属性信息的方法</h4> <ol> <li>获取元素文本</li> <li>获取元素的属性(html的属性值)</li> </ol> <pre><code class="prism language-python"><span class="token comment"># 获取元素文本</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>text <span class="token comment"># 获取这个元素的name属性的值</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"id"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>get_attribute<span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span> </code></pre> <h2>七、自动化测试定位策略</h2> <h4>1、定位方式</h4> <p><a href="http://img.e-com-net.com/image/info8/53835cc63570455e9ee6b7afd1299ddf.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/53835cc63570455e9ee6b7afd1299ddf.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第6张图片" width="650" height="567" style="border:1px solid black;"></a></p> <h4>2、通用 Web 定位方式</h4> <table> <thead> <tr> <th>定位策略</th> <th>描述</th> </tr> </thead> <tbody> <tr> <td>class name</td> <td>通过 class 属性定位元素</td> </tr> <tr> <td>css selector</td> <td>通过匹配 css selector 定位元素</td> </tr> <tr> <td>id</td> <td>通过 id 属性匹配元素</td> </tr> <tr> <td>name</td> <td>通过 name 属性定位元素</td> </tr> <tr> <td>link text</td> <td>通过 text 标签中间的 text 文本定位元素</td> </tr> <tr> <td>partial link text</td> <td>通过 text 标签中间的 text 文本的部分内容定位元素</td> </tr> <tr> <td>tag name</td> <td>通过 tag 名称定位元素</td> </tr> <tr> <td>xpath</td> <td>通过 xpath 表达式匹配元素</td> </tr> </tbody> </table> <h4>3、选择定位器通用原则</h4> <ol> <li>与研发约定的属性优先(class属性: <code>[name='locate']</code>)</li> <li>身份属性 id,name(web 定位)</li> <li>复杂场景使用组合定位:</li> </ol> <ul> <li>xpath,css</li> <li>属性动态变化(id,text)</li> <li>重复元素属性(id,text,class)</li> <li>父子定位(子定位父)</li> </ul> <ol start="4"> <li>js定位</li> </ol> <h4>4、Web 弹框定位</h4> <ol> <li>场景:web 页面 alert 弹框</li> <li>解决:web 需要使用 <code>driver.switchTo().alert()</code> 处理</li> </ol> <h4>5、下拉框/日期控件定位</h4> <ol> <li>场景:</li> </ol> <ul> <li><code><input></code>标签组合的下拉框无法定位</li> <li><code><input></code>标签组合的日期控件无法定位</li> </ul> <ol start="2"> <li>解决:面对这些元素,我们可以引入JS注入技术来解决问题。</li> </ol> <h4>6、文件上传定位</h4> <ol> <li>场景:input 标签文件上传</li> <li>解决:input 标签直接使用 send_keys()方法</li> </ol> <p><a href="http://img.e-com-net.com/image/info8/9473d35055224ded8195b5e6a2ba0abf.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/9473d35055224ded8195b5e6a2ba0abf.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第7张图片" width="650" height="420" style="border:1px solid black;"></a></p> <h4>L1实战–测试人论坛搜索功能自动化测试</h4> <pre><code class="prism language-python"><span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">class</span> <span class="token class-name">TestCeshiren01</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">setup</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" 前提条件:进入测试人论坛的搜索页面 :return: """</span> <span class="token comment"># 实例化driver对象</span> self<span class="token punctuation">.</span>driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token comment"># 隐式等待</span> <span class="token comment"># 打开被测地址</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://ceshiren.com/search?expanded=true"</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">teardown</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token comment"># 每一次用例结束之后都会关闭chromedriver进程,也会关闭浏览器</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_search01</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" 测试步骤:1.输入搜索关键词;2.点击搜索按钮 :return: """</span> <span class="token comment"># 定位搜索框,并输入搜索内容,如果是动态id,使用css</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">"[placeholder=搜索]"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"appium"</span><span class="token punctuation">)</span> <span class="token comment"># 定位到搜索按钮,并点击搜索</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">".search-cta"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 断言=预期结果与实际结果对比的结果</span> <span class="token comment"># 定位实际结果,即为获取搜索结果列表的标题内容</span> web_element <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">".topic-title"</span><span class="token punctuation">)</span> <span class="token comment"># 获取文本类的实际结果断言,appium关键字是否在获取的实际结果文本之中</span> <span class="token keyword">assert</span> <span class="token string">"appium"</span> <span class="token keyword">in</span> web_element<span class="token punctuation">.</span>text </code></pre> <h2>八、高级定位-css</h2> <h4>1、css 选择器概念</h4> <ol> <li>css 选择器有自己的语法规则和表达式</li> <li>css 定位通常分为绝对定位和相对定位</li> <li>和Xpath一起常用于UI自动化测试中的元素定位</li> </ol> <h4>2、css 相对定位使用场景</h4> <ol> <li>支持web产品</li> <li>支持app端的webview</li> </ol> <h4>3、css 相对定位的优点</h4> <ol> <li>可维护性更强</li> <li>语法更加简洁</li> <li>解决各种复杂的定位场景</li> </ol> <h4>4、css 定位的调试方法</h4> <ol> <li>进入浏览器的console</li> <li>输入:<code>$("css表达式")</code>或者<code>$$("css表达式")</code>,如果表达式里有双引号,外面要单引号,如果表达式用的是单引号,外面就要用双引号,外双内单,外单内双</li> </ol> <h4>5、css基础语法</h4> <table> <thead> <tr> <th>类型</th> <th>表达式</th> </tr> </thead> <tbody> <tr> <td>标签</td> <td>标签名</td> </tr> <tr> <td>类</td> <td>. (表示class属性值)</td> </tr> <tr> <td>ID</td> <td># (表示id属性值)</td> </tr> <tr> <td>属性</td> <td>[属性名=‘属性值’]</td> </tr> </tbody> </table> <p>【类型:表达式】</p> <ol> <li>标签:标签名</li> </ol> <ul> <li><code>$("div")</code> 获取所有的div标签</li> </ul> <ol start="2"> <li>类:.表示为class属性值,如果类里面有多个值(单词),就不能直接复制,将空格改为.即可</li> </ol> <ul> <li><code>$(".logo-big")</code>等同于<code>$("[class='logo-big']")</code></li> </ul> <ol start="3"> <li>ID:#表示为id属性值</li> </ol> <ul> <li><code>$("#site-logo")</code>等同于<code>$("[id='site-logo']")</code></li> </ul> <ol start="4"> <li>属性:[属性名=‘属性值’]</li> </ol> <ul> <li><code>$("[alt='测试人社区']")</code></li> </ul> <p><a href="http://img.e-com-net.com/image/info8/c857e00e372346778a91eb63e303fa8d.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/c857e00e372346778a91eb63e303fa8d.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第8张图片" width="650" height="290" style="border:1px solid black;"></a></p> <h4>6、css关系定位</h4> <table> <thead> <tr> <th>类型</th> <th>格式</th> </tr> </thead> <tbody> <tr> <td>并集</td> <td>元素,元素</td> </tr> <tr> <td>邻近兄弟(了解即可)</td> <td>元素+元素</td> </tr> <tr> <td>兄弟(了解即可)</td> <td>元素1~元素2</td> </tr> <tr> <td>父子</td> <td>元素>元素</td> </tr> <tr> <td>后代</td> <td>元素 元素</td> </tr> </tbody> </table> <p>【类型:格式】</p> <ol> <li>并集:元素,元素<code>$("#main,#ember4")</code></li> </ol> <p><a href="http://img.e-com-net.com/image/info8/0b6d058a542445d9974292314902d63d.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/0b6d058a542445d9974292314902d63d.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第9张图片" width="650" height="226" style="border:1px solid black;"></a></p> <p><a href="http://img.e-com-net.com/image/info8/1536a996e77f4e8fb4976dfe71bd4f40.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/1536a996e77f4e8fb4976dfe71bd4f40.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第10张图片" width="650" height="306" style="border:1px solid black;"></a></p> <ol start="2"> <li>邻近兄弟(了解即可):元素+元素<br> <code>$("#ember39+#ember40")</code></li> <li>兄弟(了解即可):元素1~元素2<br> <code>$("#ember39~#ember41")</code></li> <li>父子:元素>元素<br> <code>$("#main>#ember4")</code></li> <li>后代:元素 元素<br> <code>$("#main #skip-link")</code></li> </ol> <p><a href="http://img.e-com-net.com/image/info8/fb70e4ef460f42d29ceaec8338ed99b0.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/fb70e4ef460f42d29ceaec8338ed99b0.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第11张图片" width="650" height="230" style="border:1px solid black;"></a></p> <h4>7、css 顺序关系</h4> <table> <thead> <tr> <th>类型</th> <th>格式</th> </tr> </thead> <tbody> <tr> <td>父子关系+顺序</td> <td>元素 元素</td> </tr> <tr> <td>父子关系+标签类型+顺序</td> <td>元素 元素</td> </tr> </tbody> </table> <p>【类型:格式】</p> <ol> <li>父子关系+顺序:元素 元素(父亲有多个孩子,找到第一个孩子)<br> 表达式:<code>//:nth-child(n)</code><br> <code>$("#ember15>:nth-child(3)")</code> ( #ember15为父亲,:nth-child(3)为第三个孩子)</li> <li>父子关系+标签类型+顺序:元素 元素(父亲的孩子有多个类型,想找其中一个类型里面的第一个孩子)<br> 表达式:<code>//:nth-of-type(n)</code><br> <code>$("#ember15>div:nth-of-type(1)")</code>( #ember15为父亲,:nth-of-type(1)为第三个类型div的第一个孩子)</li> </ol> <p><a href="http://img.e-com-net.com/image/info8/9302b11ec31944f9a74fe2defb3535a6.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/9302b11ec31944f9a74fe2defb3535a6.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第12张图片" width="650" height="329" style="border:1px solid black;"></a></p> <p>css表达式定位</p> <p><a href="http://img.e-com-net.com/image/info8/95660b0556f04a4fb0c42ac3ab8c0ebd.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/95660b0556f04a4fb0c42ac3ab8c0ebd.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第13张图片" width="650" height="601" style="border:1px solid black;"></a></p> <h2>九、高级定位-xpath</h2> <h4>1、xpath 基本概念</h4> <ol> <li>XPath 是一门在 XML 文档中查找信息的语言</li> <li>XPath 使用路径表达式在 XML 文档中进行导航</li> <li>XPath 的应用非常广泛</li> <li>XPath 可以应用在UI自动化测试</li> </ol> <h4>2、xpath 使用场景</h4> <ol> <li>web自动化测试</li> <li>app自动化测试</li> </ol> <h4>3、xpath 相对定位的优点</h4> <ol> <li>可维护性更强</li> <li>语法更加简洁</li> <li>相比于css可以支持更多的方式</li> </ol> <h4>4、xpath 定位的调试方法</h4> <ol> <li>浏览器-console</li> </ol> <ul> <li>$x(“xpath表达式”)</li> </ul> <ol start="2"> <li>浏览器-elements</li> </ol> <ul> <li>ctrl+f 输入xpath或者css</li> </ul> <h4>5、xpath 基础语法(包含关系)</h4> <table> <thead> <tr> <th>表达式</th> <th>结果</th> </tr> </thead> <tbody> <tr> <td>/</td> <td>从该节点的子元素选取</td> </tr> <tr> <td>//</td> <td>从该节点的子孙元素选取</td> </tr> <tr> <td>*</td> <td>通配符</td> </tr> <tr> <td>nodename</td> <td>选取此节点的所有子节点</td> </tr> <tr> <td>…</td> <td>选取当前节点的父节点</td> </tr> <tr> <td>@</td> <td>选取属性</td> </tr> </tbody> </table> <p>【表达式:结果】</p> <ol> <li>/ :从该节点的子元素选取</li> <li>// :从该节点的子孙元素选取</li> <li> <ul> <li>:通配符<br> <code>$x("//*[@id='ember61']")</code>,匹配所有的[@id=‘ember61’]<br> <code>$x("//tr[@id='ember61']")</code>,匹配tr标签下面的[@id=‘ember61’]</li> </ul> </li> <li><code>nodename</code> :选取此节点的所有子节点,相当于标签名</li> <li><code>.. </code>:选取当前节点的父节点,<br> 如<code>$x("//*[@id='ember61']/..")</code>,寻找ember61的父节点</li> </ol> <p>写法二:<code>$x("//tr[@id='ember61']")</code>,在某个标签下寻找</p> <ol start="6"> <li> <p><code>@ </code>:选取属性</p> </li> <li> <p>整个页面<br> <code>$x("/")</code></p> </li> </ol> <p><a href="http://img.e-com-net.com/image/info8/9f44ce15d26e4d76a3c4bf37f14f19aa.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/9f44ce15d26e4d76a3c4bf37f14f19aa.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第14张图片" width="650" height="707" style="border:1px solid black;"></a></p> <p>页面中的所有的子元素,匹配/下面的所有节点,相当于是html<br> <code>$x("/*")</code></p> <p><a href="http://img.e-com-net.com/image/info8/3909a9577c7f4dc0abd3852e1eff71da.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/3909a9577c7f4dc0abd3852e1eff71da.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第15张图片" width="650" height="503" style="border:1px solid black;"></a></p> <p>整个页面中的所有元素<br> <code>$x("//*")</code></p> <p><a href="http://img.e-com-net.com/image/info8/23867e8cd1f5436c8d24ec2f4edfd8b0.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/23867e8cd1f5436c8d24ec2f4edfd8b0.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第16张图片" width="650" height="624" style="border:1px solid black;"></a></p> <p>查找页面上面所有的div标签节点,标签不等于属性<br> <code>$x("//div")</code></p> <p><a href="http://img.e-com-net.com/image/info8/ec58527e0f8542828c74f2bfb3a9bfb8.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/ec58527e0f8542828c74f2bfb3a9bfb8.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第17张图片" width="650" height="681" style="border:1px solid black;"></a></p> <p>查找id属性为ember61的节点,*先匹配所有节点,再匹配某个属性<br> <code>$x('//*[@id="ember61"]')</code></p> <p><a href="http://img.e-com-net.com/image/info8/62e2ba52d531455eae4fb31f44043208.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/62e2ba52d531455eae4fb31f44043208.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第18张图片" width="650" height="219" style="border:1px solid black;"></a></p> <p>查找ember61节点的父节点</p> <p><code>$x('//*[@id="ember61"]/..')</code></p> <p><code>$x("//*[@id='ember61']/../..")</code> 再往上寻找父节点</p> <h4>6、xpath 顺序关系(索引)</h4> <pre><code class="prism language-python">xpath通过索引直接获取对应元素 <span class="token comment"># 查找tbody下的所有tr</span> $x<span class="token punctuation">(</span><span class="token string">"//tbody//tr"</span><span class="token punctuation">)</span> <span class="token comment"># 查找tbody下的第一个tr,下标从1开始</span> $x<span class="token punctuation">(</span><span class="token string">"//tbody//tr[1]"</span><span class="token punctuation">)</span> <span class="token comment"># 获取所有的tr,注意这里的tr并不是都是同一个父节点</span> $x<span class="token punctuation">(</span><span class="token string">"//tr"</span><span class="token punctuation">)</span> <span class="token comment"># 获取每个不同父节点下面的第一个tr</span> $x<span class="token punctuation">(</span><span class="token string">"//tr[1]"</span><span class="token punctuation">)</span> </code></pre> <p><a href="http://img.e-com-net.com/image/info8/0cd27b7ce4644239a0ad12af5b83c34c.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/0cd27b7ce4644239a0ad12af5b83c34c.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第19张图片" width="650" height="258" style="border:1px solid black;"></a></p> <h4>7、xpath 高级用法</h4> <pre><code>①[last()]: 选取最后一个 $x("//tr[last()]") # 获取每一个父节点下的最后一个tr $x("//tbody//tr[last()]") # 获取tbody下面的最后一个tr ②[@属性名='属性值' and @属性名='属性值']: 与关系 $x("//*[@class='topic-list-item category-bu-161-category unseen-topic ember-view' and @id='ember44']") ③[@属性名='属性值' or @属性名='属性值']: 或关系 $x("//*[@class='topic-list-item category-bu-161-category unseen-topic ember-view' or @id='ember44']") ④[text()='文本信息']: 根据文本信息定位 $x("//*[text()='赏金任务']") # text不是属性,不需要加@,是一个方法,加括号 ⑤[contains(text(),'文本信息')]: 根据文本信息包含定位;也可以contains(@id或@name等) $x("//*[contains(text(),'赏金')]") $x("//*[contains(@id,'site')]") ⑥注意:所有的表达式需要和[]结合 </code></pre> <h2>十、显式等待高级使用</h2> <h4>1、显式等待原理</h4> <ol> <li>在代码中定义等待一定条件发生后再进一步执行代码</li> <li>在最长等待时间内循环执行结束条件的函数,结合③一起查看</li> <li>源码:<code>WebDriverWait(driver 实例, 最长等待时间, 轮询时间).until(结束条件函数)</code></li> </ol> <h4>2、常见 expected_conditions</h4> <table> <thead> <tr> <th>类型</th> <th>示例方法</th> <th>说明</th> </tr> </thead> <tbody> <tr> <td>element</td> <td>element_to_be_clickable();visibility_of_element_located()</td> <td>针对于元素,比如判断元素是否可以点击,或者元素是否可见</td> </tr> <tr> <td>url</td> <td>url_contains()</td> <td>针对于 url</td> </tr> <tr> <td>title</td> <td>title_is()</td> <td>针对于标题</td> </tr> <tr> <td>frame</td> <td>frame_to_be_available_and_switch_to_it(locator)</td> <td>针对于 frame</td> </tr> <tr> <td>alert</td> <td>alert_is_present()</td> <td>针对于弹窗</td> </tr> </tbody> </table> <h4>3、封装等待条件</h4> <ol> <li>官方的 excepted_conditions 不可能覆盖所有场景,如有些按钮需要点击两次或多次才会有反应</li> <li>定制封装条件会更加灵活、可控</li> </ol> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>remote<span class="token punctuation">.</span>webdriver <span class="token keyword">import</span> WebDriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>support<span class="token punctuation">.</span>wait <span class="token keyword">import</span> WebDriverWait <span class="token keyword">class</span> <span class="token class-name">TestWebdriverWait</span><span class="token punctuation">:</span> driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>maximize_window<span class="token punctuation">(</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/#/ui_study/iframe"</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">teardown</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_webdriver_wait</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token comment"># 解决的问题:有的按钮点击一次没有反应,可能要点击多次,比如企业微信的添加成员</span> <span class="token comment"># 解决的方案:一直点击按钮,直到下个页面出现,封装成显式等待的一个条件</span> <span class="token keyword">def</span> <span class="token function">muliti_click</span><span class="token punctuation">(</span>button_element<span class="token punctuation">,</span>until_ele<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token comment"># 函数封装</span> <span class="token keyword">def</span> <span class="token function">inner</span><span class="token punctuation">(</span>driver<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token comment"># 封装点击方法</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span>button_element<span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">return</span> driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span>until_ele<span class="token punctuation">)</span> <span class="token keyword">return</span> inner time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token comment"># 在限制时间内会一直点击按钮,直到展示弹框</span> WebDriverWait<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">.</span>until<span class="token punctuation">(</span>muliti_click<span class="token punctuation">(</span><span class="token string">"//*[text()='点击两次响应']"</span><span class="token punctuation">,</span><span class="token string">"//*[text()='该弹框点击两次后才会弹出']"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> </code></pre> <h2>十一、高级控件交互方法</h2> <h4>1、使用场景</h4> <table> <thead> <tr> <th>使用场景</th> <th>对应事件</th> </tr> </thead> <tbody> <tr> <td>复制粘贴</td> <td>键盘事件</td> </tr> <tr> <td>拖动元素到某个位置</td> <td>鼠标事件</td> </tr> <tr> <td>鼠标悬停</td> <td>鼠标事件</td> </tr> <tr> <td>滚动到某个元素</td> <td>滚动事件</td> </tr> <tr> <td>使用触控笔点击</td> <td>触控笔事件(了解即可)</td> </tr> </tbody> </table> <h4>2、ActionChains解析</h4> <ol> <li>实例化类ActionChains,参数为driver实例。</li> <li>中间可以有多个操作。</li> <li>.perform()代表确定执行。</li> </ol> <h4>3、键盘事件</h4> <ol> <li>按下、释放键盘键位</li> <li>结合send_keys回车</li> <li>键盘事件-使用shift实现大写</li> </ol> <ul> <li><code>ActionChains(self.driver)</code>: 实例化ActionChains类</li> <li><code>key_down(Keys.SHIFT, ele)</code>: 按下shift键实现大写</li> <li><code>send_keys("selenium")</code>: 输入大写的selenium</li> <li><code>perform()</code>: 确认执行</li> </ul> <pre><code class="prism language-python"><span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver <span class="token keyword">import</span> ActionChains<span class="token punctuation">,</span> Keys <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">class</span> <span class="token class-name">TestKeyBoard</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">setup_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token comment"># 隐式等待3秒</span> <span class="token keyword">def</span> <span class="token function">teardown_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_shift</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" 键盘事件-使用shift实现大写 1.访问https://ceshiren.com/官方网站 2.点击搜索按钮 3.输入搜索的内容,输入的同时按着shift键 :return: """</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://ceshiren.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 点击搜索按钮</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"search-button"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 目标元素,即为输入框</span> ele <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"search-term"</span><span class="token punctuation">)</span> <span class="token comment"># key_down代表按下某个键位,.send_keys输入内容,.perform()确认执行以上操作</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span><span class="token punctuation">.</span>key_down<span class="token punctuation">(</span>Keys<span class="token punctuation">.</span>SHIFT<span class="token punctuation">,</span> ele<span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"selenium"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <ol start="4"> <li>键盘事件-输入后回车</li> </ol> <ul> <li>直接输入回车: <code>元素.send_keys(Keys.ENTER)</code></li> <li>使用ActionChains: <code>key_down(Keys.ENTER)</code></li> </ul> <pre><code class="prism language-python"><span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver <span class="token keyword">import</span> ActionChains<span class="token punctuation">,</span> Keys <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">class</span> <span class="token class-name">TestKeyBoard</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">setup_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token comment"># 隐式等待3秒</span> <span class="token keyword">def</span> <span class="token function">teardown_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_enter</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""键盘事件-输入后回车"""</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.sogou.com/"</span><span class="token punctuation">)</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"query"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"python语言"</span><span class="token punctuation">)</span> <span class="token comment"># 第一种回车方式,直接输入回车</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"query"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span>Keys<span class="token punctuation">.</span>ENTER<span class="token punctuation">)</span> <span class="token comment"># 第二种使用ActionChains,要记得加.perform()</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span><span class="token punctuation">.</span>key_down<span class="token punctuation">(</span>Keys<span class="token punctuation">.</span>ENTER<span class="token punctuation">)</span><span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <ol start="5"> <li>键盘事件-复制粘贴</li> </ol> <ul> <li>多系统兼容 <ul> <li>mac 的复制按钮为 COMMAND</li> <li>windows 的复制按钮为 CONTROL</li> </ul> </li> <li>左箭头:<code>Keys.ARROW_LEFT</code></li> <li>按下COMMAND或者CONTROL: <code>key_down(cmd_ctrl)</code></li> <li>按下剪切与粘贴按钮: <code>send_keys("xvvvvv")</code></li> </ul> <pre><code class="prism language-python"><span class="token keyword">import</span> sys <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver <span class="token keyword">import</span> ActionChains<span class="token punctuation">,</span> Keys <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">class</span> <span class="token class-name">TestKeyBoard</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">setup_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token comment"># 隐式等待3秒</span> <span class="token keyword">def</span> <span class="token function">teardown_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_copy_and_paste</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""键盘事件-复制粘贴"""</span> <span class="token comment"># 打开网页</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://ceshiren.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 点击搜索按钮</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"search-button"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 目标元素,即为输入框</span> ele <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"search-term"</span><span class="token punctuation">)</span> <span class="token comment"># 判断操作系统是否为Mac(darwin),是mac返回command键位,windows返回control键位</span> command_control <span class="token operator">=</span> Keys<span class="token punctuation">.</span>COMMAND <span class="token keyword">if</span> sys<span class="token punctuation">.</span>platform <span class="token operator">==</span> <span class="token string">"darwin"</span> <span class="token keyword">else</span> Keys<span class="token punctuation">.</span>CONTROL <span class="token comment"># .key_down(Keys.SHIFT, ele)按下shift键,.send_keys("selenium")输入大写selenium,</span> <span class="token comment"># .key_down(Keys.ARROW_LEFT)按下左箭头,.key_down(command_control)按下command或control键位,</span> <span class="token comment"># .send_keys("xvv"),x表示为剪切,多少个v表示复制多少次,.key_up(command_control)表示松开command或control键位,.perform()执行</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span>\ <span class="token punctuation">.</span>key_down<span class="token punctuation">(</span>Keys<span class="token punctuation">.</span>SHIFT<span class="token punctuation">,</span> ele<span class="token punctuation">)</span>\ <span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"selenium@"</span><span class="token punctuation">)</span>\ <span class="token punctuation">.</span>key_down<span class="token punctuation">(</span>Keys<span class="token punctuation">.</span>ARROW_LEFT<span class="token punctuation">)</span>\ <span class="token punctuation">.</span>key_down<span class="token punctuation">(</span>command_control<span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"xvvvvvv"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>key_up<span class="token punctuation">(</span>command_control<span class="token punctuation">)</span>\ <span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> </code></pre> <h4>4、鼠标事件</h4> <ol> <li>双击<br> <code>double_click(元素对象)</code>: 双击元素</li> <li>拖动元素<br> <code>drag_and_drop(起始元素对象, 结束元素对象)</code>: 拖动并放开元素</li> <li>指定位置(悬浮)<br> <code>move_to_element(元素对象)</code>: 移动到某个元素</li> </ol> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver <span class="token keyword">import</span> ActionChains<span class="token punctuation">,</span> Keys <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">class</span> <span class="token class-name">TestKeyBoard</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">setup_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token comment"># 隐式等待3秒</span> <span class="token keyword">def</span> <span class="token function">teardown_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_double_click</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""鼠标事件-双击"""</span> <span class="token comment"># 打开网页</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/#/ui_study/iframe"</span><span class="token punctuation">)</span> <span class="token comment"># 获取点击按钮</span> ele <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"primary_btn"</span><span class="token punctuation">)</span> <span class="token comment"># .double_click(ele)调用双击方法,传入双击元素,.perform()执行</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span><span class="token punctuation">.</span>double_click<span class="token punctuation">(</span>ele<span class="token punctuation">)</span><span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_drag_and_drop</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""鼠标事件-拖动元素"""</span> <span class="token comment"># 打开网页</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/#/ui_study/action_chains"</span><span class="token punctuation">)</span> <span class="token comment"># 获取需要拖动的元素,即起始元素的位置</span> item_left <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">'#item1'</span><span class="token punctuation">)</span> <span class="token comment"># #表示id标签</span> <span class="token comment"># 获取目标元素的位置</span> item_right <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">'#item3'</span><span class="token punctuation">)</span> <span class="token comment"># #表示id标签</span> <span class="token comment"># 实现拖拽操作,.drag_and_drop(item_left, item_right)</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span><span class="token punctuation">.</span>drag_and_drop<span class="token punctuation">(</span>item_left<span class="token punctuation">,</span> item_right<span class="token punctuation">)</span><span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_hover</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""鼠标事件-悬浮"""</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://vip.ceshiren.com/#/ui_study/action_chains2"</span><span class="token punctuation">)</span> <span class="token comment"># 获取下拉框位置</span> ele <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">".menu"</span><span class="token punctuation">)</span> <span class="token comment"># 鼠标悬浮在下拉框</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span><span class="token punctuation">.</span>move_to_element<span class="token punctuation">(</span>ele<span class="token punctuation">)</span><span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 选择下拉选项</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[contains(text(),'测开班')]"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> </code></pre> <h4>5、滚轮/滚动操作</h4> <ol> <li>滚动到元素<br> <code>scroll_to_element(WebElement对象)</code>:滚动到某个元素</li> <li>根据坐标滚动<br> <code>scroll_by_amount(横坐标, 纵坐标)</code></li> <li>注意: selenium 版本需要在 4.2 之后</li> </ol> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver <span class="token keyword">import</span> ActionChains <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">class</span> <span class="token class-name">TestScroll</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">setup_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span> <span class="token comment"># 隐式等待</span> <span class="token keyword">def</span> <span class="token function">teardown_class</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_scoll_to_element</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""滚轮/滚动操作-滚动到元素"""</span> <span class="token comment"># 打开网页</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://ceshiren.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 获取页面底部某个标题</span> ele <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[text()='接口测试上线标准']"</span><span class="token punctuation">)</span> <span class="token comment"># 页面滚动操作,找到"接口测试上线标准",selenium版本需要在 4.2 之后</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span><span class="token punctuation">.</span>scroll_to_element<span class="token punctuation">(</span>ele<span class="token punctuation">)</span><span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token keyword">def</span> <span class="token function">test_scroll_to_xy</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""滚轮/滚动操作-根据坐标滚动"""</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://ceshiren.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 坐标滚动方式,.scroll_by_amount(0, 10000)纵向滚动</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span><span class="token punctuation">.</span>scroll_by_amount<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">3000</span><span class="token punctuation">)</span><span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> </code></pre> <h2>十二、网页 frame 与多窗口处理</h2> <h4>1、selenium⾥⾯如何处理多窗⼜场景</h4> <ol> <li>多个窗口识别</li> <li>多个窗口之间切换</li> </ol> <h4>2、selenium⾥⾯如何处理frame</h4> <ol> <li>多个frame识别</li> <li>多个frame之间切换</li> </ol> <h4>3、多窗口处理</h4> <ol> <li>点击某些链接,会重新打开⼀个窗口,对于这种情况,想在新页⾯上操作,就得先切换窗口了。</li> <li>获取窗口的唯⼀标识⽤句柄表⽰,所以只需要切换句柄,就可以在多个页⾯灵活操作了。</li> </ol> <h4>4、多窗口处理流程</h4> <ol> <li>先获取到当前的窗口句柄(driver.current_window_handle)</li> <li>再获取到所有的窗口句柄(driver.window_handles)</li> <li>判断是否是想要操作的窗口,如果是,就可以对窗口进⾏操作,如果不是,跳转到另外⼀个窗口,对另⼀个窗口进⾏操作 (driver.switch_to_window)</li> </ol> <pre><code class="prism language-python"><span class="token triple-quoted-string string">"""base.py文件,Base类有前置和后置操作"""</span> <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token comment"># 前置和后置操作,提供测试用例调用</span> <span class="token keyword">class</span> <span class="token class-name">Base</span><span class="token punctuation">(</span><span class="token builtin">object</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token comment"># 前置操作</span> <span class="token keyword">def</span> <span class="token function">setup</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver <span class="token operator">=</span> webdriver<span class="token punctuation">.</span>Chrome<span class="token punctuation">(</span><span class="token punctuation">)</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>implicitly_wait<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token comment"># 隐式等待</span> <span class="token comment"># 后置操作</span> <span class="token keyword">def</span> <span class="token function">teardown</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>quit<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token triple-quoted-string string">"""测试用例文件test_window.py"""</span> <span class="token keyword">import</span> time <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> webui<span class="token punctuation">.</span>window_frame<span class="token punctuation">.</span>base <span class="token keyword">import</span> Base <span class="token comment"># 继承Base类,Base类里有前置和后置操作</span> <span class="token keyword">class</span> <span class="token class-name">TestWindows</span><span class="token punctuation">(</span>Base<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">test_window</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.baidu.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 找到登录按钮,并点击</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[@id='s-top-loginbtn']"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">print</span><span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>current_window_handle<span class="token punctuation">)</span> <span class="token comment"># 点击登录之后,打印当前窗口</span> <span class="token comment"># 点击弹窗里的立即注册按钮</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[text()='立即注册']"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># # 点击立即注册之后,打印当前窗口</span> <span class="token comment"># print(self.driver.current_window_handle)</span> <span class="token comment"># # 打印所有窗口的名字,列表形式,会有注册页面的窗口,</span> <span class="token comment"># print(self.driver.window_handles)</span> <span class="token comment"># 获取所有窗口列表,赋给window</span> window <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>window_handles <span class="token comment"># window[-1]获取注册页面的窗口,并切换到注册页面的窗口</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>window<span class="token punctuation">(</span>window<span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token comment"># 注册页面,输入用户名username</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"TANGRAM__PSP_4__userName"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"username"</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token comment"># 切换回最初登录页面的窗口</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>window<span class="token punctuation">(</span>window<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token comment"># # 登录页面,点击短信登录</span> <span class="token comment"># self.driver.find_element(By.XPATH, "//*[text()='短信登录']").click()</span> <span class="token comment"># 获取用户名输入框,并输入用户名</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"TANGRAM__PSP_11__userName"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"login_username"</span><span class="token punctuation">)</span> <span class="token comment"># 获取密码输入框,并输入密码</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"TANGRAM__PSP_11__password"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"login_password"</span><span class="token punctuation">)</span> <span class="token comment"># 点击登录</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"TANGRAM__PSP_11__submit"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span> </code></pre> <h4>5、frame处理</h4> <pre><code class="prism language-python"><span class="token number">1</span>)frame介绍 ①在web⾃动化中,如果⼀个元素定位不到,那么很⼤可能是在iframe中。 ②什么是frame? a<span class="token punctuation">.</span> frame是html中的框架,在html中,所谓的框架就是可以在同⼀个浏览器中显⽰不⽌⼀个页⾯。 b<span class="token punctuation">.</span> 基于html的框架,又分为垂直框架和⽔平框架(cols,rows) ③Frame 分类 a<span class="token punctuation">.</span> frame标签包含frameset、frame、iframe三种, b<span class="token punctuation">.</span> frameset和普通的标签⼀样,不会影响正常的定位,可以使⽤index、<span class="token builtin">id</span>、name 、webelement任意种⽅式定位frame。 c<span class="token punctuation">.</span> ⽽frame与iframe对selenium定位⽽⾔是⼀样的。selenium有⼀组⽅法对frame进⾏操作 <span class="token number">2</span>)多frame切换 ①frame存在两种:⼀种是嵌套的,⼀种是未嵌套的 ②切换frame ❖ driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>frame<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 根据元素id或者index切换切换frame</span> ❖ driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>default_content<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 切换到默认frame</span> ❖ driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>parent_frame<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 切换到⽗级frame</span> <span class="token number">3</span>)frame未嵌套 ①处理未嵌套的iframe ❖ driver<span class="token punctuation">.</span>switch_to_frame<span class="token punctuation">(</span>“frame 的 <span class="token builtin">id</span>”<span class="token punctuation">)</span> ❖ driver<span class="token punctuation">.</span>switch_to_frame<span class="token punctuation">(</span>“frame <span class="token operator">-</span> index”<span class="token punctuation">)</span> frame⽆ID的时候依据索引来处理,索引从<span class="token number">0</span>开始 driver<span class="token punctuation">.</span>switch_to_frame<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token number">4</span>)frame嵌套 ②处理嵌套的iframe ❖ 对于嵌套的先进⼊到iframe的⽗节点,再进到⼦节点,然后可以对⼦节点⾥⾯的对象进⾏处理和操作 ❖ driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>frame<span class="token punctuation">(</span>“⽗节点”<span class="token punctuation">)</span> ❖ driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>frame<span class="token punctuation">(</span>“⼦节点”<span class="token punctuation">)</span> </code></pre> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> webui<span class="token punctuation">.</span>window_frame<span class="token punctuation">.</span>base <span class="token keyword">import</span> Base <span class="token comment"># 继承Base类,Base类里有前置和后置操作</span> <span class="token keyword">class</span> <span class="token class-name">TestFrame</span><span class="token punctuation">(</span>Base<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">test_frame</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable"</span><span class="token punctuation">)</span> <span class="token comment"># 切换到frame中,根据frame的元素id</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>frame<span class="token punctuation">(</span><span class="token string">"iframeResult"</span><span class="token punctuation">)</span> <span class="token comment"># 写法一,常用</span> <span class="token comment"># self.driver.switch_to_frame("iframeResult") # 写法二</span> <span class="token comment"># 获取"请拖拽我!"的属性,获取文本内容</span> <span class="token keyword">print</span><span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"draggable"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>text<span class="token punctuation">)</span> <span class="token comment"># 写法一:切回网页,即不在frame页面,即切回frame父节点</span> <span class="token comment"># self.driver.switch_to.parent_frame()</span> <span class="token comment"># 写法二:切换到默认frame节点,即刚打开的地址节点</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>default_content<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 获取"点击运行"按钮,并点击</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"submitBTN"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> </code></pre> <p><a href="http://img.e-com-net.com/image/info8/6056596c1b9b45e080f903c981ccd705.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/6056596c1b9b45e080f903c981ccd705.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第20张图片" width="650" height="426" style="border:1px solid black;"></a></p> <h2>十三、文件上传弹框处理</h2> <h4>1、⽂件上传</h4> <ol> <li>input标签可以直接使⽤send_keys(⽂件地址)上传⽂件</li> <li>⽤法: <ul> <li>el = driver.find_element_by_id(‘上传按钮id’)</li> <li>el.send_keys(”⽂件路径+⽂件名")</li> </ul> </li> </ol> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> webui<span class="token punctuation">.</span>window_frame<span class="token punctuation">.</span>base <span class="token keyword">import</span> Base <span class="token comment"># 继承Base类,Base类里有前置和后置操作</span> <span class="token keyword">class</span> <span class="token class-name">TestFile</span><span class="token punctuation">(</span>Base<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">test_file_upload</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.baidu.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 找到百度的相机图标并点击</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//*[@class='soutu-btn']"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 定位到选择文件,并选择文件</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>XPATH<span class="token punctuation">,</span> <span class="token string">"//input[@class='upload-pic']"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span><span class="token string">"/Users/jiyu/PycharmProjects/pythonProject/webui/img/12.png"</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> </code></pre> <h4>2、chrome 开启 debug 模式</h4> <ol> <li>有时候登录⽅式⽐较繁琐,需要动态⼿机密码,⼆维码登录之类的。⾃动话实现⽐较⿇烦。⼿⼯登录后,不想让selenium启动⼀个新浏览器。可以使⽤chrome的debug⽅式来执⾏测试。</li> <li>启动chrome的时候需要先退出所有chrome进程。使⽤ps aux|grep chrome|grep -v 'grep’查看是否有chrome进程存在。确保没有chrome进程被启动过。</li> <li>正常启动chrome的debug模式 <ul> <li> <h2>默认macOS系统</h2> </li> </ul> <code>/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debuggingport=9222</code> <ul> <li> <h2>Windows下找到chrome.exe位置执⾏下⾯的命令</h2> </li> </ul> <code>chrome.exe --remote-debugging-port=9222</code></li> <li>启动后的提⽰信息,代表chrome运⾏正常,不要关闭⾃动打开的chrome窗口。</li> </ol> <h4>3、弹框处理机制</h4> <ol> <li>在页⾯操作中有时会遇到JavaScript所⽣成的alert、confirm以及prompt弹框,可以使⽤<code>switch_to.alert()</code>⽅法定位到。然后使⽤text/accept/dismiss/send_keys等⽅法进⾏操作。</li> <li>操作alert常⽤的⽅法: <ul> <li><code>switch_to.alert()</code>:获取当前页⾯上的警告框。</li> <li><code>text</code>:返回alert/confirm/prompt 中的⽂字信息。</li> <li><code>accept()</code>:接受现有警告框。</li> <li><code>dismiss()</code>:解散现有警告框。</li> <li><code>send_keys(keysToSend)</code>:发送⽂本⾄警告框。keysToSend:将⽂本发送⾄警告框。</li> </ul> </li> </ol> <p><a href="http://img.e-com-net.com/image/info8/a364611445b44f03b71c021cb71e2fa9.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/a364611445b44f03b71c021cb71e2fa9.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第21张图片" width="650" height="484" style="border:1px solid black;"></a></p> <pre><code class="prism language-python"><span class="token keyword">import</span> time <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver <span class="token keyword">import</span> ActionChains <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> webui<span class="token punctuation">.</span>window_frame<span class="token punctuation">.</span>base <span class="token keyword">import</span> Base <span class="token keyword">class</span> <span class="token class-name">TestAlert</span><span class="token punctuation">(</span>Base<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">test_alert</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""" ❖ 打开⽹页 https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable ❖ 操作窗⼜右侧页⾯, 将元素1拖拽到元素2 ❖ 这时候会有⼀个alert弹框,点击弹框中的’确定’ ❖ 然后再按’点击运⾏’ ❖ 关闭⽹页 :return: """</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable"</span><span class="token punctuation">)</span> <span class="token comment"># 切换到frame中,根据frame的元素id</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>frame<span class="token punctuation">(</span><span class="token string">"iframeResult"</span><span class="token punctuation">)</span> <span class="token comment"># 获取需要拖动的元素,即起始元素的位置</span> a1 <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">'#draggable'</span><span class="token punctuation">)</span> <span class="token comment"># 获取目标元素的位置</span> a2 <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">'#droppable'</span><span class="token punctuation">)</span> <span class="token comment"># 实现拖拽操作,.drag_and_drop(a1, a2):将a1拖拽到a2上,.perform()执行</span> action <span class="token operator">=</span> ActionChains<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">)</span> action<span class="token punctuation">.</span>drag_and_drop<span class="token punctuation">(</span>a1<span class="token punctuation">,</span> a2<span class="token punctuation">)</span><span class="token punctuation">.</span>perform<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment"># 强制等待2秒,查看效果</span> <span class="token comment"># 切换到alert页面,点击alert的确认按钮.accept()</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>alert<span class="token punctuation">.</span>accept<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 退出alert页面,返回到默认frame节点</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>switch_to<span class="token punctuation">.</span>default_content<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 获取"点击运行"按钮,并点击</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">'submitBTN'</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span> </code></pre> <h2>十四、自动化关键数据记录</h2> <h4>1、什么是关键数据</h4> <ol> <li>代码的执行日志</li> <li>代码执行的截图</li> <li>page source(页面源代码)</li> </ol> <h4>2、记录关键数据的作用</h4> <table> <thead> <tr> <th>内容</th> <th>作用</th> </tr> </thead> <tbody> <tr> <td>日志</td> <td>1. 记录代码的执行记录,方便复现场景;2. 可以作为bug依据</td> </tr> <tr> <td>截图</td> <td>1. 断言失败或成功截图;2.异常截图达到丰富报告的作用;3. 可以作为bug依据</td> </tr> <tr> <td>page source</td> <td>1. 协助排查报错时元素当时是否存在页面上</td> </tr> </tbody> </table> <h4>3、行为日志记录</h4> <ol> <li>日志配置</li> <li>脚本日志级别 <ul> <li>debug记录步骤信息</li> <li>info记录关键信息,比如断言等</li> </ul> </li> </ol> <pre><code class="prism language-python"><span class="token comment">#日志配置文件log_utils.py</span> <span class="token comment"># 日志配置</span> <span class="token keyword">import</span> logging <span class="token comment"># 创建logger实例</span> logger <span class="token operator">=</span> logging<span class="token punctuation">.</span>getLogger<span class="token punctuation">(</span><span class="token string">'simple_example'</span><span class="token punctuation">)</span> <span class="token comment"># 设置日志级别</span> logger<span class="token punctuation">.</span>setLevel<span class="token punctuation">(</span>logging<span class="token punctuation">.</span>DEBUG<span class="token punctuation">)</span> <span class="token comment"># 流处理器</span> ch <span class="token operator">=</span> logging<span class="token punctuation">.</span>StreamHandler<span class="token punctuation">(</span><span class="token punctuation">)</span> ch<span class="token punctuation">.</span>setLevel<span class="token punctuation">(</span>logging<span class="token punctuation">.</span>DEBUG<span class="token punctuation">)</span> <span class="token comment"># 日志打印格式</span> formatter <span class="token operator">=</span> logging<span class="token punctuation">.</span>Formatter<span class="token punctuation">(</span><span class="token string">'%(asctime)s - %(name)s - %(levelname)s - %(message)s'</span><span class="token punctuation">)</span> <span class="token comment"># 添加格式配置</span> ch<span class="token punctuation">.</span>setFormatter<span class="token punctuation">(</span>formatter<span class="token punctuation">)</span> <span class="token comment"># 添加日志配置</span> logger<span class="token punctuation">.</span>addHandler<span class="token punctuation">(</span>ch<span class="token punctuation">)</span> </code></pre> <pre><code class="prism language-python"><span class="token comment"># 测试用例脚本文件test_data_record.py</span> <span class="token comment"># 日志与脚本结合</span> <span class="token keyword">from</span> selenium <span class="token keyword">import</span> webdriver <span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> webui<span class="token punctuation">.</span>data_record<span class="token punctuation">.</span>log_utils <span class="token keyword">import</span> logger <span class="token keyword">from</span> webui<span class="token punctuation">.</span>window_frame<span class="token punctuation">.</span>base <span class="token keyword">import</span> Base <span class="token comment"># 继承Base类,Base类里有前置和后置操作</span> <span class="token keyword">class</span> <span class="token class-name">TestDataRecord</span><span class="token punctuation">(</span>Base<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">""""""</span> <span class="token keyword">def</span> <span class="token function">test_data_record</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> search_content <span class="token operator">=</span> <span class="token string">"python语言"</span> <span class="token comment"># 打开网页</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.sogou.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 定位输入框,输入内容</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"query"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span>search_content<span class="token punctuation">)</span> <span class="token comment"># 加入日志,步骤信息较多且琐碎,使用debug</span> logger<span class="token punctuation">.</span>debug<span class="token punctuation">(</span><span class="token string-interpolation"><span class="token string">f"搜索的信息为:</span><span class="token interpolation"><span class="token punctuation">{</span>search_content<span class="token punctuation">}</span></span><span class="token string">"</span></span><span class="token punctuation">)</span> <span class="token comment"># 点击搜索</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"stb"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 获取搜索结果列表的标题,对应测试结果的实际结果</span> search_result <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">"em"</span><span class="token punctuation">)</span> <span class="token comment"># 多个em的情况下,默认拿第一个</span> <span class="token comment"># 添加日志,断言使用info,级别高于debug,断言实际结果与预期结果是否一致</span> logger<span class="token punctuation">.</span>info<span class="token punctuation">(</span><span class="token string-interpolation"><span class="token string">f"实际结果为:</span><span class="token interpolation"><span class="token punctuation">{</span>search_result<span class="token punctuation">.</span>text<span class="token punctuation">}</span></span><span class="token string">,预期结果为:</span><span class="token interpolation"><span class="token punctuation">{</span>search_content<span class="token punctuation">}</span></span><span class="token string">"</span></span><span class="token punctuation">)</span> <span class="token comment"># 断言,search_result.text 获取搜索结果的文本信息,预期结果search_content</span> <span class="token keyword">assert</span> search_result<span class="token punctuation">.</span>text <span class="token operator">==</span> search_content </code></pre> <h4>4、步骤截图记录</h4> <ol> <li>save_screenshot(截图路径+名称)</li> <li>记录关键页面 <ul> <li>断言页面</li> <li>重要的业务场景页面</li> <li>容易出错的页面</li> </ul> </li> </ol> <pre><code class="prism language-python"><span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> webui<span class="token punctuation">.</span>data_record<span class="token punctuation">.</span>log_utils <span class="token keyword">import</span> logger <span class="token keyword">from</span> webui<span class="token punctuation">.</span>window_frame<span class="token punctuation">.</span>base <span class="token keyword">import</span> Base <span class="token comment"># 继承Base类,Base类里有前置和后置操作</span> <span class="token keyword">class</span> <span class="token class-name">TestDataRecord</span><span class="token punctuation">(</span>Base<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">test_screen_shot_data_record</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> search_content01 <span class="token operator">=</span> <span class="token string">"python语言"</span> <span class="token comment"># 打开网页</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.sogou.com/"</span><span class="token punctuation">)</span> <span class="token comment"># 定位输入框,输入内容</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"query"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span>search_content01<span class="token punctuation">)</span> <span class="token comment"># 加入日志,步骤信息较多且琐碎,使用debug</span> logger<span class="token punctuation">.</span>debug<span class="token punctuation">(</span><span class="token string-interpolation"><span class="token string">f"搜索的信息为:</span><span class="token interpolation"><span class="token punctuation">{</span>search_content01<span class="token punctuation">}</span></span><span class="token string">"</span></span><span class="token punctuation">)</span> <span class="token comment"># 点击搜索</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"stb"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>click<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># 获取搜索结果列表的标题,对应测试结果的实际结果</span> search_result01 <span class="token operator">=</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>CSS_SELECTOR<span class="token punctuation">,</span> <span class="token string">"em"</span><span class="token punctuation">)</span> <span class="token comment"># 多个em的情况下,默认拿第一个</span> <span class="token comment"># 添加日志,断言使用info,级别高于debug,断言实际结果与预期结果是否一致</span> logger<span class="token punctuation">.</span>info<span class="token punctuation">(</span><span class="token string-interpolation"><span class="token string">f"实际结果为:</span><span class="token interpolation"><span class="token punctuation">{</span>search_result01<span class="token punctuation">.</span>text<span class="token punctuation">}</span></span><span class="token string">,预期结果为:</span><span class="token interpolation"><span class="token punctuation">{</span>search_content01<span class="token punctuation">}</span></span><span class="token string">"</span></span><span class="token punctuation">)</span> <span class="token comment"># 截图记录,双重保障</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>save_screenshot<span class="token punctuation">(</span><span class="token string">"search_result01.png"</span><span class="token punctuation">)</span> <span class="token comment"># 断言,search_result01.text 获取搜索结果的文本信息,预期结果search_content01</span> <span class="token keyword">assert</span> search_result01<span class="token punctuation">.</span>text <span class="token operator">==</span> search_content01 </code></pre> <h4>5、page source记录</h4> <ol> <li>使用page_source属性获取页面源码</li> <li>在调试过程中,如果有找不到元素的错误可以保存当时的page_source调试代码</li> </ol> <pre><code class="prism language-python"><span class="token keyword">from</span> selenium<span class="token punctuation">.</span>webdriver<span class="token punctuation">.</span>common<span class="token punctuation">.</span>by <span class="token keyword">import</span> By <span class="token keyword">from</span> webui<span class="token punctuation">.</span>window_frame<span class="token punctuation">.</span>base <span class="token keyword">import</span> Base <span class="token comment"># 继承Base类,Base类里有前置和后置操作</span> <span class="token keyword">class</span> <span class="token class-name">TestDataRecord</span><span class="token punctuation">(</span>Base<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">test_page_source_data_record</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token triple-quoted-string string">"""获取page_source主要用于调试,可以不需要断言等其余信息"""</span> <span class="token comment"># 现象:产生了no such element的错误</span> <span class="token comment"># 方案:在报错的代码行之前打印page_source,确认定位的元素没有问题</span> content <span class="token operator">=</span> <span class="token string">"python语言"</span> <span class="token comment"># 打开网页</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">"https://www.sogou.com/"</span><span class="token punctuation">)</span> <span class="token comment"># # 定位输入框,输入内容</span> <span class="token comment"># self.driver.find_element(By.ID, "query").send_keys(content)</span> <span class="token comment"># 获取page_source,即获取的是这个网页的源代码</span> <span class="token comment"># logger.debug(self.driver.page_source) # 可以使用debug查看输出的内容</span> <span class="token comment"># 将获取的page_source写入到record.html</span> <span class="token keyword">with</span> <span class="token builtin">open</span><span class="token punctuation">(</span><span class="token string">"record.html"</span><span class="token punctuation">,</span> <span class="token string">"w"</span><span class="token punctuation">,</span> encoding<span class="token operator">=</span><span class="token string">"utf-8"</span><span class="token punctuation">)</span> <span class="token keyword">as</span> f<span class="token punctuation">:</span> f<span class="token punctuation">.</span>write<span class="token punctuation">(</span>self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>page_source<span class="token punctuation">)</span> <span class="token comment"># 错误定位输入框</span> self<span class="token punctuation">.</span>driver<span class="token punctuation">.</span>find_element<span class="token punctuation">(</span>By<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"query1"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>send_keys<span class="token punctuation">(</span>content<span class="token punctuation">)</span> </code></pre> <p><a href="http://img.e-com-net.com/image/info8/a2b2c0fd5d3a4c8bb38caac950f6af8b.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/a2b2c0fd5d3a4c8bb38caac950f6af8b.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第22张图片" width="650" height="410" style="border:1px solid black;"></a></p> <p><a href="http://img.e-com-net.com/image/info8/e9657571012b4fbf9bda1a345dd1bab6.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/e9657571012b4fbf9bda1a345dd1bab6.jpg" alt="软件测试/测试开发丨用户端Web自动化测试学习笔记_第23张图片" width="650" height="445" style="border:1px solid black;"></a></p> <h2>点此获取更多相关资料</h2> </div> </div> </div> </div> </div> <!--PC和WAP自适应版--> <div id="SOHUCS" sid="1722195640198443008"></div> <script type="text/javascript" src="/views/front/js/chanyan.js"></script> <!-- 文章页-底部 动态广告位 --> <div class="youdao-fixed-ad" id="detail_ad_bottom"></div> </div> <div class="col-md-3"> <div class="row" id="ad"> <!-- 文章页-右侧1 动态广告位 --> <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_1"> </div> </div> <!-- 文章页-右侧2 动态广告位 --> <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_2"></div> </div> <!-- 文章页-右侧3 动态广告位 --> <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_3"></div> </div> </div> </div> </div> </div> </div> <div class="container"> <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(学习,笔记,软件测试,自动化测试,python)</h4> <div id="paradigm-article-related"> <div class="recommend-post mb30"> <ul class="widget-links"> <li><a href="/article/1950233451282100224.htm" title="python 读excel每行替换_Python脚本操作Excel实现批量替换功能" target="_blank">python 读excel每行替换_Python脚本操作Excel实现批量替换功能</a> <span class="text-muted">weixin_39646695</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E8%AF%BBexcel%E6%AF%8F%E8%A1%8C%E6%9B%BF%E6%8D%A2/1.htm">读excel每行替换</a> <div>Python脚本操作Excel实现批量替换功能大家好,给大家分享下如何使用Python脚本操作Excel实现批量替换。使用的工具Openpyxl,一个处理excel的python库,处理excel,其实针对的就是WorkBook,Sheet,Cell这三个最根本的元素~明确需求原始excel如下我们的目标是把下面excel工作表的sheet1表页A列的内容“替换我吧”批量替换为B列的“我用来替换的</div> </li> <li><a href="/article/1950233199242178560.htm" title="x86-64汇编语言训练程序与实战" target="_blank">x86-64汇编语言训练程序与实战</a> <span class="text-muted">十除以十等于一</span> <div>本文还有配套的精品资源,点击获取简介:汇编语言是一种低级语言,与机器代码紧密相关,特别适用于编写系统级代码及性能要求高的应用。nasm编译器是针对x86和x86-64架构的汇编语言编译器,支持多种语法风格和指令集。项目Euler提供数学和计算机科学问题,鼓励编程技巧应用,前100个问题的答案可共享。x86-64架构扩展了寄存器数量并引入新指令,提升了数据处理效率。学习汇编语言能够深入理解计算机底层</div> </li> <li><a href="/article/1950233072825856000.htm" title="三菱PLC全套学习资料及应用手册" target="_blank">三菱PLC全套学习资料及应用手册</a> <span class="text-muted">good2know</span> <div>本文还有配套的精品资源,点击获取简介:三菱PLC作为工业自动化领域的核心设备,其系列产品的学习和应用需要全面深入的知识。本次资料包为学习者提供从基础到进阶的全方位学习资源,包括各种型号PLC的操作手册、编程指南、软件操作教程以及实际案例分析,旨在帮助用户系统掌握PLC的编程语言、指令系统及在各类工业应用中的实施。1.三菱PLC基础知识入门1.1PLC的基本概念可编程逻辑控制器(PLC)是工业自动化</div> </li> <li><a href="/article/1950232782412247040.htm" title="日更006 终极训练营day3" target="_blank">日更006 终极训练营day3</a> <span class="text-muted">懒cici</span> <div>人生创业课(2)今天的主题:学习方法一:遇到有用的书,反复读,然后结合自身实际,列践行清单,不要再写读书笔记思考这本书与我有什么关系,我在哪些地方能用到,之后我该怎么用方法二:读完书没映像怎么办?训练你的大脑,方法:每读完一遍书,立马合上书,做一场分享,几分钟都行对自己的学习要求太低,要逼自己方法三:学习深度不够怎么办?找到细分领域的榜样,把他们的文章、书籍、产品都体验一遍,成为他们的超级用户,向</div> </li> <li><a href="/article/1950232190038110208.htm" title="day15|前端框架学习和算法" target="_blank">day15|前端框架学习和算法</a> <span class="text-muted">universe_01</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a> <div>T22括号生成先把所有情况都画出来,然后(在满足什么情况下)把不符合条件的删除。T78子集要画树状图,把思路清晰。可以用暴力法、回溯法和DFS做这个题DFS深度搜索:每个边都走完,再回溯应用:二叉树搜索,图搜索回溯算法=DFS+剪枝T200岛屿数量(非常经典BFS宽度把树状转化成队列形式,lambda匿名函数“一次性的小函数,没有名字”setup语法糖:让代码更简洁好写的语法ref创建:基本类型的</div> </li> <li><a href="/article/1950231381485350912.htm" title="《极简思维》第三部分" target="_blank">《极简思维》第三部分</a> <span class="text-muted">小洋苏兮</span> <div>整理你的人际关系如何改善人际关系?摘录:因为人际关系问题是人们生活中不快乐的主要原因。感想:感觉这个说的挺对,之前我总是埋头学习,不管舍友不管自己的合作伙伴的一些事情,但实际上,这学期关注了之后好多了摘录:“亲密关系与社交会让你健康而快乐。这是基础。太过于关注成就或不太关心人际关系的人都不怎么快乐。基本上来说,人类就是建立在人脉关系上的。”感想:但是如果有时想的太多就不太好,要以一个开放的心态跟别</div> </li> <li><a href="/article/1950230873060208640.htm" title="你要记住,最重要的是:随时做好准备,为了你可能成为更好的自己,放弃现在的自己。" target="_blank">你要记住,最重要的是:随时做好准备,为了你可能成为更好的自己,放弃现在的自己。</a> <span class="text-muted">霖霖z</span> <div>打卡人:周云日期:2018年11月09日【日精进打卡第180天】【知~学习】《六项精进》0遍共214遍《通篇》1遍共106遍《大学》2遍共347遍《坚强工作,温柔生活》ok《不抱怨的世界》104-108页《经典名句》你要记住,最重要的是:随时做好准备,为了你可能成为更好的自己,放弃现在的自己。【行~实践】一、修身:(对自己个人)1、坚持打卡二、齐家:(对家庭和家人)打扫卫生,接送孩子,洗衣做饭,陪</div> </li> <li><a href="/article/1950229986984128512.htm" title="贫穷家庭的孩子考上985以后会怎样?" target="_blank">贫穷家庭的孩子考上985以后会怎样?</a> <span class="text-muted">Mellisa蜜思言</span> <div>我出生在一个贫穷的农村家庭,据我妈说,我出生的时候才4斤多,而她生完我以后月子里就瘦到70斤。家里一直很穷,父母都是在菜市场卖菜的,家里还有几亩地种庄稼的。我很小开始就要去帮忙,暑假的生活就是帮忙去卖菜和割稻谷,那时候自己对于割稻谷这种事情有着莫名的恐惧,生怕自己长大以后还是每年都要过着割稻谷这种日子。父母因为忙于生计无暇顾及我的学习,幸好我因为看到他们这样子的生活,内心里有深深的恐惧感,驱使着我</div> </li> <li><a href="/article/1950227573938122752.htm" title="2019-06-05" target="_blank">2019-06-05</a> <span class="text-muted">第十七把巴鲁克</span> <div>今天去实验田里实习,见到了福寿螺真的可怕且牛皮,六级也快来了,说实话还是害怕。我昨天考了环工原理,真的太难了,太烦了,理工科真的难,烦。实验报告还是没写,要抓紧速度抓紧时间,还是应该学会努力学习,远离一些不上进的事物。</div> </li> <li><a href="/article/1950223878005518336.htm" title="为什么焦虑、抑郁、自残的青少年越来越多?" target="_blank">为什么焦虑、抑郁、自残的青少年越来越多?</a> <span class="text-muted">精神健康</span> <div>很多家长觉得没缺孩子吃的穿的,他们有安稳的生活,他们有什么可焦虑、抑郁的,但现在的孩子,学习压力越来越大,每天休息的时间越来越少,出现焦虑抑郁是很正常的。从发展的角度看,青少年时期,人的身体、情绪,智力、人格都急剧发展,正从未成熟走向成熟,情绪起伏不定,易冲动,再者,由于缺乏生活经验,以及来自于家长、学校、社会的各种要求和压力,从而不知所措,心中的焦虑、恐惧、彷徨得不到及时的排解,从而导致心理上的</div> </li> <li><a href="/article/1950222857124507648.htm" title="读书打卡《别想太多啦》" target="_blank">读书打卡《别想太多啦》</a> <span class="text-muted">chenchen_68ed</span> <div>第一,世间之事,不去尝试永远不知道其中的奥秘,在尝试中有失败是必然的。如果担心失败,那什么都学不会。第二,经历的失败越多,越会对失败者抱有宽容的态度,“原来如此,我也经历过类似的失败啦,那只是暂时的”。经历越多失败的长者,越能包容别人,这也就是所谓的“越年长越宽容”。成熟的人,就是在众多失败经历中不断学习,并接纳别人的失败。对于他人的小小过失不吹毛求疵,自己的心态会更加平和。在不断失败中学习,让自</div> </li> <li><a href="/article/1950222602781913088.htm" title="2023-01-26" target="_blank">2023-01-26</a> <span class="text-muted">胡喜平</span> <div>我觉得《可见的学习》一书确实从底层逻辑说清楚了,教学的本质。可是太多术语和概念,一时间难以消化啊。而且知道和懂得有距离,运用就更不行了,需要高手和专家的指导。我需要多听听新课标的讲座了,来反复印证。读论文也有了一点点灵感,明天修改我的论文。</div> </li> <li><a href="/article/1950221204333850624.htm" title="平静得接受自己的笨拙 20190118 晨间日记" target="_blank">平静得接受自己的笨拙 20190118 晨间日记</a> <span class="text-muted">吴伯符</span> <div>图片发自App最近做了一个关于微习惯的分享,这里有八个字:微量开始,超额完成。这里的言下之意其实是要你在一开始的时候,平静地接受自己的笨拙。接受自己的笨拙,理解自己的笨拙,放慢速度尝试,观察哪里可以改进,再反复练习,观察自己哪里可以再进一步改进,再反复…这是学习一切技能的必须的过程。这里的两个关键点是:1.尽快的开始这个过程,这就能够用到微习惯的微量开始。2.尽快的度过这个过程,这就需要用到超额完</div> </li> <li><a href="/article/1950220179610857472.htm" title="【花了N长时间读《过犹不及》,不断练习,可以越通透】" target="_blank">【花了N长时间读《过犹不及》,不断练习,可以越通透】</a> <span class="text-muted">君君Love</span> <div>我已经记不清花了多长时间去读《过犹不及》,读书笔记都写了42页,这算是读得特别精细的了。是一本难得的好书,虽然书中很多内容和圣经吻合,我不是基督徒,却觉得这样的文字值得细细品味,和我们的生活息息相关。我是个界线建立不牢固的人,常常愧疚,常常害怕他人的愤怒,常常不懂拒绝,还有很多时候表达不了自己真实的感受,心里在说不嘴里却在说好……这本书给我很多的启示,让我学会了怎样去建立属于自己的清晰的界限。建立</div> </li> <li><a href="/article/1950219924043526144.htm" title="二十四节气组诗 谷雨" target="_blank">二十四节气组诗 谷雨</a> <span class="text-muted">离陌_6639</span> <div>图片来源网络,若侵犯了你的权益,请联系我删除6.谷雨文/离陌背上行囊背上如行囊的我从此任行程马不停蹄今天家乡的田野春雨快马加鞭播下希望的种子观音不语目送着我和夏天一道在观音山出关图片来源网络,若侵犯了你的权益,请联系我删除你好啊,我是离陌,已然在懵懂中走过了16年的岁月,为了珍惜当下的每一秒,所以立志做一名终身学习者。文学对于我来说是一种信仰,诗歌是我的生命。人生之道,四通八达,即入文学,自当持之</div> </li> <li><a href="/article/1950219036667211776.htm" title="你好,2020年" target="_blank">你好,2020年</a> <span class="text-muted">瑄瑄妍妍的妈咪</span> <div>早上好,今天是2020年的第一天,也就是元旦,新年新的一天开始了。新的开始,重新规划未来的一年。从今天开始,用了一个新的记账软件,之前的随手记软件,也没有删除,只是重新下载了一个别的软件,开始一个新的记账旅程,对于理财开支,有个新的规划。通过小红书视频软件,学习了不少育儿知识,和各种不同的美食,以后动手制作,给宝宝做健康美味的营养餐。学习方面,继续学英语吧!虽然是抽出时间学的,进度也比较慢,但是积</div> </li> <li><a href="/article/1950218819616174080.htm" title="基于redis的Zset实现作者的轻量级排名" target="_blank">基于redis的Zset实现作者的轻量级排名</a> <span class="text-muted">周童學</span> <a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/%E7%BC%93%E5%AD%98/1.htm">缓存</a> <div>基于redis的Zset实现轻量级作者排名系统在今天的技术架构中,Redis是一种广泛使用的内存数据存储系统,尤其在需要高效检索和排序的场景中表现优异。在本篇博客中,我们将深入探讨如何使用Redis的有序集合(ZSet)构建一个高效的笔记排行榜系统,并提供相关代码示例和详细的解析。1.功能背景与需求假设我们有一个笔记分享平台,用户可以发布各种笔记,系统需要根据用户发布的笔记数量来生成一个实时更新的</div> </li> <li><a href="/article/1950216170401492992.htm" title="常规笔记本和加固笔记本的区别" target="_blank">常规笔记本和加固笔记本的区别</a> <span class="text-muted">luchengtech</span> <a class="tag" taget="_blank" href="/search/%E7%94%B5%E8%84%91/1.htm">电脑</a><a class="tag" taget="_blank" href="/search/%E4%B8%89%E9%98%B2%E7%AC%94%E8%AE%B0%E6%9C%AC/1.htm">三防笔记本</a><a class="tag" taget="_blank" href="/search/%E5%8A%A0%E5%9B%BA%E8%AE%A1%E7%AE%97%E6%9C%BA/1.htm">加固计算机</a><a class="tag" taget="_blank" href="/search/%E5%8A%A0%E5%9B%BA%E7%AC%94%E8%AE%B0%E6%9C%AC/1.htm">加固笔记本</a> <div>在现代科技产品中,笔记本电脑因其便携性和功能性被广泛应用。根据使用场景和需求的不同,笔记本可分为常规笔记本和加固笔记本,二者在多个方面存在显著区别。适用场景是区分二者的重要标志。常规笔记本主要面向普通消费者和办公人群,适用于家庭娱乐、日常办公、学生学习等相对稳定的室内环境。比如,人们在家用它追剧、处理文档,学生在教室用它完成作业。而加固笔记本则专为特殊行业设计,像军事、野外勘探、工业制造、交通运输</div> </li> <li><a href="/article/1950215728720310272.htm" title="《云襄传》:云襄做的局是浑水摸鱼吗?" target="_blank">《云襄传》:云襄做的局是浑水摸鱼吗?</a> <span class="text-muted">书生号贺</span> <div>云襄入南都是要浑水摸鱼吗?他是云台的高材生吗?他为啥笃定师父一定会让他留在南都?他为啥觉得他能够做局成功?他是在经商吗?还是在经营人心与欲望?云襄是云台弟子,云台属千门的一支,另一支叫凌渊,云台教人经商之道,重智慧,凌渊以武力取胜,但倍受打压。云襄学习十五年,下高山奔越州,途经南洋,因恩人闻聪被害,囚于白驹镇,念于情分,被卷入这样一个局面里,结识了舒亚南与金十两,于是,复仇小组成立,目标是南都漕帮</div> </li> <li><a href="/article/1950214458265628672.htm" title="心力践行营十二期一阶学习打卡" target="_blank">心力践行营十二期一阶学习打卡</a> <span class="text-muted">LX_王彤彤</span> <div>姓名:王彤彤时间:2021年4月24日一:朗读师父的十大人生哲学二:师父的早安分享感悟很喜欢这句话:所有的行动都是基于目标的尝试,没有所谓的失败,只是不同尝试后得到的不同结果,让我们更好地调整下一次的行动。三:感恩日记1.我太幸福了,我很感恩姑姑,因为姑姑放假又投喂了我,还给我带了饺子回家,这让我感觉很幸福。谢谢,谢谢,谢谢。2.我太幸福了,我很感恩师父晚上的直播,因为听他的分享我知道怎么更好的去</div> </li> <li><a href="/article/1950214205252628480.htm" title="为了在未来的人工智能世界中取得成功,学生们必须学习人类写作的优点" target="_blank">为了在未来的人工智能世界中取得成功,学生们必须学习人类写作的优点</a> <span class="text-muted">睿邸管家</span> <div>澳大利亚各地的学生在新学年开始使用铅笔、钢笔和键盘学习写字。在工作场所,机器也在学习写作,如此有效,几年之内,它们可能会写得比人类更好。有时它们已经做到了,就像Grammarly这样的应用程序所展示的那样。当然,人类现在的日常写作可能很快就会由具有人工智能(AI)的机器来完成。手机和电子邮件软件常用的预测文本是无数人每天都在使用的一种人工智能写作形式。据AI行业研究机构称,到2022年,人工智能及</div> </li> <li><a href="/article/1950213434863841280.htm" title="闭组进行时..." target="_blank">闭组进行时...</a> <span class="text-muted">李亚青_强化班</span> <div>今天是2019年12月1号距离开始三月学习的日子:2019年10月07,已经过去将近两个月,回顾这一阶段的学习,收获了什么?又学会了什么呢?图片发自App我想,收获最大的就是身边这一群人吧,有和蔼可亲的学姐,贴心的学长,嬉戏打闹,玩的不亦乐乎,但也同样认真踏实学习小伙伴图片发自App本以为在这样的时刻,有太多太多话,太多太多想法想要表达,可言到此处,又觉得似乎没有什么想要说的了还是那句话,幸运遇到</div> </li> <li><a href="/article/1950213052171350016.htm" title="2021-10-23" target="_blank">2021-10-23</a> <span class="text-muted">赵甄文的幸福</span> <div>秀荣感恩日记Day42[烟花]感恩语录感恩自己有能力有好身体,可以到处走动,做自己想做的事情10.23感恩日记今天做的事情瑜伽一小时户外散步一小时泡脚20分钟学习打卡和孩子沟通[爱心]感动的瞬间今天瑜伽回来,发现老公在厨房里做鱼。每次老公有时间休息的时候都会给我做硬菜。刘姐约我一起去公园散步晒太阳。虽然完美错过,但心里还是暖暖的。每天睁开眼打开手机,先去自己的群里逛一逛,每每发现有人点赞或者互动都</div> </li> <li><a href="/article/1950212797946195968.htm" title="孤独的守候" target="_blank">孤独的守候</a> <span class="text-muted">怒吼的生命</span> <div>孤独了时光岁月了寂寞带来了惆怅那些孤独的日子里我们珍惜奋斗起来品味人生的真谛做到更好奋斗当中的你是那么努力格外自律学习起来五彩斑斓那些日子时光匆匆人生的机会很多需要把握痛苦的回忆记得住那些忧愁孤苦五一的日子寂寞当中的你时光荏苒独自带给我荒草学习起来努力奋斗可是我们做的还不够把握发展生活带给我们更多希望静静的述说你的故事你的精彩人生当中我们总是努力把握生活带给我们更多的学习生活当中我们奋斗可是做的还</div> </li> <li><a href="/article/1950210374787723264.htm" title="第八课: 写作出版你最关心的出书流程和市场分析(无戒学堂复盘)" target="_blank">第八课: 写作出版你最关心的出书流程和市场分析(无戒学堂复盘)</a> <span class="text-muted">人在陌上</span> <div>今天是周六,恰是圣诞节。推掉了两个需要凑腿的牌局,在一个手机,一个笔记本,一台电脑,一杯热茶的陪伴下,一个人静静地回听无戒学堂的最后一堂课。感谢这一个月,让自己的习惯开始改变,至少,可以静坐一个下午而不觉得乏味枯燥难受了,要为自己点个赞。我深知,这最后一堂课的内容,以我的资质和毅力,可能永远都用不上。但很明显,无戒学堂是用了心的,毕竟,有很多优秀学员,已经具备了写作能力,马上就要用到这堂课的内容。</div> </li> <li><a href="/article/1950209368356089856.htm" title="AI模型训练中过拟合和欠拟合的区别是什么?" target="_blank">AI模型训练中过拟合和欠拟合的区别是什么?</a> <span class="text-muted">workflower</span> <a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a> <div>在AI模型训练中,过拟合和欠拟合是两种常见的模型性能问题,核心区别在于模型对数据的学习程度和泛化能力:欠拟合(Underfitting)-定义:模型未能充分学习到数据中的规律,对训练数据的拟合程度较差,在训练集和测试集上的表现都不好(如准确率低、损失值高)。-原因:-模型结构过于简单(如用线性模型解决非线性问题);-训练数据量不足或特征信息不充分;-训练时间太短,模型尚未学到有效模式。-表现:训练</div> </li> <li><a href="/article/1950208983868436480.htm" title="2018-08-29精进打卡" target="_blank">2018-08-29精进打卡</a> <span class="text-muted">米兰王</span> <div>姓名:王兰英【日精进打卡第25天】【知~学习】《六项精进》1遍共39遍《大学》1遍共50遍【经典名句分享】一切都是最好的安排。【行~实践】一、修身:(对自己个人)1,散步1小时。2,每天坚持读书。二、齐家:(对家庭和家人)1,指导孩子开车。2,和家人一起逛超市。三、建功:(对工作)用心做好每件事。{积善}:发愿从2018年8月5日起1年内365个善事。今日1善,累计27善。【省~觉悟】正人先正己。</div> </li> <li><a href="/article/1950208107430866944.htm" title="python笔记14介绍几个魔法方法" target="_blank">python笔记14介绍几个魔法方法</a> <span class="text-muted">抢公主的大魔王</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a> <div>python笔记14介绍几个魔法方法先声明一下各位大佬,这是我的笔记。如有错误,恳请指正。另外,感谢您的观看,谢谢啦!(1).__doc__输出对应的函数,类的说明文档print(print.__doc__)print(value,...,sep='',end='\n',file=sys.stdout,flush=False)Printsthevaluestoastream,ortosys.std</div> </li> <li><a href="/article/1950207203017289728.htm" title="陶勇:要不要参加分班考试学习?看完再说。" target="_blank">陶勇:要不要参加分班考试学习?看完再说。</a> <span class="text-muted">陶勇</span> <div>每年到了升学季,有很多培训机构都特别忙,为什么呢?因为有成千上万的学生,会选择升学前的分班考试的培训。比如说,小升初的孩子,到了暑假,很多孩子都会去选择一个初中,初一的分班考试的培训,那考入高中的孩子也有很多孩子会选择这种新高一的分班考试的培训。当然了,我个人认为这种选择并不是孩子自身的选择,主要还是家长的选择。当然也有少数孩子会对自己有比较高的要求,他们也会主动的去选择。为什么要去上分班考试的这</div> </li> <li><a href="/article/1950205034075582464.htm" title="《感官品牌》读书笔记 1" target="_blank">《感官品牌》读书笔记 1</a> <span class="text-muted">西红柿阿达</span> <div>原文:最近我在东京街头闲逛时,与一位女士擦肩而过,我发现她的香水味似曾相识。“哗”的一下,记亿和情感立刻像潮水般涌了出来。这个香水味把我带回了15年前上高中的时候,我的一位亲密好友也是用这款香水。一瞬间,我呆站在那里,东京的街景逐渐淡出,取而代之的是我年少时的丹麦以及喜悦、悲伤、恐惧、困惑的记忆。我被这熟悉的香水味征服了。感想:感官是有记忆的,你所听到,看到,闻到过的有代表性的事件都会在大脑中深深</div> </li> <li><a href="/article/60.htm" title="Dom" target="_blank">Dom</a> <span class="text-muted">周华华</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/html/1.htm">html</a> <div><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml&q</div> </li> <li><a href="/article/187.htm" title="【Spark九十六】RDD API之combineByKey" target="_blank">【Spark九十六】RDD API之combineByKey</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/spark/1.htm">spark</a> <div>1. combineByKey函数的运行机制   RDD提供了很多针对元素类型为(K,V)的API,这些API封装在PairRDDFunctions类中,通过Scala隐式转换使用。这些API实现上是借助于combineByKey实现的。combineByKey函数本身也是RDD开放给Spark开发人员使用的API之一   首先看一下combineByKey的方法说明:</div> </li> <li><a href="/article/314.htm" title="msyql设置密码报错:ERROR 1372 (HY000): 解决方法详解" target="_blank">msyql设置密码报错:ERROR 1372 (HY000): 解决方法详解</a> <span class="text-muted">daizj</span> <a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a><a class="tag" taget="_blank" href="/search/%E8%AE%BE%E7%BD%AE%E5%AF%86%E7%A0%81/1.htm">设置密码</a> <div>MySql给用户设置权限同时指定访问密码时,会提示如下错误: ERROR 1372 (HY000): Password hash should be a 41-digit hexadecimal number;   问题原因:你输入的密码是明文。不允许这么输入。   解决办法:用select password('你想输入的密码');查询出你的密码对应的字符串, 然后</div> </li> <li><a href="/article/441.htm" title="路漫漫其修远兮 吾将上下而求索" target="_blank">路漫漫其修远兮 吾将上下而求索</a> <span class="text-muted">周凡杨</span> <a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0+%E6%80%9D%E7%B4%A2/1.htm">学习 思索</a> <div>王国维在他的《人间词话》中曾经概括了为学的三种境界古今之成大事业、大学问者,罔不经过三种之境界。“昨夜西风凋碧树。独上高楼,望尽天涯路。”此第一境界也。“衣带渐宽终不悔,为伊消得人憔悴。”此第二境界也。“众里寻他千百度,蓦然回首,那人却在灯火阑珊处。”此第三境界也。学习技术,这也是你必须经历的三种境界。第一层境界是说,学习的路是漫漫的,你必须做好充分的思想准备,如果半途而废还不如不要开始。这里,注</div> </li> <li><a href="/article/568.htm" title="Hadoop(二)对话单的操作" target="_blank">Hadoop(二)对话单的操作</a> <span class="text-muted">朱辉辉33</span> <a class="tag" taget="_blank" href="/search/hadoop/1.htm">hadoop</a> <div>Debug: 1、 A = LOAD '/user/hue/task.txt' USING PigStorage(' ') AS (col1,col2,col3); DUMP A; //输出结果前几行示例: (>ggsnPDPRecord(21),,) (-->recordType(0),,) (-->networkInitiation(1),,) </div> </li> <li><a href="/article/695.htm" title="web报表工具FineReport常用函数的用法总结(日期和时间函数)" target="_blank">web报表工具FineReport常用函数的用法总结(日期和时间函数)</a> <span class="text-muted">老A不折腾</span> <a class="tag" taget="_blank" href="/search/finereport/1.htm">finereport</a><a class="tag" taget="_blank" href="/search/%E6%8A%A5%E8%A1%A8%E5%B7%A5%E5%85%B7/1.htm">报表工具</a><a class="tag" taget="_blank" href="/search/web%E5%BC%80%E5%8F%91/1.htm">web开发</a> <div>web报表工具FineReport常用函数的用法总结(日期和时间函数)   说明:凡函数中以日期作为参数因子的,其中日期的形式都必须是yy/mm/dd。而且必须用英文环境下双引号(" ")引用。   DATE DATE(year,month,day):返回一个表示某一特定日期的系列数。 Year:代表年,可为一到四位数。 Month:代表月份。</div> </li> <li><a href="/article/822.htm" title="c++ 宏定义中的##操作符" target="_blank">c++ 宏定义中的##操作符</a> <span class="text-muted">墙头上一根草</span> <a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a> <div>#与##在宏定义中的--宏展开 #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {       &nbs</div> </li> <li><a href="/article/949.htm" title="分析Spring源代码之,DI的实现" target="_blank">分析Spring源代码之,DI的实现</a> <span class="text-muted">aijuans</span> <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/DI/1.htm">DI</a><a class="tag" taget="_blank" href="/search/%E7%8E%B0/1.htm">现</a><a class="tag" taget="_blank" href="/search/%E6%BA%90%E4%BB%A3%E7%A0%81/1.htm">源代码</a> <div>(转) 分析Spring源代码之,DI的实现 2012/1/3 by tony                 接着上次的讲,以下这个sample [java]  view plain copy print </div> </li> <li><a href="/article/1076.htm" title="for循环的进化" target="_blank">for循环的进化</a> <span class="text-muted">alxw4616</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a> <div>// for循环的进化 // 菜鸟 for (var i = 0; i < Things.length ; i++) { // Things[i] } // 老鸟 for (var i = 0, len = Things.length; i < len; i++) { // Things[i] } // 大师 for (var i = Things.le</div> </li> <li><a href="/article/1203.htm" title="网络编程Socket和ServerSocket简单的使用" target="_blank">网络编程Socket和ServerSocket简单的使用</a> <span class="text-muted">百合不是茶</span> <a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E5%9F%BA%E7%A1%80/1.htm">网络编程基础</a><a class="tag" taget="_blank" href="/search/IP%E5%9C%B0%E5%9D%80%E7%AB%AF%E5%8F%A3/1.htm">IP地址端口</a> <div>  网络编程;TCP/IP协议   网络:实现计算机之间的信息共享,数据资源的交换   协议:数据交换需要遵守的一种协议,按照约定的数据格式等写出去   端口:用于计算机之间的通信      每运行一个程序,系统会分配一个编号给该程序,作为和外界交换数据的唯一标识 0~65535   查看被使用的</div> </li> <li><a href="/article/1330.htm" title="JDK1.5 生产消费者" target="_blank">JDK1.5 生产消费者</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/thread/1.htm">thread</a><a class="tag" taget="_blank" href="/search/%E7%94%9F%E4%BA%A7%E6%B6%88%E8%B4%B9%E8%80%85/1.htm">生产消费者</a><a class="tag" taget="_blank" href="/search/java%E5%A4%9A%E7%BA%BF%E7%A8%8B/1.htm">java多线程</a> <div>ArrayBlockingQueue:        一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。队列的头部 是在队列中存在时间最长的元素。队列的尾部 是在队列中存在时间最短的元素。新元素插入到队列的尾部,队列检索操作则是从队列头部开始获得元素。 ArrayBlockingQueue的常用方法: </div> </li> <li><a href="/article/1457.htm" title="JAVA版身份证获取性别、出生日期及年龄" target="_blank">JAVA版身份证获取性别、出生日期及年龄</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%80%A7%E5%88%AB/1.htm">性别</a><a class="tag" taget="_blank" href="/search/%E5%87%BA%E7%94%9F%E6%97%A5%E6%9C%9F/1.htm">出生日期</a><a class="tag" taget="_blank" href="/search/%E5%B9%B4%E9%BE%84/1.htm">年龄</a> <div>        工作中需要根据身份证获取性别、出生日期及年龄,且要还要支持15位长度的身份证号码,网上搜索了一下,经过测试好像多少存在点问题,干脆自已写一个。 CertificateNo.java package com.bijian.study; import java.util.Calendar; import </div> </li> <li><a href="/article/1584.htm" title="【Java范型六】范型与枚举" target="_blank">【Java范型六】范型与枚举</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>首先,枚举类型的定义不能带有类型参数,所以,不能把枚举类型定义为范型枚举类,例如下面的枚举类定义是有编译错的   public enum EnumGenerics<T> { //编译错,提示枚举不能带有范型参数 OK, ERROR; public <T> T get(T type) { return null; </div> </li> <li><a href="/article/1711.htm" title="【Nginx五】Nginx常用日志格式含义" target="_blank">【Nginx五】Nginx常用日志格式含义</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/nginx/1.htm">nginx</a> <div>1. log_format 1.1 log_format指令用于指定日志的格式,格式:   log_format name(格式名称) type(格式样式)   1.2 如下是一个常用的Nginx日志格式:   log_format main '[$time_local]|$request_time|$status|$body_bytes</div> </li> <li><a href="/article/1838.htm" title="Lua 语言 15 分钟快速入门" target="_blank">Lua 语言 15 分钟快速入门</a> <span class="text-muted">ronin47</span> <a class="tag" taget="_blank" href="/search/lua+%E5%9F%BA%E7%A1%80/1.htm">lua 基础</a> <div>- - 单行注释 - - [[      [多行注释] - - ]]   - - - - - - - - - - - 1. 变量 & 控制流 - - - - - - - - - - num = 23 - - 数字都是双精度 str = 'aspythonstring' </div> </li> <li><a href="/article/1965.htm" title="java-35.求一个矩阵中最大的二维矩阵 ( 元素和最大 )" target="_blank">java-35.求一个矩阵中最大的二维矩阵 ( 元素和最大 )</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>the idea is from: http://blog.csdn.net/zhanxinhang/article/details/6731134 public class MaxSubMatrix { /**see http://blog.csdn.net/zhanxinhang/article/details/6731134 * Q35 求一个矩阵中最大的二维</div> </li> <li><a href="/article/2092.htm" title="mongoDB文档型数据库特点" target="_blank">mongoDB文档型数据库特点</a> <span class="text-muted">开窍的石头</span> <a class="tag" taget="_blank" href="/search/mongoDB%E6%96%87%E6%A1%A3%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93%E7%89%B9%E7%82%B9/1.htm">mongoDB文档型数据库特点</a> <div>MongoDD: 文档型数据库存储的是Bson文档-->json的二进制 特点:内部是执行引擎是js解释器,把文档转成Bson结构,在查询时转换成js对象。 mongoDB传统型数据库对比    传统类型数据库:结构化数据,定好了表结构后每一个内容符合表结构的。也就是说每一行每一列的数据都是一样的    文档型数据库:不用定好数据结构,</div> </li> <li><a href="/article/2219.htm" title="[毕业季节]欢迎广大毕业生加入JAVA程序员的行列" target="_blank">[毕业季节]欢迎广大毕业生加入JAVA程序员的行列</a> <span class="text-muted">comsci</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>     一年一度的毕业季来临了。。。。。。。。      正在投简历的学弟学妹们。。。如果觉得学校推荐的单位和公司不适合自己的兴趣和专业,可以考虑来我们软件行业,做一名职业程序员。。。      软件行业的开发工具中,对初学者最友好的就是JAVA语言了,网络上不仅仅有大量的</div> </li> <li><a href="/article/2346.htm" title="PHP操作Excel – PHPExcel 基本用法详解" target="_blank">PHP操作Excel – PHPExcel 基本用法详解</a> <span class="text-muted">cuiyadll</span> <a class="tag" taget="_blank" href="/search/PHP/1.htm">PHP</a><a class="tag" taget="_blank" href="/search/Excel/1.htm">Excel</a> <div>导出excel属性设置//Include classrequire_once('Classes/PHPExcel.php');require_once('Classes/PHPExcel/Writer/Excel2007.php');$objPHPExcel = new PHPExcel();//Set properties 设置文件属性$objPHPExcel->getProperties</div> </li> <li><a href="/article/2473.htm" title="IBM Webshpere MQ Client User Issue (MCAUSER)" target="_blank">IBM Webshpere MQ Client User Issue (MCAUSER)</a> <span class="text-muted">darrenzhu</span> <a class="tag" taget="_blank" href="/search/IBM/1.htm">IBM</a><a class="tag" taget="_blank" href="/search/jms/1.htm">jms</a><a class="tag" taget="_blank" href="/search/user/1.htm">user</a><a class="tag" taget="_blank" href="/search/MQ/1.htm">MQ</a><a class="tag" taget="_blank" href="/search/MCAUSER/1.htm">MCAUSER</a> <div>IBM MQ JMS Client去连接远端MQ Server的时候,需要提供User和Password吗? 答案是根据情况而定,取决于所定义的Channel里面的属性Message channel agent user identifier (MCAUSER)的设置。 http://stackoverflow.com/questions/20209429/how-mca-user-i</div> </li> <li><a href="/article/2600.htm" title="网线的接法" target="_blank">网线的接法</a> <span class="text-muted">dcj3sjt126com</span> <div>一、PC连HUB (直连线)A端:(标准568B):白橙,橙,白绿,蓝,白蓝,绿,白棕,棕。 B端:(标准568B):白橙,橙,白绿,蓝,白蓝,绿,白棕,棕。 二、PC连PC (交叉线)A端:(568A): 白绿,绿,白橙,蓝,白蓝,橙,白棕,棕; B端:(标准568B):白橙,橙,白绿,蓝,白蓝,绿,白棕,棕。 三、HUB连HUB&nb</div> </li> <li><a href="/article/2727.htm" title="Vimium插件让键盘党像操作Vim一样操作Chrome" target="_blank">Vimium插件让键盘党像操作Vim一样操作Chrome</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/chrome/1.htm">chrome</a><a class="tag" taget="_blank" href="/search/vim/1.htm">vim</a> <div>什么是键盘党? 键盘党是指尽可能将所有电脑操作用键盘来完成,而不去动鼠标的人。鼠标应该说是新手们的最爱,很直观,指哪点哪,很听话!不过常常使用电脑的人,如果一直使用鼠标的话,手会发酸,因为操作鼠标的时候,手臂不是在一个自然的状态,臂肌会处于绷紧状态。而使用键盘则双手是放松状态,只有手指在动。而且尽量少的从鼠标移动到键盘来回操作,也省不少事。 在chrome里安装 vimium 插件 </div> </li> <li><a href="/article/2854.htm" title="MongoDB查询(2)——数组查询[六]" target="_blank">MongoDB查询(2)——数组查询[六]</a> <span class="text-muted">eksliang</span> <a class="tag" taget="_blank" href="/search/mongodb/1.htm">mongodb</a><a class="tag" taget="_blank" href="/search/MongoDB%E6%9F%A5%E8%AF%A2%E6%95%B0%E7%BB%84/1.htm">MongoDB查询数组</a> <div>MongoDB查询数组 转载请出自出处:http://eksliang.iteye.com/blog/2177292 一、概述  MongoDB查询数组与查询标量值是一样的,例如,有一个水果列表,如下所示: > db.food.find() { "_id" : "001", "fruits" : [ "苹</div> </li> <li><a href="/article/2981.htm" title="cordova读写文件(1)" target="_blank">cordova读写文件(1)</a> <span class="text-muted">gundumw100</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/Cordova/1.htm">Cordova</a> <div>使用cordova可以很方便的在手机sdcard中读写文件。 首先需要安装cordova插件:file 命令为: cordova plugin add org.apache.cordova.file 然后就可以读写文件了,这里我先是写入一个文件,具体的JS代码为: var datas=null;//datas need write var directory=&</div> </li> <li><a href="/article/3108.htm" title="HTML5 FormData 进行文件jquery ajax 上传 到又拍云" target="_blank">HTML5 FormData 进行文件jquery ajax 上传 到又拍云</a> <span class="text-muted">ileson</span> <a class="tag" taget="_blank" href="/search/jquery/1.htm">jquery</a><a class="tag" taget="_blank" href="/search/Ajax/1.htm">Ajax</a><a class="tag" taget="_blank" href="/search/html5/1.htm">html5</a><a class="tag" taget="_blank" href="/search/FormData/1.htm">FormData</a> <div>html5 新东西:FormData  可以提交二进制数据。 页面test.html <!DOCTYPE> <html> <head> <title> formdata file jquery ajax upload</title> </head> <body> <</div> </li> <li><a href="/article/3235.htm" title="swift appearanceWhenContainedIn:(version1.2 xcode6.4)" target="_blank">swift appearanceWhenContainedIn:(version1.2 xcode6.4)</a> <span class="text-muted">啸笑天</span> <a class="tag" taget="_blank" href="/search/version/1.htm">version</a> <div>  swift1.2中没有oc中对应的方法: + (instancetype)appearanceWhenContainedIn:(Class <UIAppearanceContainer>)ContainerClass, ... NS_REQUIRES_NIL_TERMINATION;  解决方法: 在swift项目中新建oc类如下: #import &</div> </li> <li><a href="/article/3362.htm" title="java实现SMTP邮件服务器" target="_blank">java实现SMTP邮件服务器</a> <span class="text-muted">macroli</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B/1.htm">编程</a> <div>电子邮件传递可以由多种协议来实现。目前,在Internet 网上最流行的三种电子邮件协议是SMTP、POP3 和 IMAP,下面分别简单介绍。   ◆ SMTP 协议   简单邮件传输协议(Simple Mail Transfer Protocol,SMTP)是一个运行在TCP/IP之上的协议,用它发送和接收电子邮件。SMTP 服务器在默认端口25上监听。SMTP客户使用一组简单的、基于文本的</div> </li> <li><a href="/article/3489.htm" title="mongodb group by having where 查询sql" target="_blank">mongodb group by having where 查询sql</a> <span class="text-muted">qiaolevip</span> <a class="tag" taget="_blank" href="/search/%E6%AF%8F%E5%A4%A9%E8%BF%9B%E6%AD%A5%E4%B8%80%E7%82%B9%E7%82%B9/1.htm">每天进步一点点</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0%E6%B0%B8%E6%97%A0%E6%AD%A2%E5%A2%83/1.htm">学习永无止境</a><a class="tag" taget="_blank" href="/search/mongo/1.htm">mongo</a><a class="tag" taget="_blank" href="/search/%E7%BA%B5%E8%A7%82%E5%8D%83%E8%B1%A1/1.htm">纵观千象</a> <div>SELECT cust_id, SUM(price) as total FROM orders WHERE status = 'A' GROUP BY cust_id HAVING total > 250 db.orders.aggregate( [ { $match: { status: 'A' } }, { $group: { </div> </li> <li><a href="/article/3616.htm" title="Struts2 Pojo(六)" target="_blank">Struts2 Pojo(六)</a> <span class="text-muted">Luob.</span> <a class="tag" taget="_blank" href="/search/POJO/1.htm">POJO</a><a class="tag" taget="_blank" href="/search/strust2/1.htm">strust2</a> <div>注意:附件中有完整案例 1.采用POJO对象的方法进行赋值和传值 2.web配置 <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee&q</div> </li> <li><a href="/article/3743.htm" title="struts2步骤" target="_blank">struts2步骤</a> <span class="text-muted">wuai</span> <a class="tag" taget="_blank" href="/search/struts/1.htm">struts</a> <div>1、添加jar包 2、在web.xml中配置过滤器 <filter>        <filter-name>struts2</filter-name>        <filter-class>org.apache.st</div> </li> </ul> </div> </div> </div> <div> <div class="container"> <div class="indexes"> <strong>按字母分类:</strong> <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a> </div> </div> </div> <footer id="footer" class="mb30 mt30"> <div class="container"> <div class="footBglm"> <a target="_blank" href="/">首页</a> - <a target="_blank" href="/custom/about.htm">关于我们</a> - <a target="_blank" href="/search/Java/1.htm">站内搜索</a> - <a target="_blank" href="/sitemap.txt">Sitemap</a> - <a target="_blank" href="/custom/delete.htm">侵权投诉</a> </div> <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved. <!-- <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>--> </div> </div> </footer> <!-- 代码高亮 --> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script> <link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/> <script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script> </body> </html>