1、自动化测试定位策略
- 不知道应该使用哪种定位方式?
- 元素定位不到无法解决?
定位方式

通用 Web 定位方式
| 定位策略 | 描述 | 
|---|---|
| class name | 通过 class 属性定位元素 | 
| css selector | 通过匹配 css selector 定位元素 | 
| id | 通过 id 属性匹配元素 | 
| name | 通过 name 属性定位元素 | 
| link text | 通过 <a>text</a>标签中间的 text 文本定位元素 | 
| partial link text | 通过 <a>text</a>标签中间的 text 文本的部分内容定位元素 | 
| tag name | 通过 tag 名称定位元素 | 
| xpath | 通过 xpath 表达式匹配元素 | 
选择定位器通用原则
- 
与研发约定的属性优先(class属性: [name='locate'])
- 
身份属性 id,name(web 定位) 
- 
复杂场景使用组合定位: 
- xpath,css
- 属性动态变化(id,text)
- 重复元素属性(id,text,class)
- 父子定位(子定位父)
- js定位
相关章节
- 高级定位-xpath
- 高级定位-css
- 执行JavaScript脚本
- 面试题-定位不到元素
Web 弹框定位
- 场景
- web 页面 alert 弹框
 
- 解决:
- web 需要使用 driver.switchTo().alert()处理
 
- web 需要使用 
下拉框/日期控件定位
- 场景:
- 
<input>标签组合的下拉框无法定位
- 
<input>标签组合的日期控件无法定位
 
- 
- 解决:
- 面对这些元素,我们可以引入 JS 注入技术来解决问题。
 
文件上传定位
- 场景:
- input 标签文件上传
 
- 解决:
- input 标签直接使用 send_keys()方法
 
具体的章节请循序渐进进行学习。
2、测试人论坛搜索功能自动化测试
目录
- 产品分析
- 测试用例分析
- 编写脚本
- 脚本优化
产品分析
- 产品:测试人论坛
- 功能:搜索
测试用例分析
| 用例标题 | 前提条件 | 用例步骤 | 预期结果 | 实际结果 | 
|---|---|---|---|---|
| 测试人搜索功能 | 进入测试人论坛首页 | 1. 点击搜索按钮 | 
- 输入搜索关键词
- 点击搜索按钮|1. 搜索成功
- 搜索结果列表包含关键字||
编写脚本
"""
__author__ = '霍格沃兹测试开发学社'
__desc__ = '更多测试开发技术探讨,请访问:https://ceshiren.com/t/topic/15860'
"""
# 结合pytest测试框架
# 用例标题=文件名+类名+方法名
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
class TestCeshiren:
    def test_search(self):
        """
        前提条件: 进入测试人论坛的搜索页面
        测试步骤: 1. 输入搜索关键词
                  2. 点击搜索按钮
        预期结果/实际结果
        :return:
        """
        # 打开浏览器
        driver = webdriver.Chrome()
        driver.implicitly_wait(3)
        # 打开被测地址
        driver.get("https://ceshiren.com/search?expanded=true")
        # 定位到搜索输入框,并输入搜索内容
        driver.find_element(By.CSS_SELECTOR, "[placeholder='搜索']").send_keys("appium")
        # 定位到搜索按钮,并点击
        driver.find_element(By.CSS_SELECTOR, ".search-cta").click()
        #断言
        web_element=driver.find_element(By.CSS_SELECTOR, ".topic-title")、
        assert "appium" in web_element.text.lower()
脚本优化-前置与后置
- 前置:setup- 初始化浏览器驱动
 
- 后置:teardown- 关闭浏览器
 
