//直接从我的文档copy'的所以有点乱,这个为自己的学习总结 

Web自动化知识

  • 考前准备

Pip install pytest

Pip install selenium

Pip install selenium.webdriver.(显示等待)

生成 requirements.txt 文件

安装好所有依赖包后,可以使用以下命令生成 requirements.txt 文件。

pip freeze >requirements.txt

这条命令会将当前虚拟环境中的所有已安装包及其版本信息输出到requirements.txt 文件中。

使用 requirements.txt 文件安装依赖

在新的环境或其他开发人员的机器上,可以使用requirements.txt 文件来安装项目的所有依赖包。

首先,确保激活虚拟环境,然后运行以下命令:

pip install -r requirements.txt

这条命令会读取 requirements.txt 文件并安装其中列出的所有依赖包。

环境搭建

#导包

#指定驱动服务更快速

import time

from selenium import webdriver

#创建浏览器对象

driver=webdriver.Chrome()

# 打开商品管理页面

driver.get("https://litemall.hogwarts.ceshiren.com/")

#页面最大化

driver.maximize_window()

time.sleep(5)

#关闭驱动

driver.quit()

  • 元素定位及找不到怎么办

元素定位

name

driver.find_element(By.NAME,"password").clear() ​

id

driver.find_element(By.ID,"password") ​

LINK_TEXT(找不到元素试试直接中文)

driver.find_element(By.LINK_TEXT, "通讯录").click()

tag name

xpath

1.有明确文本的:driver.find_element(By.XPATH,"//*[text()='商品列表']")

2.输入框输入"//label[text()='商品编号']/following-sibling::div//input"

利用页面结构(label + 输入框)进行相对定位,非常稳定,适合表单输入

3.包含文本匹配://*[contains(text(), '商品')]

用途:查找文本中包含“商品”的任意元素。

  1. 部分匹配

✅ XPath 中的部分匹配函数

匹配类型

CSS Selector

XPath

以...开头

[attr^='value']

starts-with(@attr, 'value')

以...结尾

[attr$='value']

ends-with(@attr, 'value')

包含...

[attr*='value']

contains(@attr, 'value')

css_selector

id,#开头

class,.开头

部分匹配

self.driver.find_element(By.CSS_SELECTOR, "input[id^='user']") # id 以 user 开头 self.driver.find_element(By.CSS_SELECTOR, "input[id$='Name']") # id 以 Name 结尾# self.driver.find_element(By.CSS_SELECTOR, "input[class*='input']") # class 包含 input

calss_name(多个名选取其中一个)

PARTIAL_LINK_TEXT = "partial link text"

页面没有加载完成

显示等待

#下载 pip install selenium.webdriver.

 #导入包 

 

from selenium.webdriver.support.wait import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

el = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH, '//* [@id="1"]/div/h3/a'))) # driver.find_element(By.XPATH, '//*[@id="1"]/div/h3/a').click() el.click()

隐式等待

driver.implicitly_wait(3)

强制等待

impot time Time.sleep()

框架内元素不可找

当元素在子页面的frame元素中需要进行切换定位

driver.switch_to.frame(driver.find_element(By.XPATH, '/html/frameset/frame[1]'))

 //大框架frame的定位

 driver.find_element(By.XPATH, '//*[@id="navs"]/ul/li[2]/a').//click()真正元素定位

元素变化

//*[@id="auto-id-ri6QaGIEhN3bTxsA"]

//*[@id="auto-id-ghlNbd98dkqJFidB"]

//*[@id="auto-id-4SCakBx15gzHDRud"]

# 定位以 auto-id- 开头的 id 元素

element = driver.find_element(By.XPATH, '//*[starts-with(@id, "auto-id-")]')

成功://*[@id="fanwe_success_box"]/table/tbody/tr/td[2]/div[2]
失败://*[@id="fanwe_error_box"]/table/tbody/tr/td[2]/div[2]
# 不管是正例和反例的提示信息都要进行获取
# 可以通过手写xpath以**开头进行定位
text = driver.find_element(By.XPATH, '//*[starts-
with(@id,"fanwe_")]/table/tbody/tr/td[2]/div[2]').text
//把变化的去掉留下固定的就好

