软件测试/测试开发丨用户端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/1773613272952537088.htm" title="【Python】一文详细介绍 py格式 文件" target="_blank">【Python】一文详细介绍 py格式 文件</a> <span class="text-muted">高斯小哥</span> <a class="tag" taget="_blank" href="/search/Python%E5%9F%BA%E7%A1%80%E3%80%90%E9%AB%98%E8%B4%A8%E9%87%8F%E5%90%88%E9%9B%86%E3%80%91/1.htm">Python基础【高质量合集】</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8/1.htm">新手入门</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a> <div>【Python】一文详细介绍py格式文件个人主页:高斯小哥高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程希望得到您的订阅和支持~创作高质量博文(平均质量分92+),分享更多关于深度学习、PyTorch、Python领域的优质内容!(希望得到您的关注~)文章目录一、py格式文件简介二、如何创建和编辑py格式文件三、如何运行py</div> </li> <li><a href="/article/1773610656310820864.htm" title="大学播音主持都学什么内容?播音主持专业学什么?" target="_blank">大学播音主持都学什么内容?播音主持专业学什么?</a> <span class="text-muted">配音新手圈</span> <div>有些喜欢播音主持并且犹豫要不要报考这个大学专业的小伙伴们就会想要了解大学播音主持都学什么内容吧,毕竟如果不够了解就直接选择这个专业真的等选择完进去学习以后才知道这个专业并不是自己想要学习的东西那就来不及了。下面是小编为大家整理出来的一些播音主持专业学习的内容,请往下看吧。大学播音主持专业主要学习的课程有:播音发声、播音创作基础、广播播音主持、电视播音主持、文艺作品演播学概论、新闻学概论、新闻采编、</div> </li> <li><a href="/article/1773604712310964224.htm" title="python抓包与解包_Python—网络抓包与解包(pcap、dpkt)" target="_blank">python抓包与解包_Python—网络抓包与解包(pcap、dpkt)</a> <span class="text-muted">weixin_39691055</span> <a class="tag" taget="_blank" href="/search/python%E6%8A%93%E5%8C%85%E4%B8%8E%E8%A7%A3%E5%8C%85/1.htm">python抓包与解包</a> <div>pcap安装[root@localhost~]#pipinstallpypcap抓包与解包#-*-coding:utf-8-*-importpcap,dpktimportre,threading,requests__black_ip=['103.224.249.123','203.66.1.212']#抓包:param1eth_name网卡名,如:eth0,eth3。param2p_type日志捕</div> </li> <li><a href="/article/1773583062202908672.htm" title="新网师的精神肤色(幕布笔记)" target="_blank">新网师的精神肤色(幕布笔记)</a> <span class="text-muted">悦读书香</span> <div>王子老师的《极简100小妙招》收到已经几天了,之前大概的浏览了全书,今天起给自己定了一个计划,必须每天学习极简小妙招里面的一个妙招,并加以运用。一、今天要打卡什么内容因有完成每天学习极简小妙招的计划,所以今天晚饭吃的比较简单,草草吃完以后带着小宝到广场溜达一圈,急忙赶回来学习极简小妙招。再重看的时候不知道自己要学点什么,打卡哪一招,感觉哪个都简单,就看这一环节像王子老师说的“一看就会”,但做这一环</div> </li> <li><a href="/article/1773582305621770240.htm" title="华为OD机试 - 单向链表中间节点(Java & JS & Python & C & C++)" target="_blank">华为OD机试 - 单向链表中间节点(Java & JS & Python & C & C++)</a> <span class="text-muted">华为OD题库</span> <a class="tag" taget="_blank" href="/search/%E5%8D%8E%E4%B8%BAod/1.htm">华为od</a><a class="tag" taget="_blank" href="/search/%E9%93%BE%E8%A1%A8/1.htm">链表</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>须知哈喽,本题库完全免费,收费是为了防止被爬,大家订阅专栏后可以私信联系退款。感谢支持文章目录须知题目描述输出描述解析代码题目描述给定一个单链表L,请编写程序输出L中间结点保存的数据。如果有两个中间结点,则输出第二个中间结点保存的数据。例如:给定L为1→7→5,则输出应该为7;给定L为1→2→3→4,则输出应该为3;输入描述每个输入包含1个测试用例。每个测试用例:第一行给出链表首结点的地址、结点总</div> </li> <li><a href="/article/1773578026081124352.htm" title="学习JavaEE的日子 Day32 线程池" target="_blank">学习JavaEE的日子 Day32 线程池</a> <span class="text-muted">A 北枝</span> <a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0JavaEE/1.htm">学习JavaEE</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/java-ee/1.htm">java-ee</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E7%BA%BF%E7%A8%8B%E6%B1%A0/1.htm">线程池</a> <div>Day32线程池1.引入一个线程完成一项任务所需时间为:创建线程时间-Time1线程中执行任务的时间-Time2销毁线程时间-Time32.为什么需要线程池(重要)线程池技术正是关注如何缩短或调整Time1和Time3的时间,从而提高程序的性能。项目中可以把Time1,T3分别安排在项目的启动和结束的时间段或者一些空闲的时间段线程池不仅调整Time1,Time3产生的时间段,而且它还显著减少了创建</div> </li> <li><a href="/article/1773571355124498432.htm" title="python 推导式(派生、衍生)" target="_blank">python 推导式(派生、衍生)</a> <span class="text-muted">sanduo112</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/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/windows/1.htm">windows</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>python推导式一、推导式(派生、衍生)1.Python推导式是一种独特的数据处理方式,可以从一个数据序列构建另一个新的数据序列的结构体。2.列表(list)推导式3.字典(dict)推导式4.集合(set)推导式5.元组(tuple)推导式二、代码概述一、推导式(派生、衍生)1.Python推导式是一种独特的数据处理方式,可以从一个数据序列构建另一个新的数据序列的结构体。Python支持各种数</div> </li> <li><a href="/article/1773560996888117248.htm" title="没有如释重负" target="_blank">没有如释重负</a> <span class="text-muted">君远近</span> <div>虽然只有短短的一个多月的努力复习时间,但今天的整个考试经过,还是发现了效果的,题目做的比较自如,没有慌里慌张,而且提前五分钟完成。至于考试成绩,没有实足的把握,60分都不敢保证。但绝对相信自己,比去年肯定要好!今天早早的赶到考场,见到了刘老师,谈起来学习情况,坦率的说,真的是自己不够重视。总以为会很难,没有信心。其实不是的,只要认真对待,树立足够的信心,绝对可以通过考试的。还向老师询问了,后续再报</div> </li> <li><a href="/article/1773549956938924032.htm" title="数据挖掘|数据预处理|基于Python的数据标准化方法" target="_blank">数据挖掘|数据预处理|基于Python的数据标准化方法</a> <span class="text-muted">皖山文武</span> <a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/1.htm">数据挖掘</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BB%BA%E6%A8%A1%E4%B8%8E%E5%88%86%E6%9E%90/1.htm">数据建模与分析</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/1.htm">数据挖掘</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>基于Python的数据标准化方法1.z-score方法2.极差标准化方法3.最大绝对值标准化方法在数据分析之前,通常需要先将数据标准化(Standardization),利用标准化后的数据进行数据分析,以避免属性之间不同度量和取值范围差异造成数据对分析结果的影响。1.z-score方法Z-score方法是基于原始数据的均值和标准差来进行数据标准化的,处理后的数据均值为0,方差为1,符合标准正态分布</div> </li> <li><a href="/article/1773545802220765184.htm" title="C++学习笔记(lambda函数)" target="_blank">C++学习笔记(lambda函数)</a> <span class="text-muted">__TAT__</span> <a class="tag" taget="_blank" href="/search/C%26amp%3BC%2B%2B/1.htm">C&C++</a><a class="tag" taget="_blank" href="/search/c%2B%2B/1.htm">c++</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a> <div>C++learningnote1、lambda函数的语法2、lambda函数的几种用法1、lambda函数的语法lambda函数的一般语法如下:[capture_clause](parameters)->return_type{function_body}capture_clause:需要捕获的变量,但要求该变量必须在这个作用域中。通常的捕获方式有以下几种:[]:不捕获任何变量[&]:按引用捕获变</div> </li> <li><a href="/article/1773540012541935616.htm" title="CSV指南:Python程序获取大型CSV文件行数" target="_blank">CSV指南:Python程序获取大型CSV文件行数</a> <span class="text-muted">孤独打铁匠Julian</span> <a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB/1.htm">经验分享</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a> <div>本指南提供了几种使用Python来获取大型CSV文件行数的方法,并解释了每种方法的适用场景。方法1:使用csv.reader处理复杂CSV文件当你的CSV文件中包含多行字段(即某些字段的值中包含换行符)时,使用csv.reader是一个可靠的选择,因为它能够正确处理这些复杂情况。这个方法适用于大多数大小的CSV文件,但是对于非常大的文件,读取整个文件可能会占用较多的时间和内存。对于极大的文件,考虑</div> </li> <li><a href="/article/1773530120070430720.htm" title="心赏(2018.10.8)" target="_blank">心赏(2018.10.8)</a> <span class="text-muted">六一节_3928</span> <div>1.上班第一天,同事彤休完产假,回来上班,给我带了酸奶和水果。她生小孩时,我给她发了一个小红包贺喜,哪知她就记在心里了。心赏这个有心的90后。2.女儿放学回来,说自己当了小组长。一边说不想当,一边得意的样子。心赏老师给了孩子这个锻炼的机会。3.老妈今天做了"蚂蚁上树"的菜,得到女儿的高度肯定。心赏老妈还在不断学习。</div> </li> <li><a href="/article/1773514238858428416.htm" title="2022-2-13晨间日记" target="_blank">2022-2-13晨间日记</a> <span class="text-muted">越亮也打烊</span> <div>今天是什么日子起床:7:00就寝:12:08天气:晴心情:糟糕纪念日:无任务清单昨日完成的任务,最重要的三件事:寒假作业,网课,画画改进:作业时间剪短习惯养成:网课不逃~周目标·完成进度数学卷子100%学习·信息·阅读《傅雷家书》《钢铁是怎样炼成的》健康·饮食·锻炼我终于不喝饮料啦,喝茶~人际·家人·朋友邝姐姐带我吃火锅工作·思考啥时候开学,我还有几天赶完作业最美好的三件事1.卷子写完了2.我有冰</div> </li> <li><a href="/article/1773512348661776384.htm" title="中原焦点团队38期王芳芳坚持分享第236天,20230630总约练134次,来访113次,咨8次,观察员13次" target="_blank">中原焦点团队38期王芳芳坚持分享第236天,20230630总约练134次,来访113次,咨8次,观察员13次</a> <span class="text-muted">芳芳王</span> <div>学习焦点的初心是想拯救孩子,孩子由于沉迷游戏,成绩下滑,在学习的过程中发现是自己的教育方式出了状况。经过半年的学习,一些焦点的基本技巧,如接纳、欣赏、倾听、同理心、尊重等都有了一定的了解。但在实际应用时仍然存在很多问题,感觉自己仍然没有放下对孩子成绩的期望,仍然把握不住对孩子管理的度。我该如何去陪伴好孩子?多用心去听课,并加强反思,多约练。去思考如何让自己快乐起来?</div> </li> <li><a href="/article/1773504261557125120.htm" title="谷歌浏览器驱动Chromedriver(114-120版本)文件以及驱动下载教程" target="_blank">谷歌浏览器驱动Chromedriver(114-120版本)文件以及驱动下载教程</a> <span class="text-muted">pigerr杨</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><a class="tag" taget="_blank" href="/search/chrome/1.htm">chrome</a><a class="tag" taget="_blank" href="/search/drivers/1.htm">drivers</a> <div>ChromeDriver官方网站GitHub||GoogleChromeLabs/chrome-for-testingChromeDriver113-125_JSONChromeforTestingavailability123-125zip白月黑羽Python基础|进阶|Qt图形界面|Django|自动化测试|性能测试|JS语言|JS前端|原理与安装</div> </li> <li><a href="/article/1773500735770656768.htm" title="大创项目推荐 深度学习 opencv python 公式识别(图像识别 机器视觉)" target="_blank">大创项目推荐 深度学习 opencv python 公式识别(图像识别 机器视觉)</a> <span class="text-muted">laafeer</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a> <div>文章目录0前言1课题说明2效果展示3具体实现4关键代码实现5算法综合效果6最后0前言优质竞赛项目系列,今天要分享的是基于深度学习的数学公式识别算法实现该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!学长这里给一个题目综合评分(每项满分5分)难度系数:3分工作量:4分创新点:4分更多资料,项目分享:https://gitee.com/dancheng-senior/postgraduate1课题</div> </li> <li><a href="/article/1773499614951964672.htm" title="#D174-读书会作业-《财务自由之路》3" target="_blank">#D174-读书会作业-《财务自由之路》3</a> <span class="text-muted">白洲笔记</span> <div>最近沉迷于写作营,一直就没时间去弄读书会的作业,书的第二遍也就看了个开头,趁着日更的时间,赶紧把作业做了,这次是15到21课。【1.印象最深刻的部分】(本周所读内容中印象最深刻的部分)*活在未来,最正确的方法是什么?用正确的方法做正确的事情,判断什么是正确的?逻辑。学会思考。"作对事情"永远比“把事情作对“重要的多。”长远思考,耐心验证,小心总结提炼“证明自己正确并不是学习的任务和目标,时刻成长,</div> </li> <li><a href="/article/1773499616306724864.htm" title="读书笔记《穿越寒冬》" target="_blank">读书笔记《穿越寒冬》</a> <span class="text-muted">如雪般飞舞</span> <div>各位好,我们今天来讲一本书,名字叫作《穿越寒冬》。看起来特别应景,大家觉得现在创业的状况不景气,大家都在忍受着寒冬的煎熬。但实际上,这本书的英文名字并不是这个意思,它的英文名叫作“如何创立一家新公司,并且能够活下来”。我在整个读完了以后,我发现这本书真正要翻译得好,它的名字应该叫作《创业生存手册》。这个书的作者,来自硅谷的霍夫曼船长。霍夫曼船长写过一本让创业者觉得特别贴心的书,叫作《让大象飞》它和</div> </li> <li><a href="/article/1773478938652246016.htm" title="账务处理又出错?资深会计来教你,学会效率翻倍!共同学习" target="_blank">账务处理又出错?资深会计来教你,学会效率翻倍!共同学习</a> <span class="text-muted">小橘子要努力吖</span> <div>作为一名会计,在实际工作中会遇到各种麻烦的账务处理问题。那么,最常用的会计处理方法都有哪些呢?今天小编为大家带来了从业二十六年的资深老会计分享的十四中会计常用的账务处理问题的解决方案,快来看看吧!一、促销品的账务处理在促销时公司经常会把一些商品按进价赠送给消费者使用二、款已付清但发票未到的账务处理三、购买材料发生不合理损耗的账务处理问题公司在购买材料时,常常会发生一些不合理的损耗,那么这种问题该怎</div> </li> <li><a href="/article/1773477427016695808.htm" title="【真诚子】通晓鬼谷第七篇读书日记。" target="_blank">【真诚子】通晓鬼谷第七篇读书日记。</a> <span class="text-muted">真诚子l通晓鬼谷</span> <div>今天把个人品牌,从193读到208页,书的内容质量出奇的高,尤其是这一段。对标学习法,找一个比自己强,或者你期望成为的人进行模仿性学习,对标学习,不是到处,去找人对标兵学习很多人的优点,或是学习自己认为好的方面,而是找准一个对标高手,然后全方位的学习这个人。我在做品牌咨询时就对标,学习了一个在国内很有名的行业顶尖大咖。我先找到他公司的方案,进行完全模仿,连PPT的排版都一样,而且我只参照他一个人的</div> </li> <li><a href="/article/1773475811752476672.htm" title="ES-LTR粗排模块" target="_blank">ES-LTR粗排模块</a> <span class="text-muted">poins</span> <a class="tag" taget="_blank" href="/search/jenkins/1.htm">jenkins</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a> <div>ES-LTR粗排模块官方资源:https://github.com/HeiBoWang/elasticsearch-learning-to-rankElasticsearch学习排名插件使用机器学习提高搜索相关性排名。它为维基媒体基金会和Snagajob等地方的搜索提供了动力!这个插件有什么功能此插件:允许您在Elasticsearch中存储特征(Elasticsearch查询模板)记录特征得分(</div> </li> <li><a href="/article/1773475780618158080.htm" title="2018-11-18成长小组学习笔记" target="_blank">2018-11-18成长小组学习笔记</a> <span class="text-muted">实验中学45</span> <div>因为嗓子“罢工”,我面对众人只能借“微笑”代言。在开始授课前,绣霞老师先反馈上次作业的情况,提到“接纳”需是真正发自内心的完全接纳,而不是口头上的接纳,内心却是排斥的。提到一个“问题”孩子恰恰对家爱的更加“深沉”,夫妻间的问题不能影响到孩子,对孩子更好的爱不是你为他做的更多,而是给他自由、健康成长的空间。图片发自App一、孩子:家庭的一面镜子夫妻成了彼此的“投射”,婚姻便“吵的不可开交”,婚姻便成</div> </li> <li><a href="/article/1773460076456116224.htm" title="2.5 项目讲解流程" target="_blank">2.5 项目讲解流程</a> <span class="text-muted">王守谦26</span> <a class="tag" taget="_blank" href="/search/%E9%A1%B9%E7%9B%AE%E8%B5%84%E6%96%99/1.htm">项目资料</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a> <div>一、项目讲解1、自我介绍2、项目流程-===============================二、自我介绍(一)、学员自我介绍,讲解存在的问题比如:讲解年份、卡顿、重点学历、忘记(二)自我规则内容1、开场白:礼貌用语2、时间:自我介绍1-2分钟以内3、内容:姓名、籍贯、毕业院校、(拉进面试官距离)4、技能:功能测试、接口测试、自动化测试、app测试、性能测试、安全测试黑盒测试、白盒测试、灰盒</div> </li> <li><a href="/article/1773458565772673024.htm" title="【鸿蒙HarmonyOS开发笔记】ArkUI常用组件介绍汇总(更新中)" target="_blank">【鸿蒙HarmonyOS开发笔记】ArkUI常用组件介绍汇总(更新中)</a> <span class="text-muted">温、</span> <a class="tag" taget="_blank" href="/search/%E9%B8%BF%E8%92%99HarmonyOS%E5%BC%80%E5%8F%91%E7%AC%94%E8%AE%B0/1.htm">鸿蒙HarmonyOS开发笔记</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/1.htm">学习记录</a><a class="tag" taget="_blank" href="/search/harmonyos/1.htm">harmonyos</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/%E5%8D%8E%E4%B8%BA/1.htm">华为</a> <div>概述此文总结开发中用到的一些常用组件,便于查阅,此文持续更新,闲的没事就更线性布局(Row/Column)不多介绍了,最常用的布局组件,两者除了方向不一样,别的都一样方便起见下面只写Column常用属性排列方向上的间距:spaceColumn({space:20}){Row().width('90%').height(50).backgroundColor(0xF5DEB3)Row().width</div> </li> <li><a href="/article/1773450885851054080.htm" title="python转码" target="_blank">python转码</a> <span class="text-muted">Desamond</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>转码在许多场景中都有应用,以下是一些常见的场景:网页开发:当用户在网页上输入文本时,可能需要将特殊字符(如空格、引号、特殊符号等)进行转码,以防止这些字符对URL或HTML代码产生干扰。文件名处理:在处理文件名时,可能需要将特殊字符进行转码,以避免文件名被错误地解析或显示。数据传输:在数据传输过程中,为了确保数据的完整性和正确性,可能需要将数据中的特殊字符进行转码。数据存储:在数据库或数据存储中,</div> </li> <li><a href="/article/1773444718840053760.htm" title="排序算法太多?常用排序都在这了,一篇文章总结和实现所有面试会考的排序算法(基于Python实现)" target="_blank">排序算法太多?常用排序都在这了,一篇文章总结和实现所有面试会考的排序算法(基于Python实现)</a> <span class="text-muted">宇宙之一粟</span> <a class="tag" taget="_blank" href="/search/%E4%B8%8D%E5%BD%92%E8%B7%AF%E4%B9%8BPython/1.htm">不归路之Python</a><a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/IT%E9%9D%A2%E8%AF%95%E9%A2%98%E6%94%B6%E9%9B%86%E4%B8%8E%E6%80%BB%E7%BB%93/1.htm">IT面试题收集与总结</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95/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/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a><a class="tag" taget="_blank" href="/search/%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95/1.htm">排序算法</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>文章目录排序算法1.常见的排序算法1.1选择排序1.1.1思想1.1.2实现**1.1.3选择排序分析**1.2冒泡排序**1.2.1思想****1.2.2实现****1.2.3冒泡排序分析**1.3插入排序**1.3.1思想****1.3.2实现****1.3.3插入排序分析**1.4归并排序☆☆★**1.4.1思想****1.4.2实现****1.4.3归并排序分析**1.5快速排序☆★★**</div> </li> <li><a href="/article/1773442075023441920.htm" title="27.Python从入门到精通—Python异常处理 抛出异常 用户自定义异常 定义清理行为 预定义的清理行为" target="_blank">27.Python从入门到精通—Python异常处理 抛出异常 用户自定义异常 定义清理行为 预定义的清理行为</a> <span class="text-muted">以山河作礼。</span> <a class="tag" taget="_blank" href="/search/%23/1.htm">#</a><a class="tag" taget="_blank" href="/search/Python%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%E2%80%94%E8%AF%A6%E8%A7%A3%E7%89%88/1.htm">Python基础入门—详解版</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a> <div>27.从入门到精通:Python异常处理抛出异常用户自定义异常定义清理行为预定义的清理行为异常处理抛出异常用户自定义异常定义清理行为预定义的清理行为异常处理在Python中,异常处理是一种处理程序在执行期间可能遇到的错误的方法。当Python解释器遇到错误时,它会引发异常。异常是一种Python对象,它包含有关错误的信息,例如错误类型和错误位置。为了处理异常,您可以使用try-except语句。在</div> </li> <li><a href="/article/1773441502228316160.htm" title="2019-07-16" target="_blank">2019-07-16</a> <span class="text-muted">振华老凤祥店长崔宁宁</span> <div>大爱的李老师,智慧的教授,亲爱的跃友们:大家好!我是莱州鑫和金店李总的人~崔宁宁今天是我的日精进行动第56天,我分享一下今天的改变,我们相互勉励,每天进步一点点,离成功便不远。1、比学习:人这一生最主要的就是信念,坚定不移的信念是成功路上的重要基石!2、比改变:我是一切的根源,我变了世界就变了!改变自己的心态!3、比付出:承担才能成长,付出才会杰出!4、比谦卑:学习每位优秀店长身上的优点!5、比感</div> </li> <li><a href="/article/1773439683024453632.htm" title="python清华大学出版社答案_Python机器学习及实践" target="_blank">python清华大学出版社答案_Python机器学习及实践</a> <span class="text-muted">weixin_39805119</span> <a class="tag" taget="_blank" href="/search/python%E6%B8%85%E5%8D%8E%E5%A4%A7%E5%AD%A6%E5%87%BA%E7%89%88%E7%A4%BE%E7%AD%94%E6%A1%88/1.htm">python清华大学出版社答案</a> <div>第1章机器学习的基础知识1.1何谓机器学习1.1.1传感器和海量数据1.1.2机器学习的重要性1.1.3机器学习的表现1.1.4机器学习的主要任务1.1.5选择合适的算法1.1.6机器学习程序的步骤1.2综合分类1.3推荐系统和深度学习1.3.1推荐系统1.3.2深度学习1.4何为Python1.4.1使用Python软件的由来1.4.2为什么使用Python1.4.3Python设计定位1.4.</div> </li> <li><a href="/article/1773437340203679744.htm" title="2018-12-02" target="_blank">2018-12-02</a> <span class="text-muted">子分小</span> <div>姓名:张颖公司:菲尔德国际英语【反省总结第146天,始于20180709今天是20181202】【知~学习】六项精进大纲背诵3遍每天十个单词坚持第181天每天学习一篇英文文章第94天英语流利说课程第71天学习30分钟【行~实践】一、修身:(对自己个人)步行5000步二、齐家:(对家庭和家人)无三、建功:(对工作)完成与Arti活动课和两节Demo准备开班事宜{积善}:发愿从2018年7月9日起1年</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>