# selenium_zentao_demo **Repository Path**: yaxy1234/zentao_test ## Basic Information - **Project Name**: selenium_zentao_demo - **Description**: Web自动化测试实战 | Selenium + Python + pytest + Allure 对禅道系统登录功能完成自动化测试,采用Page Object设计模式与数据驱动,覆盖8个测试场景,集成Allure报告及失败自动截图。用例通过率100%。 - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-04-08 - **Last Updated**: 2026-09-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: 测试 ## README ## ​一、项目概述 本项目是一个基于 Selenium + pytest + Allure 的禅道登录功能自动化测试项目。项目从零开始,逐步构建了一个完整的测试框架,实现了登录功能的数据驱动测试,并集成了专业的测试报告系统。 技术栈: - Selenium WebDriver:浏览器自动化驱动 - pytest:测试框架,支持数据驱动 - Allure:测试报告生成工具 - Python:开发语言 项目结构: ![输入图片说明](images/%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84.png.png) 二、配置环境 禅道:本地部署禅道(官方网站上下载) Edge浏览器下载 EdgeDriver (msedgedriver.exe) 其他插件或者配置 ``` # 安装Selenium pip install selenium # 安装pytest pip install pytest # 安装Allure用于报告 pip install allure-pytest ``` test_basic.py ``` from selenium import webdriver import time import os from dotenv import load_dotenv #加载.env文件 load_dotenv() zentao_loginurl = os.getenv("ZENTAO_LOGIN_URL") driver = webdriver.Edge() # 访问禅道登录页面 driver.get(zentao_loginurl) # 等待 time.sleep(3) # 打印当前页面的标题 print("当前页面标题:", driver.title) driver.quit() ``` ## 三、登录接口测试 ![输入图片说明](images/%E7%99%BB%E5%BD%95%E6%8E%A5%E5%8F%A3%E4%B8%BB%E9%A1%B5.png) 查看页面源代码,注意观察确定元素 ![输入图片说明](images/%E6%9F%A5%E7%9C%8B%E9%A1%B5%E9%9D%A2%E6%BA%90%E4%BB%A3%E7%A0%81.png) ### 1、基础登录接口测试 test_login.py ``` from selenium import webdriver from selenium.webdriver.common.by import By import time import os from dotenv import load_dotenv #加载.env文件 load_dotenv() class ZenTaoLoginTest: def __init__(self): # 获取所有配置 self.login_url = os.getenv("ZENTAO_LOGIN_URL") self.password = os.getenv("MY_PASSWORD") self.username = "admin" def test_login_success(self): self.driver = webdriver.Edge() self.driver.maximize_window() self.driver.get(self.login_url) time.sleep(2) """测试用例1:正常登录""" print("正常登录测试") self.driver.find_element(By.ID, "account").send_keys(self.username) self.driver.find_element(By.NAME, "password").send_keys(self.password) self.driver.find_element(By.ID, "submit").click() time.sleep(3) if "地盘" in self.driver.page_source: print("✅测试通过:登录成功") else: print("❌测试失败:登录未成功") self.driver.quit() def test_login_wrong_password(self): self.driver = webdriver.Edge() self.driver.maximize_window() self.driver.get(self.login_url) time.sleep(2) """测试用例2:密码错误""" print("密码错误测试") self.driver.refresh() time.sleep(1) self.driver.find_element(By.ID, "account").send_keys(self.username) self.driver.find_element(By.NAME, "password").send_keys("wrongpassword") self.driver.find_element(By.ID, "submit").click() time.sleep(2) if "登录失败" in self.driver.page_source: print("✅测试通过:密码错误时正确提示") else: print("❌️测试失败:未显示错误提示") self.driver.quit() if __name__ == "__main__": test = ZenTaoLoginTest() test.test_login_success() test.test_login_wrong_password() ``` ### 2、数据驱动测试登录接口 test_data_driven.py 覆盖8个测试场景:正常登录、密码错误、账号为空、密码为空、账号不存在,输入超长和sql注入 再根据每个不同的用例加入断言assert ``` from selenium import webdriver from selenium.webdriver.common.by import By import time import pytest import os from dotenv import load_dotenv #加载.env文件 load_dotenv() login_url = os.getenv("ZENTAO_LOGIN_URL") my_password = os.getenv("MY_PASSWORD") # 测试数据:[(用户名, 密码, 预期结果类型, 预期包含的文字,错误原因)] test_data = [ ("admin", my_password, "success", "地盘","正常登录"), ("admin", "wrong", "fail", "登录失败","密码错误"), ("", "123456", "fail", "登录失败","账号为空"), ("admin", "", "fail", "登录失败","密码错误"), ("","","fail","登录失败","账号密码为空"), ("nonexist", "123456", "fail", "登录失败","账号不存在"), ("admin", "a" * 1000, "fail", "参数错误", "密码超长(1000位)"), ("admin", "' OR '1'='1", "fail", "登录失败", "SQL注入测试"), ] class TestZenTaoLoginDataDriven: @pytest.mark.parametrize("username,password,expected_type,expected_msg,detail", test_data) def test_login(self, username, password, expected_type, expected_msg,detail): # 每个用例启动新浏览器 driver = webdriver.Edge() driver.maximize_window() driver.get(login_url) time.sleep(1) # 输入账号密码 driver.find_element(By.ID, "account").send_keys(username) driver.find_element(By.NAME, "password").send_keys(password) driver.find_element(By.ID, "submit").click() time.sleep(2) # 根据预期类型进行断言 if expected_type == "success": assert expected_msg in driver.page_source print(f"✅登录成功:{username}") else: # 失败场景:检查错误提示 page_text = driver.page_source assert expected_msg in page_text print(f"✅失败场景正确:{username} - {expected_msg} : {detail}") driver.quit() ``` 注意脚本执行,配置需要切换,要不然会找不到函数或者点击函数侧边的运行 ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-08%20171317.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-08%20171344.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-09%20102826.png) 或者也可以直接在终端使用命令行执行 ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-08%20171540.png) ` pytest test_data_driven.py -v -s` 在密码超长的情况,预期返回的是前端提示密码超长,但是实际返回是连续登录错误后的“您还有3次机会”的提示。这说明系统有安全防护设计,但同时也暴露了一个问题:超长密码没有被前置拦截,而是在后端被当作一次失败登录处理。这可以作为优化建议:在前端增加密码长度限制,减少不必要的服务器负载和安全风险。 ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-09%20103021.png) 3、执行生成Allure报告 需要配置 `pip install allure-pytest` test_with_allure.py ``` import os import time import allure from dotenv import load_dotenv from selenium import webdriver from selenium.webdriver.common.by import By #加载.env文件 load_dotenv() login_url = os.getenv("ZENTAO_LOGIN_URL") my_password = os.getenv("MY_PASSWORD") @allure.feature("禅道登录功能") class TestZenTaoWithAllure: @allure.story("正常登录") @allure.title("使用正确的账号密码登录") def test_login_success(self): with allure.step("打开浏览器,访问登录页"): driver = webdriver.Edge() driver.get(login_url) with allure.step("输入账号和密码"): driver.find_element(By.ID, "account").send_keys("admin") driver.find_element(By.NAME, "password").send_keys(my_password) with allure.step("点击登录按钮"): driver.find_element(By.ID, "submit").click() time.sleep(2) with allure.step("验证登录成功"): assert "地盘" in driver.page_source allure.attach(driver.get_screenshot_as_png(), "登录成功截图", allure.attachment_type.PNG) driver.quit() @allure.story("异常登录") @allure.title("使用错误的密码登录") def test_login_wrong_password(self): with allure.step("打开浏览器,访问登录页"): driver = webdriver.Edge() driver.get(login_url) with allure.step("输入正确账号和错误密码"): driver.find_element(By.ID, "account").send_keys("admin") driver.find_element(By.NAME, "password").send_keys("wrongpassword") with allure.step("点击登录按钮"): driver.find_element(By.ID, "submit").click() time.sleep(2) with allure.step("验证错误提示"): assert "登录失败" in driver.page_source driver.quit() ``` 生成Allure报告并本地查看 ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-08%20173056.png) ![输入图片说明](Allure%E6%8A%A5%E5%91%8A.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-08%20173215.png) ![输入图片说明](images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-04-08%20173202.png) ## 四、总结与思考 ### 1、总结 本项目从零开始构建了一个完整的禅道登录自动化测试框架。通过四个阶段的渐进式开发,首先验证了Selenium环境能正常打开浏览器并访问禅道页面;然后编写了包含成功登录和密码错误两个场景的完整测试脚本,掌握了元素定位和操作模拟等核心技术;接着采用pytest框架实现数据驱动测试,用5组测试数据覆盖了正常登录、密码错误、账号为空、密码为空、账号不存在等多种场景,实现了测试逻辑与数据的分离;最后集成Allure报告系统,通过装饰器和步骤细化生成了专业的可视化测试报告。整个项目还结合.gitignore和.env文件保护了密码等敏感信息,形成了从环境搭建、脚本编写、数据驱动到报告生成的完整自动化测试解决方案。 ### 2、思考与笔记 (1)网站可优化部分-错误提示 建议详细给出错误原因,不同的错误给出不同的提示 目前不管是密码错误还是用户名错误,亦或者是为空,都只是提示“登录失败” (2)网站前端未对超长输入做限制 登录界面未对输入长度做限制,攻击者可利用超长输入导致服务器拒绝服务、性能下降、数据截断或缓冲区溢出等安全风险。 (3)思考By.ID的底层逻辑是什么 driver.find_element(By.ID, "account").send_keys(username)  driver.find_element(By.NAME, "password").send_keys(password)  driver.find_element(By.ID, "submit").click() 填写表单的底层代码逻辑是什么,是否是直接查看页面源代码寻找对应的元素? 本质上是查看页面源代码寻找元素,但 Selenium 做了很多智能处理: 1. 不是直接读取静态源代码,而是通过浏览器驱动获取当前实时的 DOM 树 2. 支持动态内容:即使 JavaScript 修改了页面,也能找到元素 3. 等待机制:可以等待元素出现后再操作 driver.find_element(By.ID, "account") ↓ Selenium 客户端库 (Python) ↓ WebDriver 协议 (HTTP 请求) ↓ 浏览器驱动 (ChromeDriver/EdgeDriver) ↓ 浏览器 DevTools 协议 ↓ 浏览器引擎 (Blink/EdgeHTML) ↓ 查找 DOM 树中的元素 ↓ 返回元素引用 ↓ .send_keys("admin") ↓ 模拟输入事件