转换路径法

当搜索按钮实在定位不到,可以用回车键替代

from selenium.webdriver.common.keys import Keys# 输入完直接按回车 = 搜索search_input = self.driver.find_element(By.CSS_SELECTOR,

'[placeholder="搜索"]')

search_input.send_keys(search_key)

search_input.send_keys(Keys.ENTER)  # 回车触发搜索

  • 断言知识

✅ 五、常见断言方法总结(Python)

断言方法

说明

assert x == y

相等

assert x in y

包含

assert x.startswith(y)

以...开头

assert elem.is_displayed()

元素可见

assert elem.is_enabled()

元素可操作

self.assertEqual(a, b)

unittest 相等断言

self.assertIn(a, b)

unittest 包含断言

self.assertTrue(expr)

表达式为真

列子:

assert "登录成功" in message, f"期望包含'登录成功',实际是:{message}"

6. 元素存

在性断言

检查某个元素是否存在(注意:不存在会抛异常)。

from selenium.common.exceptions

import NoSuchElementExceptiontry:    

driver.find_element(By.ID, "logout-btn")    

assert True  # 找到了

except NoSuchElementException:    

assert False, "未找到退出按钮"

4. 元素状态断言

检查元素是否可见、可点击、被选中等。

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

elem = driver.find_element(By.ID, "submit-btn")

# 是否可见
assert elem.is_displayed()

# 是否可点击
assert elem.is_enabled()

# 是否被选中(如复选框)
assert elem.is_selected()

# 使用 expected_conditions 做显式等待 + 断言
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.ID, "submit-btn")))

  • 不同应用题模版

功能模块

  1. 切换页面

#切换窗口

handles=self.driver.window_handles#所有句柄

old_handles=self.driver.current_window_handle#当前句柄

self.driver.switch_to.window(handles[-1])#切换到最新的窗口

new_handles=self.driver.current_window_handle

print(f"所有句柄:{handles},切换前句柄:{old_handles},切换后句柄:{new_handles}")

  1. 页面截屏

# 截取当前页面的截图并保存到本地文件driver.save_screenshot('screenshot.png')

  1. 商品管理类

import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import time