from selenium import webdriver
from selenium.webdriver.common.by import By
class TestCeshirenLinear:
    # 前置处理:初始化
    def setup(self):
        self.browser = webdriver.Chrome()
        self.browser.implicitly_wait(10)
        self.browser.maximize_window()
    # 后置处理:收尾
    def teardown(self):
        self.browser.quit()
    # 测试用例
    def test_search(self):
        # 访问测试人社区
        self.browser.get("https://ceshiren.com/")
        # 点击搜索按钮
        search_button = self.browser.find_element(By.ID, "search-button")
        search_button.click()
        # 输入搜索关键词
        search_input = self.browser.find_element(By.ID, "search-term")
        search_input.clear()
        search_input.send_keys("hogwarts")
        # 点击搜索结果项
        result_items = self.browser.find_elements(By.CSS_SELECTOR, "div.user-titles")
        top_item = result_items[0]
        top_item_name = top_item.find_element(By.CSS_SELECTOR, "span.name").text
        top_item.click()
脚本优化-添加断言
- 
assert语句
import logging
import time
import allure
from selenium import webdriver
from selenium.webdriver.common.by import By
class TestCeshirenLinear:
    # 前置处理:初始化
    def setup(self):
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(10)
        self.driver.maximize_window()
    # 后置处理:收尾
    def teardown(self):
        self.driver.quit()
    # 测试用例
    def test_search(self):
        # 访问测试人社区
        self.driver.get("https://ceshiren.com/")
        # 点击搜索按钮
        logging.info("点击搜索按钮")
        search_button = self.browser.find_element(By.ID, "search-button")
        search_button.click()
        # 输入搜索关键词
        logging.info("输入搜索关键词")
        search_input = self.browser.find_element(By.ID, "search-term")
        search_input.clear()
        search_input.send_keys("霍格沃兹测试学院官方")
        logging.info("点击搜索结果项")
        xpath_expr = "//div[@class='user-titles']/span[contains(text(), '霍格沃兹测试学院官方')]"
        target_item = self.browser.find_element(By.XPATH, xpath_expr)
        target_item.click()
        # 测试断言
        logging.info("测试断言")
        full_name = self.browser.find_element(By.CSS_SELECTOR, "h2.full-name").text
        assert "霍格沃兹测试学院官方" == full_name
# 结合pytest测试框架
# 用例标题=文件名+类名+方法名
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
#=============优化1
#问题: 1. 没有前置和后置的处理动作 2. driver启动了之后没有做quit()
# 如果没有quit()动作,会导致大量的 chromedriver 进程一直存在 mac 使用 ps -ef | grep chromedriver, window 看任务管理期
class TestCeshiren:
    def setup(self):
        """
        前提条件: 进入测试人论坛的搜索页面
        :return:
        """
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(3)
        # 打开被测地址
        self.driver.get("https://ceshiren.com/search?expanded=true")
    def teardown(self):
        # 优化问题: 2. driver启动了之后没有做quit()
        # 每一次用例结束之后都会关闭chromedriver的进程,也会关闭浏览器
        self.driver.quit()
    # def test_search2(self):
        # self.driver.
    def test_search(self):
        """
        测试步骤: 1. 输入搜索关键词
                  2. 点击搜索按钮
        预期结果/实际结果
        :return:
        """
        # 打开浏览器
        # 定位到搜索输入框,并输入搜索内容
        self.driver.find_element(By.CSS_SELECTOR, "[placeholder='搜索']").send_keys("appium")
        # 定位到搜索按钮,并点击
        self.driver.find_element(By.CSS_SELECTOR, ".search-cta").click()
        # 断言=预期结果与实际结果对比的结果
        # 获取实际结果, 即为获取搜索结果列表的标题内容
        # 第一种方式,获取第一个搜索结果,
        # time.sleep(3) # 加一个3秒的强制等待,等待页面渲染完成,如果没有报错,证明定位没有错误,反之,可能定位或者其他原因的错误
        web_element=self.driver.find_element(By.CSS_SELECTOR, ".topic-title")
        # 获取文本类的实际结果 断言,appium关键字是否在获取的实际结果文本之中
        # 两种解决方案: 1. 统一,比如 断言 Appium in
        # 2. 就是把获取到的内容和预期结果同意 使用.lower 就可以使大写的字母小写
        assert "appium" in web_element.text.lower()