Python+Selenium实战:TPshop商城注册登录自动化测试入门
简介《PythonSeleniumChrome 自动化测试 TPshop 商城项目实战一——注册、登录练习》是一份面向 Web 自动化测试初学者的实战型 PDF。内容围绕 TPshop 商城注册与登录流程展开系统讲解 Selenium 模块导入、Chrome 驱动实例化、页面打开、元素定位、文本输入、状态校验、隐式等待与显式等待以及 JavaScript 滚动执行等关键操作并通过示例代码演示从注册到登录的完整自动化测试过程。资源包为 1 个 PDF 文件大小约 97KB内容精炼、结构清晰。目前已有 2431 人学习/下载是入门 Web UI 自动化测试的实用参考资料。读者可从中获取完整的功能测试分解步骤学习如何通过错误信息定位验证码、密码格式、两次密码一致性等问题并掌握滚动页面、处理弹窗、后退导航等实战技巧便于迁移到其他 Web 项目的自动化测试中。 很多人问我web自动化测试到底怎么上手最快我的答案一直没变别在demo上耗直接拿一个真实项目跑起来。用pythonseleniumchrome这套组合把TPshop商城的前台注册和登录流程做成自动化脚本是我比较推荐的一条入门路径。TPshop是一个开源商城系统本地部署之后页面结构稳定、业务完整非常适合拿来练习元素定位、等待、断言这些基本功。这篇实战笔记就把环境准备、用例设计、脚本实现和常见坑整个过一遍给正准备动手的朋友做个参照。1. 项目背景与测试环境准备1.1 为什么选TPshop练手TPshop是ThinkPHP开发的开源B2C商城系统虽然商业项目也会选用但对我们练习自动化来说最重要的是两点一是环境可控二是业务齐全。本地搭好之后注册、登录、购物车、下单、个人中心这些模块随便折腾脚本写错也不会影响别人。相比直接用线上商城或公开演示站TPshop不用担心对方改版、封IP、验证码升级测试数据也可以随便造这对自动化练习太友好了。我最早学Selenium时也在各种网站上试过但效果很差——页面元素今天能定位到明天就变了脚本跑两天就废。后来换成TPshop本地部署一口气把注册、登录、商品搜索、加入购物车全写了才算真正把自动化测试的套路摸清楚。如果你是刚开始学我建议你也先从注册、登录这两个模块入手因为这两个业务覆盖了表单操作、按钮点击、页面跳转、错误提示断言等常见场景学会了后面写别的模块就是复制粘贴加改定位。1.2 环境版本匹配Python、Selenium、ChromeDriver一个都不能错环境准备是老生常谈但版本不匹配的坑我见得太多了。先说结论Python用3.7以上Selenium用4.xChrome浏览器用最新稳定版ChromeDriver必须和浏览器的大版本号对应。怎么查打开Chrome地址栏输入chrome://version看“Google Chrome”那行比如120.0.6099.109那么ChromeDriver就去下载120.0.6099开头的版本。这里有一个容易踩的坑如果你还在用Windows 7Chrome官方早就停止支持了最高只能装到109版本ChromeDriver也得选109对应的版本不能用新的120版本。很多新手下载了新版驱动在win7上跑起来直接报“此版本浏览器不支持”之类的错误其实不是代码问题是版本问题。另外Selenium4里推荐用webdriver.Chrome(serviceService(...))方式指定驱动路径你可以手动下载解压后放到固定目录也可以用webdriver-manager自动管理但国内网络环境下自动下载偶尔会失败所以我更建议手动放好至少知道driver在哪。from selenium import webdriver from selenium.webdriver.chrome.service import Service service Service(rD:\driver\chromedriver.exe) driver webdriver.Chrome(serviceservice) driver.get(http://localhost/tpshop) driver.maximize_window()很多老教程写的是webdriver.Chrome()在Selenium4里不指定service也能跑前提是chromedriver已经加入PATH。把driver放到Python安装目录的Scripts文件夹下也算一种方式但多人协作时容易乱各写各的路径反而增加排查成本。我个人的习惯是把driver放在项目目录下的driver/文件夹里用Service去指定这样换机器时只要同步一下代码修改一个路径变量就行不用动系统环境变量。2. 被测系统分析与测试用例设计2.1 TPshop注册/登录模块功能梳理写脚本前一定要先把被测功能梳理清楚。TPshop前台注册、登录的页面逻辑大概是点击“免费注册”进入注册页填写手机号、密码、确认密码有的版本还有图形验证码和短信验证登录页支持手机号/用户名/邮箱登录输入密码后勾选“记住用户名”可以直接登录。不同版本界面略有差异但底层流程基本一致。我习惯把功能点列成一张表写脚本时对照着看避免漏用例。模块功能点自动化关注点注册合法手机号两次密码一致输入框定位、注册成功提示、页面跳转注册重复手机号错误提示文案、停留当前页注册两次密码不一致前端校验提示注册密码长度过短校验规则断言登录正确账号密码登录成功、用户名显示登录错误密码密码错误提示登录空提交必填校验提示列出来后你会发现注册和登录的自动化用例并不复杂真正花时间的是定位元素和等元素出现。对了TPshop注册成功后会跳到登录页或者直接显示成功提示不同版本不一样跑脚本之前先手动点一遍把实际流程记录下来再写断言。这里最关键的一点是预期结果不能写得模棱两可否则后面断言根本不知道要等哪个元素。2.2 先写用例再写脚本避免脚本越写越乱很多新手一上来就开浏览器写代码结果写到后面逻辑全缠在一起。我的习惯是先把用例用中文写出来不写代码逻辑就写前置条件、操作步骤、预期结果。比如正常注册用例可以这么写前置条件——访问注册页步骤——1.输入未注册手机号2.输入密码1234563.确认密码1234564.点击注册按钮预期结果——页面出现“注册成功”提示随后跳转到登录页。有了这个描述代码只是把每一步翻译成Selenium操作。后面如果脚本挂了也能对照用例检查是代码写错了还是被测系统真有bug。这一点在真实项目里特别重要因为自动化测试跑起来失败信息要么是定位失败要么是断言失败用例能帮我们快速区分是脚本问题还是业务问题。你也可以把用例维护在Excel、xmind或者禅道里但练手阶段最直接的方法是写在注释里脚本可读性会好很多。3. 注册模块自动化脚本实现3.1 元素定位优先id/name不行再xpathTPshop的表单元素还算规整很多输入框都带有name属性这就好办多了。按F12打开开发者工具点左上角箭头选中输入框就能看到元素的属性。注册页的手机号输入框一般长这样input namemobile ...密码框是input namepassword ...确认密码框是input namepassword2 ...。用Selenium定位时优先用id、name没有的话再用class_name或xpath。定位原则很简单哪个属性稳定且唯一就用哪个。不要一上来就复制浏览器自动生成的绝对xpath/html/body/div[2]/form/div[1]/input这种页面只要加一个div就全断。更好的是用相对路径加属性比如//input[namemobile]既简洁又稳定。注册按钮可能是a标签带class也可能直接是input typesubmit定位时要注意标签类型不要想当然用CLASS_NAME。from selenium import webdriver from selenium.webdriver.common.by import By driver.find_element(By.NAME, mobile).send_keys(13800138000) driver.find_element(By.NAME, password).send_keys(123456) driver.find_element(By.NAME, password2).send_keys(123456) driver.find_element(By.CLASS_NAME, reg_btn).click()这里send_keys前如果上一次跑过有残留数据最好先clear()一下防止输入框里已经有内容。我一般会在send_keys前加一句driver.find_element(...).clear()或者用Keys.CONTROL a组合键全选再删除保证每次输入都是干净的。还有一种情况是输入框自带默认提示文字直接send_keys会在默认文本后面追加导致手机号位数不对所以清理这一步不要偷懒。3.2 验证码处理与测试数据准备验证码是自动化最头疼的部分。TPshop默认可能开启了图形验证码和短信验证码如果你跑脚本时发现按钮点了没反应大概率就是卡在验证码上。我的处理方式分三种第一有测试环境权限的话直接去后台关闭验证码第二如果开发留了“万能验证码”脚本里填万能码第三通过接口造数据或绕过校验但这是后端联调做的事不推荐在UI自动化里折腾。短信验证码也一样自动化不要试图真的接收短信最好和开发约定一个测试接口或者万能短信验证码。如果你想把短信验证码的流程也自动化可以考虑用代理或数据库去拿验证码但复杂度会高不少而且不稳定个人练习阶段不建议碰。图形验证码的自动化也不是不能做用OCR识别是常见的思路但TPshop的验证码可能带干扰线识别率不高还是关闭或预留万能码最省事。再一个坑是手机号数据。注册用例如果每次都用同一个手机号第二次跑就会提示“手机号已注册”。所以测试数据要生成不重复的。临时做法可以用时间戳后8位拼上运营商前缀import time mobile 139 str(int(time.time()))[-8:] print(mobile)这样每次跑注册脚本都能生成一个大概率不重复的手机号。当然理想做法是把手机号维护在Excel或数据库里跑完后清理数据但对于新手练习动态生成最简单。如果你在跑完用例后希望保留数据也可以把生成的手机号和密码写到日志里方便后续登录用例直接用。3.3 注册流程完整代码与断言完整写一个注册函数把等待、点击、断言都带上。TPshop注册成功后页面上通常会弹一个toast提示比如“恭喜您注册成功”。我们用WebDriverWait等待这个提示元素出现然后取文本断言。from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def test_register(driver): driver.get(http://localhost/tpshop/index.php/Home/User/reg.html) mobile 139 str(int(time.time()))[-8:] driver.find_element(By.NAME, mobile).send_keys(mobile) driver.find_element(By.NAME, password).send_keys(123456) driver.find_element(By.NAME, password2).send_keys(123456) driver.find_element(By.CLASS_NAME, reg_btn).click() toast WebDriverWait(driver, 10).until( EC.visibility_of_element_located((By.CLASS_NAME, layui-layer-content)) ) text toast.text assert 成功 in text, f注册失败提示{text}注意toast的class名称以实际页面为准有可能叫tips或layui-layer-content。我写这个例子时默认是常见的Layer弹层组件如果跑的时候定位不到去页面里看一下真实class。还有如果注册成功会跳转页面toast一闪而过等待条件可以换成“页面URL包含login”或“登录按钮可见”要根据实际表现选断言点。断言语句最好带上错误提示信息用assert 条件, 说明的格式这样测试报告里能看到失败原因而不是只有一个AssertionError。4. 登录模块自动化脚本实现4.1 登录用例与数据准备登录模块相对简单但越简单越容易在断言上偷懒。常见做法是登录成功后随便等两秒就完事这不行我们要断言登录后的页面元素。TPshop登录成功后右上角通常会显示用户名或“退出”按钮用EC.visibility_of_element_located等这个元素出现再取文本做断言。测试数据方面建议先在系统里手动注册或通过SQL插入一个固定账号比如13800138001 / 123456。为什么不用随机账号因为登录脚本的职责是验证登录功能而不是验证注册每次都用固定账号数据稳定断言结果也更可控。固定账号的密码建议满足系统强度要求太简单可能被校验拦截反而干扰用例。我一般会把账号密码放到一个配置文件里比如config.ini或testdata.yaml脚本通过读取文件获取而不是硬编码到代码中。这样以后换环境改账号只需要改配置文件脚本不用动。虽然练手项目不用这么讲究但养成这个习惯后面做项目会很受益。读取配置的代码不复杂但能让脚本干净不少也方便同事接手。4.2 登录脚本实现定位、输入、点击写登录脚本主要分三步打开登录页、填账号密码、点登录按钮。TPshop首页右上角有“登录”链接可以先通过LINK_TEXT定位也可以直接访问登录URL。进入登录页后找到用户名输入框和密码输入框填入数据再点登录。用代码实现大概是driver.get(http://localhost/tpshop/index.php/Home/User/login.html) driver.find_element(By.NAME, username).send_keys(13800138001) driver.find_element(By.NAME, password).send_keys(123456) driver.find_element(By.CLASS_NAME, login_btn).click() userinfo WebDriverWait(driver, 10).until( EC.visibility_of_element_located((By.CLASS_NAME, userinfo)) ) assert 13800138001 in userinfo.text这里有个细节登录页的用户名输入框在TPshop里的name有时是username有时是mobile两种都有可能出现。稳妥做法是先在浏览器里手动看元素结构再写代码。另外登录按钮的class名可能不止一个比如login_btn btnCLASS_NAME不能带空格要取其中一个看起来唯一的类名或者用By.CSS_SELECTOR。很多人卡在这里报错说找不到元素其实不是没这个元素而是class名没写对。4.3 等待策略不要一上来就sleep新手写自动化最爱用time.sleep(3)页面加载慢就改成sleep(5)看着能跑但脚本越来越慢还特别容易偶发失败。正确做法是优先用显式等待。隐式等待driver.implicitly_wait(10)是全局的轮询查找元素直到超时显式等待WebDriverWait更精确可以指定等待某个条件比如按钮可点击、元素可见。我建议全局设一个隐式等待兜底关键操作再用显式等待精确控制。比如点击登录按钮前等按钮可点击login_btn WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.CLASS_NAME, login_btn)) ) login_btn.click()这样等的是“按钮真的可以点”而不是“傻等3秒再点”稳定性会高很多。TPshop首页有些区域是异步加载的如果明明定位到了却一直报element click intercepted大概率是元素被遮住或者还没变成可点击状态这时候就要注意等待条件了。还有一点等待时间不要设置太长一般10秒足够太长会在页面卡死时浪费很多时间。5. 常见问题与排查技巧实录5.1 ChromeDriver版本不匹配报错说了什么最常见的报错是selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version x.y.z这个报错已经告诉你了驱动和浏览器版本不匹配。解决办法就是按前面说的打开chrome://version看浏览器版本号然后去下载对应版本的ChromeDriver别图省事随便装一个。版本号主版本一致基本就行比如浏览器是120驱动也选120.x不用纠结小版本完全一致。补充一个很多人不知道的知识点ChromeDriver不向后兼容老的Chrome。比如Chrome是109你装一个114的ChromeDriver即使报错信息没明说也会导致Chrome无法启动或者崩溃。反过来如果你在win7上用Chrome109就只能用ChromeDriver109及对应的旧版本新驱动在win7上可能直接无法运行。所以环境问题优先从版本匹配上排查不要一上来就怀疑代码写错了。5.2 元素定位不到、提示NoSuchElementException怎么办跑脚本最难受的就是找不到元素。报错NoSuchElementException后先不要急着改定位表达式按下面几步排查第一页面是否真的打开了用driver.current_url和driver.title确认第二元素是否在iframe里如果在需要先driver.switch_to.frame()切进去第三页面是否还没加载完改用显式等待第四元素是不是动态ID比如TPshop有些按钮的id带了时间戳这种就不能用id定位要用name或xpath的相对定位。还有一个比较隐蔽的问题页面上存在多个相同class的元素find_element默认返回第一个可能不是你想要的。比如TPshop登录页和注册页都有“登录”按钮如果你登录页定位用By.CLASS_NAME抓到了隐藏的注册页按钮点击就会失败。这时候要给定位加一层缩小范围的前缀比如driver.find_element(By.XPATH, //div[classlogin_box]//input[namepassword])这样先限定到登录区域再去找密码框能排除不少干扰。如果还找不到就把页面结构截图或打印出来用driver.page_source看看有没有你想要的元素很多时候是页面上根本没有这个字段或者字段是后加载出来的需要加等待。5.3 提升脚本稳定性的几个习惯最后分享几个我在实战中养成的小习惯。第一每个关键步骤前加一行日志比如print(开始输入用户名...)脚本挂了能快速定位到哪一步第二失败时截图保存给driver.get_screenshot_as_file(fail.png)包一层异常处理排查时比看报错更直观第三公共方法尽量封装比如input_text(locator, text)、click_element(locator)别在一个用例里把所有find_element直接铺开第四定位表达式尽量用相对路径能承受页面局部变化。我自己在写TPshop这套练习时最开始也是各种踩坑光是driver版本就换了好几次后来把环境固定成一套才稳定下来。有个排查了半天的案例是登录后断言一直失败最后发现页面上有头像和用户名两个相同class的元素取文本时取到了头像的alt属性。这种问题光看报错根本看不出来一定要把日志和截图结合起来看。跑自动化就是这样同一个坑踩过一次下次就知道怎么躲了这也是练习最大的价值。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联
返回资讯列表 →