class TestProductManagement(unittest.TestCase):
    """商品管理自动化测试套件"""

    def setUp(self):
        """测试前置条件:初始化浏览器和等待对象"""
        self.driver = webdriver.Chrome()  # 确保已安装ChromeDriver
        self.driver.implicitly_wait(10)  # 隐式等待
        self.wait = WebDriverWait(self.driver, 10)  # 显式等待
        self.base_url = "https://your-ecommerce-site.com"  # 替换为实际URL

    def test_login_and_manage_products(self):
        """主测试流程:登录 -> 添加商品 -> 编辑商品 -> 删除商品"""
        driver = self.driver

        try:
            # 1. 登录
            self.login(driver)

            # 2. 导航到商品管理页面
            self.navigate_to_product_management(driver)

            # 3. 添加新商品
            product_name = f"Test Product {int(time.time())}"  # 使用时间戳确保唯一性
            product_price = "99.99"
            self.add_product(driver, product_name, product_price)

            # 4. 验证商品添加成功
            self.verify_product_added(driver, product_name)

            # 5. 编辑商品
            new_price = "88.88"
            self.edit_product(driver, product_name, new_price)

            # 6. 验证商品编辑成功
            self.verify_product_edited(driver, product_name, new_price)

            # 7. 删除商品
            self.delete_product(driver, product_name)

            # 8. 验证商品删除成功
            self.verify_product_deleted(driver, product_name)

        except Exception as e:
            self.fail(f"测试执行过程中发生异常: {str(e)}")

    def login(self, driver):
        """执行登录操作"""
        print("正在执行登录...")
        driver.get(f"{self.base_url}/login")

        # 等待页面加载并定位元素
        username_input = self.wait.until(
            EC.presence_of_element_located((By.ID, "username"))  # 替换为实际定位符
        )
        password_input = driver.find_element(By.ID, "password")  # 替换为实际定位符
        login_button = driver.find_element(By.XPATH, "//button[@type='submit']")  # 替换为实际定位符

        # 输入凭据并提交
        username_input.send_keys("your_username")  # 替换为测试账号
        password_input.send_keys("your_password")  # 替换为测试密码
        login_button.click()

        # 验证登录成功 (等待跳转到主页或出现欢迎信息)
        self.wait.until(
            EC.presence_of_element_located((By.XPATH, "//h1[contains(text(), 'Dashboard')]"))
            # 或者根据实际情况定位
        )
        print("登录成功!")

    def navigate_to_product_management(self, driver):
        """导航到商品管理页面"""
        print("导航到商品管理...")
        # 示例:点击侧边栏的"商品管理"链接
        product_mgmt_link = self.wait.until(
            EC.element_to_be_clickable((By.LINK_TEXT, "商品管理"))  # 替换为实际文本或定位符
        )
        product_mgmt_link.click()
        # 可能需要等待页面加载
        self.wait.until(
            EC.presence_of_element_located((By.ID, "product-list-table"))  # 替换为商品列表的定位符
        )

    def add_product(self, driver, name, price):
        """添加新商品"""
        print(f"添加商品: {name}")
        # 点击"添加商品"按钮
        add_button = self.wait.until(
            EC.element_to_be_clickable((By.ID, "add-product-btn"))  # 替换为实际定位符
        )
        add_button.click()

        # 等待模态框或新页面加载
        name_input = self.wait.until(
            EC.presence_of_element_located((By.ID, "product-name"))  # 替换为实际定位符
        )
        price_input = driver.find_element(By.ID, "product-price")  # 替换为实际定位符
        save_button = driver.find_element(By.ID, "save-product-btn")  # 替换为实际定位符

        # 填写表单
        name_input.send_keys(name)
        price_input.send_keys(price)

        # 保存
        save_button.click()

        # 等待保存成功提示或页面刷新
        self.wait.until(
            EC.invisibility_of_element_located((By.ID, "save-product-btn"))  # 等待保存按钮消失(模态框关闭)
            # 或者等待成功提示出现
        )
        print("商品添加成功!")

    def verify_product_added(self, driver, product_name):
        """验证商品是否已添加到列表中"""
        print("验证商品添加...")
        # 在商品列表中查找新添加的商品
        product_row = self.wait.until(
            EC.presence_of_element_located((By.XPATH, f"//tr[td[contains(text(), '{product_name}')]]"))
        )
        self.assertIsNotNone(product_row, f"未能在列表中找到商品: {product_name}")
        print("商品添加验证通过!")

    def edit_product(self, driver, product_name, new_price):
        """编辑商品信息"""
        print(f"编辑商品: {product_name}")
        # 找到对应商品的"编辑"按钮
        edit_button = self.wait.until(
            EC.element_to_be_clickable((By.XPATH, f"//tr[td[contains(text(), '{product_name}')]]//button[@class='edit-btn']"))
            # 根据实际HTML结构调整XPATH
        )
        edit_button.click()

        # 等待编辑表单加载
        price_input = self.wait.until(
            EC.presence_of_element_located((By.ID, "edit-product-price"))  # 替换为实际定位符
        )
        save_button = driver.find_element(By.ID, "update-product-btn")  # 替换为实际定位符

        # 清除旧价格并输入新价格
        price_input.clear()
        price_input.send_keys(new_price)

        # 保存
        save_button.click()

        # 等待更新完成
        self.wait.until(
            EC.invisibility_of_element_located((By.ID, "update-product-btn"))
        )
        print("商品编辑成功!")

    def verify_product_edited(self, driver, product_name, expected_price):
        """验证商品信息已更新"""
        print("验证商品编辑...")
        # 再次在列表中查找商品,检查价格是否更新
        # 这里简化处理,实际可能需要刷新或重新查找
        price_cell = self.wait.until(
            EC.presence_of_element_located((By.XPATH, f"//tr[td[contains(text(), '{product_name}')]]/td[@class='price-column']"))
            # 定位价格所在的单元格
        )
        actual_price = price_cell.text.strip()
        self.assertEqual(actual_price, expected_price, f"商品价格未更新。期望: {expected_price}, 实际: {actual_price}")
        print("商品编辑验证通过!")

    def delete_product(self, driver, product_name):
        """删除商品"""
        print(f"删除商品: {product_name}")
        # 找到对应商品的"删除"按钮
        delete_button = self.wait.until(
            EC.element_to_be_clickable((By.XPATH, f"//tr[td[contains(text(), '{product_name}')]]//button[@class='delete-btn']"))
        )
        delete_button.click()

        # 处理确认对话框 (通常为浏览器原生弹窗)
        try:
            alert = self.wait.until(EC.alert_is_present())
            alert.accept()  # 点击"确定"
            print("确认删除")
        except TimeoutException:
            print("未检测到确认弹窗,继续...")
            # 如果没有弹窗,可能需要点击模态框中的确认按钮
            # confirm_delete_btn = driver.find_element(By.ID, "confirm-delete")
            # confirm_delete_btn.click()

        # 等待删除完成 (商品行消失或出现成功提示)
        self.wait.until(
            EC.invisibility_of_element_located((By.XPATH, f"//tr[td[contains(text(), '{product_name}')]]"))
        )
        print("商品删除成功!")

    def verify_product_deleted(self, driver, product_name):
        """验证商品已从列表中删除"""
        print("验证商品删除...")
        # 尝试查找已删除的商品,应该找不到
        with self.assertRaises(TimeoutException):
            self.wait.until(
                EC.presence_of_element_located((By.XPATH, f"//tr[td[contains(text(), '{product_name}')]]"))
            )
        print("商品删除验证通过!")

    def tearDown(self):
        """测试后置操作:关闭浏览器"""
        if self.driver:
            self.driver.quit()

