Web自动化测试从入门到实战:一套完整的解决方案

你是不是也遇到过这些场景?

每天重复点击同样的功能点,点到怀疑人生。版本上线前通宵回归,几百个功能点一个一个验。终于下定决心做自动化,写完脚本后发现——维护成本比手工还高。

大多数团队自动化失败,不是因为技术不行,而是方法错了。

今天这篇文章,从零开始,手把手教你搭建一套可落地、可维护、可扩展的Web自动化测试框架。

一、技术选型:为什么是这套组合?

Selenium:Web自动化领域的事实标准,支持所有主流浏览器,生态最成熟。

Pytest:Python测试框架天花板。语法简洁、断言强大、插件丰富。

Allure:测试报告不仅好看,还包含步骤、截图、日志、趋势图。

二、环境准备:三步搞定

第一步:安装Python

访问 python.org 下载3.8以上版本,安装时记得勾选”Add Python to PATH”。

python --version

第二步:安装依赖

mkdir web_auto_test && cd web_auto_test
python -m venv venv
venv\Scripts\activate  # Windows
source venv/bin/activate  # Mac/Linux
pip install selenium pytest allure-pytest webdriver-manager

第三步:验证环境

pip list
能看到 selenium、pytest、allure-pytest 就说明安装成功。

三、第一个自动化用例:5分钟上手

需求:打开百度 → 搜索”Selenium自动化测试” → 验证搜索结果

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager

def test_baidu_search():
    # 1. 启动Chrome浏览器
    driver = webdriver.Chrome(
        service=Service(ChromeDriverManager().install())
    )

    try:
        # 2. 打开百度
        driver.get("https://www.baidu.com")
        driver.maximize_window()

        # 3. 输入搜索关键词
        search_box = driver.find_element(By.ID, "kw")
        search_box.send_keys("Selenium自动化测试")

        # 4. 点击搜索按钮
        driver.find_element(By.ID, "su").click()

        # 5. 验证结果
        assert "Selenium" in driver.title, "标题验证失败"
        results = driver.find_elements(By.CSS_SELECTOR, ".result")
        assert len(results) > 0, "未找到搜索结果"

        print(f" 测试通过!找到 {len(results)} 条结果")

    finally:
        driver.quit()

if __name__ == "__main__":
    test_baidu_search()
pytest test_baidu_search.py -v

四、企业级项目结构:Page Object模式

Page Object模式的核心思想:把页面元素和操作封装成类,测试用例只关心业务逻辑。

推荐项目结构

web_auto_test/
├── config/
│   └── config.py         # 环境配置
├── pages/
│   ├── base_page.py      # 基础页面类
│   └── login_page.py     # 登录页面
├── tests/
│   ├── conftest.py       # pytest配置
│   └── test_login.py     # 测试用例
├── reports/              # 测试报告
└── pytest.ini

基础页面类

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

class BasePage:
    """所有页面对象的基类"""

    def __init__(self, driver):
        self.driver = driver
        self.timeout = 10

    def find_element(self, locator):
        return WebDriverWait(self.driver, self.timeout).until(
            EC.presence_of_element_located(locator)
        )

    def click(self, locator):
        self.find_element(locator).click()

    def input_text(self, locator, text):
        element = self.find_element(locator)
        element.clear()
        element.send_keys(text)

    def is_visible(self, locator):
        try:
            WebDriverWait(self.driver, 5).until(
                EC.visibility_of_element_located(locator)
            )
            return True
        except:
            return False

五、实战:登录自动化测试

配置文件

# config/config.py
BASE_URL = "https://your-test-site.com"
USERNAME = "test_user"
PASSWORD = "test_password"
HEADLESS = False

登录页面对象

from selenium.webdriver.common.by import By
from pages.base_page import BasePage

class LoginPage(BasePage):
    USERNAME_INPUT = (By.ID, "username")
    PASSWORD_INPUT = (By.ID, "password")
    LOGIN_BUTTON = (By.CSS_SELECTOR, "button[type='submit']")
    ERROR_MSG = (By.CLASS_NAME, "error-msg")

    def open(self):
        self.driver.get(BASE_URL + "/login")
        return self

    def login(self, username, password):
        self.input_text(self.USERNAME_INPUT, username)
        self.input_text(self.PASSWORD_INPUT, password)
        self.click(self.LOGIN_BUTTON)
        return self

    def get_error_message(self):
        if self.is_visible(self.ERROR_MSG):
            return self.find_element(self.ERROR_MSG).text
        return None

    def is_login_success(self):
        return "dashboard" in self.driver.current_url

Pytest配置和Fixtures

import pytest
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from config.config import *

@pytest.fixture(scope="function")
def driver():
    options = webdriver.ChromeOptions()
    if HEADLESS:
        options.add_argument("--headless")

    driver = webdriver.Chrome(
        service=Service(ChromeDriverManager().install()),
        options=options
    )
    driver.maximize_window()
    driver.implicitly_wait(5)

    yield driver
    driver.quit()

@pytest.fixture(scope="function")
def login_page(driver):
    from pages.login_page import LoginPage
    return LoginPage(driver)

登录测试用例

import pytest
import allure
from config.config import *

@allure.feature("登录模块")
class TestLogin:

    @allure.story("正常登录")
    def test_login_success(self, login_page):
        login_page.open()
        login_page.login(USERNAME, PASSWORD)
        assert login_page.is_login_success(), "登录失败"

    @allure.story("异常登录")
    @pytest.mark.parametrize("username,password,expected_error", [
        ("wrong_user", PASSWORD, "用户名或密码错误"),
        (USERNAME, "wrong_pass", "用户名或密码错误"),
        ("", PASSWORD, "请输入用户名"),
        (USERNAME, "", "请输入密码"),
    ])
    def test_login_failed(self, login_page, username, password, expected_error):
        login_page.open()
        login_page.login(username, password)
        error_msg = login_page.get_error_message()
        assert expected_error in str(error_msg)

六、运行测试与生成报告

# 运行所有测试
pytest tests/ -v --alluredir=reports/allure-results

# 失败重试一次
pytest tests/ -v --alluredir=reports/allure-results --reruns 1

# 生成并打开报告
allure serve reports/allure-results

七、常见问题与解决方案

问题1:元素定位失败

#  不推荐:固定等待
import time
time.sleep(3)

#  推荐:智能等待
from selenium.webdriver.support.ui import WebDriverWait
element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "username"))
)

问题2:动态加载元素

# 等待loading消失
WebDriverWait(driver, 10).until(
    EC.invisibility_of_element_located((By.CLASS_NAME, "loading"))
)

问题3:跨浏览器支持

# Chrome
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

# Firefox
from webdriver_manager.firefox import GeckoDriverManager
driver = webdriver.Firefox(service=Service(GeckoDriverManager().install()))

八、总结

这篇文章我们搭建了一套完整的Web自动化测试框架:

  • Selenium WebDriver — 浏览器自动化
  • Pytest — 测试用例管理
  • Allure — 可视化报告
  • Page Object模式 — 可维护代码结构

三个核心原则

  1. 选对场景比写代码更重要
  2. 架构先行,Page Object让代码更易维护
  3. 持续集成,让自动化真正落地

————————————————-

你在自动化测试中遇到过哪些问题?欢迎在评论区交流!

Leave a Comment

您的邮箱地址不会被公开。 必填项已用 * 标注