if __name__ == "__main__":
    unittest.main(verbosity=2)
  1. 搜索功能类

import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
import time

class TestSearchFunctionality(unittest.TestCase):
    """搜索功能自动化测试套件"""

    def setUp(self):
        """初始化浏览器"""
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(10)
        self.wait = WebDriverWait(self.driver, 10)
        self.base_url = "https://your-website.com"  # 替换为实际URL

    def test_search_scenarios(self):
        """测试不同的搜索场景"""
        driver = self.driver
        driver.get(self.base_url)

        # 确保搜索框存在
        search_input = self.wait.until(
            EC.presence_of_element_located((By.NAME, "q"))  # 通常搜索框的name是'q'或'id'
            # 或者 By.ID, By.CLASS_NAME 等
        )

        # 场景1: 正常搜索 (期望有结果)
        self._test_normal_search(search_input, "laptop")

        # 场景2: 空搜索 (期望有提示或保持原页面)
        self._test_empty_search(search_input)

        # 场景3: 无结果搜索 (期望显示"无结果"提示)
        self._test_no_results_search(search_input, "xyz123abc")

        # 场景4: 搜索建议 (如果支持)
        self._test_search_suggestions(search_input, "lap")

    def _test_normal_search(self, search_input, query):
        """测试正常搜索"""
        print(f"执行正常搜索: '{query}'")
        search_input.clear()
        search_input.send_keys(query)
        search_input.send_keys(Keys.RETURN)  # 模拟回车

        # 等待搜索结果页面加载
        try:
            results_container = self.wait.until(
                EC.presence_of_element_located((By.ID, "search-results"))  # 替换为实际结果容器ID
            )
            # 检查是否有结果 (至少一个结果项)
            result_items = results_container.find_elements(By.CLASS_NAME, "result-item")  # 替换为实际结果项类名
            self.assertGreater(len(result_items), 0, f"搜索 '{query}' 未返回任何结果")
            print(f"正常搜索成功,找到 {len(result_items)} 个结果")
        except TimeoutException:
            self.fail(f"搜索结果页面加载超时")

    def _test_empty_search(self, search_input):
        """测试空搜索"""
        print("执行空搜索")
        search_input.clear()
        search_input.send_keys(Keys.RETURN)

        # 检查行为: 可能是显示提示信息,或者页面无变化
        try:
            # 情况A: 出现错误/提示信息
            error_message = self.driver.find_element(By.CLASS_NAME, "search-error")  # 替换为实际错误类名
            self.assertIn("请输入", error_message.text, "空搜索的错误提示信息不正确")
            print("空搜索 - 错误提示验证通过")
        except NoSuchElementException:
            # 情况B: 页面无变化 (仍在首页或原页面)
            current_url = self.driver.current_url
            # 检查URL是否未变或符合预期 (例如没有跳转到搜索结果页)
            self.assertTrue(
                self.base_url in current_url or "search" not in current_url.lower(),
                "空搜索不应跳转到搜索结果页"
            )
            print("空搜索 - 页面未跳转验证通过")

    def _test_no_results_search(self, search_input, query):
        """测试无结果搜索"""
        print(f"执行无结果搜索: '{query}'")
        search_input.clear()
        search_input.send_keys(query)
        search_input.send_keys(Keys.RETURN)

        try:
            # 等待搜索结果容器
            results_container = self.wait.until(
                EC.presence_of_element_located((By.ID, "search-results"))
            )
            # 检查是否显示"无结果"信息
            no_results_element = results_container.find_element(By.CLASS_NAME, "no-results")  # 替换为实际类名
            self.assertIsNotNone(no_results_element, "未显示'无结果'提示")
            self.assertIn("未找到", no_results_element.text, "无结果提示信息不正确")
            print("无结果搜索验证通过")
        except TimeoutException:
            self.fail("搜索结果页面加载超时")
        except NoSuchElementException:
            # 检查结果列表是否为空
            result_items = self.driver.find_elements(By.CLASS_NAME, "result-item")
            self.assertEqual(len(result_items), 0, "无结果搜索返回了结果")
            print("无结果搜索 - 结果为空验证通过")

    def _test_search_suggestions(self, search_input, partial_query):
        """测试搜索建议 (自动补全)"""
        print(f"测试搜索建议: 输入 '{partial_query}'")
        search_input.clear()
        search_input.send_keys(partial_query)

        # 等待建议下拉框出现
        try:
            suggestions_dropdown = self.wait.until(
                EC.visibility_of_element_located((By.CLASS_NAME, "suggestions-dropdown"))  # 替换为实际类名
            )
            # 获取建议列表
            suggestions = suggestions_dropdown.find_elements(By.CLASS_NAME, "suggestion-item")  # 替换为实际类名
            self.assertGreater(len(suggestions), 0, "搜索建议未出现")

            # 检查第一个建议是否包含输入的部分
            first_suggestion_text = suggestions[0].text.lower()
            self.assertIn(partial_query.lower(), first_suggestion_text,
                          f"搜索建议 '{first_suggestion_text}' 不包含查询词 '{partial_query}'")

            print(f"搜索建议测试通过,找到 {len(suggestions)} 个建议")

            # 可选: 点击一个建议并验证跳转
            # suggestions[0].click()
            # self.wait.until(EC.url_changes(self.driver.current_url))
            # print("点击建议并跳转成功")

        except TimeoutException:
            print("搜索建议未在预期时间内出现 (可能功能未启用或加载慢)")

    def tearDown(self):
        """关闭浏览器"""
        if self.driver:
            self.driver.quit()

if __name__ == "__main__":
    unittest.main(verbosity=2)

页面元素与布局检查

import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

class TestPageElements(unittest.TestCase):
    """页面元素与布局检查测试套件"""

    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(10)
        self.wait = WebDriverWait(self.driver, 10)
        self.base_url = "https://your-website.com"

    def test_homepage_elements(self):
        """测试主页关键元素"""
        driver = self.driver
        driver.get(self.base_url)

        # 1. 验证页面标题
        expected_title = "Your Website Title"
        self.assertEqual(driver.title, expected_title, f"页面标题不匹配。期望: {expected_title}, 实际: {driver.title}")

        # 2. 验证Logo存在且可见
        logo = self.wait.until(
            EC.visibility_of_element_located((By.ID, "logo"))  # 或 By.CLASS_NAME, By.CSS_SELECTOR
        )
        self.assertTrue(logo.is_displayed(), "Logo未显示")
        self.assertTrue(logo.size['height'] > 0 and logo.size['width'] > 0, "Logo尺寸为0")

        # 3. 验证主导航菜单
        nav_menu = self.wait.until(
            EC.presence_of_element_located((By.ID, "main-nav"))
        )
        self.assertTrue(nav_menu.is_displayed(), "主导航菜单未显示")

        # 检查关键导航链接
        expected_links = ["首页", "产品", "关于我们", "联系我们"]
        for link_text in expected_links:
            try:
                nav_link = driver.find_element(By.LINK_TEXT, link_text)
                self.assertTrue(nav_link.is_displayed(), f"导航链接 '{link_text}' 未显示")
                self.assertTrue(nav_link.get_attribute("href"), f"导航链接 '{link_text}' 缺少 href")
            except NoSuchElementException:
                self.fail(f"未找到导航链接: {link_text}")

        # 4. 验证搜索框
        search_input = driver.find_element(By.NAME, "q")
        self.assertTrue(search_input.is_displayed(), "搜索框未显示")
        self.assertEqual(search_input.get_attribute("placeholder"), "搜索...", "搜索框占位符不正确")

        # 5. 验证页脚信息
        footer = self.wait.until(
            EC.presence_of_element_located((By.TAG_NAME, "footer"))
        )
        self.assertTrue(footer.is_displayed(), "页脚未显示")

        # 检查版权信息
        copyright_text = footer.find_element(By.CLASS_NAME, "copyright").text
        self.assertIn("©", copyright_text, "页脚版权信息缺少 © 符号")
        current_year = str(time.localtime().tm_year)
        self.assertIn(current_year, copyright_text, f"页脚版权年份应包含 {current_year}")

        # 6. 验证关键内容区域 (例如轮播图)
        try:
            carousel = driver.find_element(By.ID, "hero-carousel")
            self.assertTrue(carousel.is_displayed(), "首页轮播图未显示")
        except NoSuchElementException:
            print("首页轮播图元素未找到,跳过检查")

    def tearDown(self):
        if self.driver:
            self.driver.quit()

if __name__ == "__main__":
    unittest.main(verbosity=2)
  • 案例展示

Web自动化知识
一、考前准备
Pip install pytest
Pip install selenium
Pip install selenium.webdriver.(显示等待)
生成 requirements.txt 文件
安装好所有依赖包后,可以使用以下命令生成 requirements.txt 文件。
pip freeze >requirements.txt
这条命令会将当前虚拟环境中的所有已安装包及其版本信息输出到requirements.txt 文件中。
使用 requirements.txt 文件安装依赖
在新的环境或其他开发人员的机器上,可以使用requirements.txt 文件来安装项目的所有依赖包。
首先,确保激活虚拟环境,然后运行以下命令:
pip install -r requirements.txt
这条命令会读取 requirements.txt 文件并安装其中列出的所有依赖包。

环境搭建
#导包
#指定驱动服务更快速
import time
from selenium import webdriver
#创建浏览器对象
driver=webdriver.Chrome()
# 打开商品管理页面
driver.get("https://litemall.hogwarts.ceshiren.com/")
#页面最大化
driver.maximize_window()
time.sleep(5)
#关闭驱动
driver.quit()

二、元素定位及找不到怎么办
元素定位
name
driver.find_element(By.NAME,"password").clear() ​
id
driver.find_element(By.ID,"password") ​
LINK_TEXT(找不到元素试试直接中文)
driver.find_element(By.LINK_TEXT, "通讯录").click()
tag name
xpath
1.有明确文本的:driver.find_element(By.XPATH,"//*[text()='商品列表']")
2.输入框输入"//label[text()='商品编号']/following-sibling::div//input"
利用页面结构(label + 输入框)进行相对定位,非常稳定,适合表单输入
3.包含文本匹配://*[contains(text(), '商品')]
用途:查找文本中包含“商品”的任意元素。
4.部分匹配
✅ XPath 中的部分匹配函数
匹配类型	CSS Selector	XPath
以...开头	[attr^='value']	starts-with(@attr, 'value')
以...结尾	[attr$='value']	ends-with(@attr, 'value')
包含...	[attr*='value']	contains(@attr, 'value')

css_selector
id,#开头
class,.开头
部分匹配
self.driver.find_element(By.CSS_SELECTOR, "input[id^='user']") # id 以 user 开头 self.driver.find_element(By.CSS_SELECTOR, "input[id$='Name']") # id 以 Name 结尾# self.driver.find_element(By.CSS_SELECTOR, "input[class*='input']") # class 包含 input
calss_name(多个名选取其中一个)
PARTIAL_LINK_TEXT = "partial link text"


页面没有加载完成
显示等待
#下载 pip install selenium.webdriver.
 #导入包 
 
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC 

el = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH, '//* [@id="1"]/div/h3/a'))) # driver.find_element(By.XPATH, '//*[@id="1"]/div/h3/a').click() el.click() 
隐式等待
driver.implicitly_wait(3) 
强制等待
impot time Time.sleep() 
框架内元素不可找
当元素在子页面的frame元素中需要进行切换定位
driver.switch_to.frame(driver.find_element(By.XPATH, '/html/frameset/frame[1]'))
 //大框架frame的定位
 driver.find_element(By.XPATH, '//*[@id="navs"]/ul/li[2]/a').//click()真正元素定位 
元素变化
//*[@id="auto-id-ri6QaGIEhN3bTxsA"]
//*[@id="auto-id-ghlNbd98dkqJFidB"]
//*[@id="auto-id-4SCakBx15gzHDRud"]
# 定位以 auto-id- 开头的 id 元素
element = driver.find_element(By.XPATH, '//*[starts-with(@id, "auto-id-")]')
成功://*[@id="fanwe_success_box"]/table/tbody/tr/td[2]/div[2]
失败://*[@id="fanwe_error_box"]/table/tbody/tr/td[2]/div[2]
# 不管是正例和反例的提示信息都要进行获取
# 可以通过手写xpath以**开头进行定位
text = driver.find_element(By.XPATH, '//*[starts-
with(@id,"fanwe_")]/table/tbody/tr/td[2]/div[2]').text
//把变化的去掉留下固定的就好
转换路径法
当搜索按钮实在定位不到,可以用回车键替代
from selenium.webdriver.common.keys import Keys# 输入完直接按回车 = 搜索search_input = self.driver.find_element(By.CSS_SELECTOR, 
'[placeholder="搜索"]')
search_input.send_keys(search_key)
search_input.send_keys(Keys.ENTER)  # 回车触发搜索

三、断言知识
✅ 五、常见断言方法总结(Python)
断言方法	说明
assert x == y	相等
assert x in y	包含
assert x.startswith(y)	以...开头
assert elem.is_displayed()	元素可见
assert elem.is_enabled()	元素可操作
self.assertEqual(a, b)	unittest 相等断言
self.assertIn(a, b)	unittest 包含断言
self.assertTrue(expr)	表达式为真
	
列子:
assert "登录成功" in message, f"期望包含'登录成功',实际是:{message}"
6. 元素存
在性断言
检查某个元素是否存在(注意:不存在会抛异常)。
from selenium.common.exceptions 
import NoSuchElementExceptiontry:    
driver.find_element(By.ID, "logout-btn")    
assert True  # 找到了
except NoSuchElementException:    
assert False, "未找到退出按钮"
4. 元素状态断言
检查元素是否可见、可点击、被选中等。
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
elem = driver.find_element(By.ID, "submit-btn")
# 是否可见
assert elem.is_displayed()
# 是否可点击
assert elem.is_enabled()
# 是否被选中(如复选框)
assert elem.is_selected()
# 使用 expected_conditions 做显式等待 + 断言
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.ID, "submit-btn")))

四、不同应用题模版
1.商品管理类

2.搜索功能类
五、案例展示
import time
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class Test:
    def setup_method(self):
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(10)
        # =======打开测试人论坛========
        self.driver.get("https://ceshiren.com/")
        self.driver.maximize_window()
    def teardown_method(self):
        # driver 退出
        self.driver.quit()
    def close_msg(self):
        # 处理可能出现的弹窗
        if "确定" in self.driver.page_source:
            self.driver.find_element(By.XPATH, '//*[text()="确定"]').click()
    # parametrize 只能在test_ python文件中的test_开头的方法上使用
    # 正向用例
    @pytest.mark.parametrize(
        "search_key",
        [
            "pytest",
            "面试题",
            "a",
            "appium desktop连接真机,start session,出现报错,手机上appium setting打开闪退,但是进程显示是进行中。报错内容:An unknown server-side error occurred while processing the command. Original error: Could not find a connected Android device in 20364ms.",
        ]
    )
    def test_search(self, search_key):
        # =============== 2. 点击搜索按钮 ==============
        self.driver.find_element(By.XPATH, '//*[@id="search-button"]').click()
 
        # =============== 3. 输入搜索关键字 ==============
        ele_send = self.driver.find_element(By.ID, 'search-term')
        ele_send.clear()
        ele_send.send_keys(search_key)
 
        # =============== 4. 点击进入高级搜索页面 ==============
        ele = WebDriverWait(self.driver, 10).until(
            EC.visibility_of_element_located((By.CLASS_NAME, 'd-icon-sliders-h'))
        )
        ele.click()
 
        # 等待搜索结果链接可点击
        search_ele = WebDriverWait(self.driver, 5).until(
            EC.element_to_be_clickable((By.CLASS_NAME, "search-link"))
        )
 
        # ✅ 关键修复:滚动到元素可见位置解决长文本测试失败问题
        self.driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", search_ele)
        # 可选:加个小延迟
        time.sleep(0.3)
        # 获取文本
        search_text = search_ele.text
        print(f"高级搜索页面下第一个标题的文本为:{search_text}")
        self.close_msg()  # 处理弹窗
        # --------------- 5. 点击标题 ---------------
        search_ele.click()  # 现在应该可以点击了
 
        # 显式等待跳转后页面加载
        WebDriverWait(self.driver, 5).until(
            EC.visibility_of_element_located((By.XPATH, '//*[@class="fancy-title"]'))
        )
        # 断言
        result_page_title = self.driver.title
        print(f"跳转页面的标题为:{result_page_title}")
        assert search_text in result_page_title
    # 为空
    def test_search_none(self):
        # =============== 2. 点击搜索按钮 ==============
        self.driver.find_element(By.XPATH, '//*[@id="search-button"]').click()
        # =============== 3. 输入搜索关键字 ==============
        ele_send = self.driver.find_element(By.ID, 'search-term')
        ele_send.clear()
        ele_send.send_keys("")
        # 处理可能出现的弹窗
        self.close_msg()
        # =============== 4. 点击进入高级搜索页面 ==============
        ele = WebDriverWait(self.driver, 10).until(
            EC.visibility_of_element_located((By.CLASS_NAME, 'd-icon-sliders-h'))
        )
        ele.click()
        # 点击搜索按钮
        self.driver.find_element(By.CSS_SELECTOR, ".search-cta").click()
        # 获取为空搜索时的提示信息
        msg = self.driver.find_element(By.XPATH, "//*[@class='fps-invalid']").text
        print(f"提示信息为:{msg}")
        # 断言
        assert msg == "您的搜索词过短。"
    # 无搜索结果
    def test_search_no_result(self):
        # =============== 2. 点击搜索按钮 ==============
        self.driver.find_element(By.XPATH, '//*[@id="search-button"]').click()
        # =============== 3. 输入搜索关键字 ==============
        ele_send = self.driver.find_element(By.ID, 'search-term')
        ele_send.clear()
        ele_send.send_keys("1234567890")  # 输入一个不可能存在的关键词
        # 处理可能出现的弹窗
        self.close_msg()
        # =============== 4. 点击进入高级搜索页面 ==============
        ele = WebDriverWait(self.driver, 10).until(
            EC.visibility_of_element_located((By.CLASS_NAME, 'd-icon-sliders-h'))
        )
        ele.click()
        # 点击搜索按钮
        self.driver.find_element(By.CSS_SELECTOR, ".search-cta").click()
        # 获取无搜索结果时的提示信息
        msg = self.driver.find_element(By.CSS_SELECTOR, ".loading-container > h3").text
        print(f"提示信息为:{msg}")
        # 断言
        assert msg == "没有找到更多结果。"



Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