这是我去年刚刚接触软件测试时写的,时间有点久远,今天想整理一下,可能有些代码设计细节有所遗忘,文章大部分由去年课程汇报的ppt改编而来,见谅!
主要功能:对于126网页邮箱的登陆注册功能进行测试。
项目主要结构介绍:
为了尽量减少代码冗余,本项目代码主要分为三层分别是 base层(基类 页面层重复的代码 公共的方法)page层(页面层 不同页面的具体操作)scripts层(业务层 对页面进行测试)
其余包中为美化项目功能或者非必需内容
项目功能,思路:
由基类提供各种网页自动化方法,再有page层将方法组装成一个新的函数,完成对网页的自动化操作。
调用自身的函数来组成完整的自动化操作
** 为了方便我把所有的xpath元素写到了一个文件中,方便阅读,添加和调用**
项目注意点:
问题1:
注册部分当我们填写手机号时,失去焦点才会出现验证码框
解决方式1:
我第一个想法是既然是失去焦点,那么后续本来就要点击 同意服务条款 ,所以我先进行一次点击单选框的点击事件,输入验证码后再次点击单选框(由于第一次点击是失去焦点并增加验证框,所以并不会勾选,所以需要再次勾选) 事实上这样处理是在这个测试用例中可以的,但是当测试用例变为 手机号码不全或者手机号码格式有问题的时候,这一次的点击单选框事件会触发(应该是由于手机号错误而没有弹出验证框,导致这个事件顺利触发了)那么后续我再次点击时,会导致单选框不被勾选而出错。 那么我提供了两种解决方法,一种是直接失焦,一种点击事件,点击空白处,具体代码在下一页。
问题2:** **
登陆框是被网页内置的一个框架,我们如果直接使用xpath等查询元素的手段,很难定位
解决方式2:
我们要先进入这个iframe,再定位元素。 1.如果自带id或者name driver.switch_to.frame(‘id或者name的值’) 2.没有id或者name,利用xpath,css等 iframe=driver.find_element_by_xpath("...") driver.switch_to.frame(iframe) 3.通过索引,但是一定要记得加s,找错很难看到,错过!!! iframe1=driver.find_elements_by_tag_name("iframe")[0] driver.switch_to.frame(iframe1)
** 问题3:**
元素定位的时候你会发现他的id,class中有很多数字是动态的,应该是时间戳之类的
解决方案3:
**这个其实不难解决,但是需要大家看一下xpath的基本用法或者css。这个其实归根结底是对于元素的定位,我这个项目中其实除了登陆的几个元素(有直接的name,不需要处理)其余的全部都是由xpath定位的,我总结一下这个126邮箱需要会的xpath基础知识(浏览器直接复制的xpath大部分不行,要自己手写)。 **
**1. // 从任意元素开始 **
**2. / 下一层元素 **
**3. /div[2] 这种表示在下一层中第2个div ,类推 **
**4. @属性 某个标签的属性 **
**5. 标签[contains(@属性,”.....”)] “.....”中表示这个属性的值中包含的内容 **
6. 标签[contains(text(),”.....”)] “.....”中表示这个标签的值,内容
源码:
base层(为page层服务):
import time
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
class Base:
# 初始化
def __init__(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.driver.get("https://www.126.com/")
# self.driver.get("https://mail.163.com/register/index.htm?from=126mail&utm_source=126mail")
# 进入内置页面
# def base_find_frame(self):
# iframe1 = self.driver.find_elements_by_tag_name("iframe")[0]
# self.driver.switch_to.frame(iframe1)
#
# def base_return_page(self):
# self.driver.switch_to.default_content()
# 查找元素方法
# 底层方法 return self.find_element(by=By.CSS_SELECTOR, value=css_selector)
def base_find_element(self,loc,timeout=30,poll_frequency=105):
return WebDriverWait(self.driver,timeout=timeout,poll_frequency=poll_frequency).until(lambda x:x.find_element(*loc))
# 点击方法
# 不用解包!!!!! 泪目 找了好久的错
def base_click(self,loc):
self.base_find_element(loc).click()
# 输入方法
def base_input(self,loc,value):
el=self.base_find_element(loc)
#清空
el.clear()
#输入
el.send_keys(value)
# 获取文本方法
def base_get_text(self,loc):
return self.base_find_element(loc).text
# 截图方法
def base_get_png(self):
self.driver.get_screenshot_as_file("../img/fail in {}.png".format(time.strftime("%Y_%m_%d %H_%M_%S")))
page层(写每个页面具体的操作方法,调用base层)
**init.py **
from selenium.webdriver.common.by import By
# 进入登录框
login_frame = By.XPATH, '//iframe[contains(@id,"x-URS-iframe")]'
# 登录框email
login_email = By.NAME, "email"
# 登录框密码
login_password = By.NAME, "password"
# 登录按钮
login_button = By.ID, "dologin"
# 登陆报错
login_err_sign = By.XPATH, '//div[@id="nerror"]/div[2]'
# 写信按钮
write_letter = By.XPATH, '//div[@id="dvNavTop"]/ul/li[2]/span[2]'
# 邮箱地址无效,返回编辑
email_err_return = By.XPATH, '//div[@class="js-component-button nui-btn "]/span[contains(text(),"返回编辑")]'
# 输入收件人邮箱
email_path = By.XPATH, '//div[@class="js-component-emailinput nui-addr nui-editableAddr nui-editableAddr-edit"]/input[@class="nui-editableAddr-ipt"]'
# 去除收件人
del_email = By.XPATH, '//div[contains(@id,"_mail_emailblock")]/a[1]'
# 输入主题
email_title = By.XPATH, '//input[contains(@id,"subjectInput")]'
# 正文框架
email_frame = By.XPATH, '//iframe[@class="APP-editor-iframe"]'
# 输入正文
email_text = By.XPATH, '//body[@class="nui-scroll"]'
# 发送
email_p_button = By.XPATH, '//footer[contains(@class,"jp")]/div[@role="button"]/span[contains(text(),"发送")]'
# 发送成功
email_p_success = By.XPATH, '//h1[contains(@id,"succInfo")]'
# 邮箱格式不对
email_err_geshi = By.XPATH, '//div[contains(@id,"_mail_emailblock")]/@title'
# 无主题时确认
email_notitle_yes = By.XPATH, '//div[contains(@id,"_mail_button")]/span[contains(text(),"确 定")]'
# 注册输入邮箱
register_email = By.XPATH, '//div[@class="item"]/input[@class="username"]'
# 注册输入密码
register_password = By.XPATH, '//div[@class="item"]/input[@class="password"]'
# 注册输入手机
register_tel = By.XPATH, '//div[@class="item"]/input[@class="phone"]'
# 注册单选框
register_alert = By.XPATH, '//div[@class="custom-checkbox service"]/span'
# 注册按钮
register_button = By.XPATH, '//div[@class="register-option"]/a'
# 前往注册
go_register_button = By.XPATH, '//div[@class="loginWrap"]//a[1]'
# 邮箱地址不能为空
register_email_errtext = By.XPATH, '//div[@class="item error"]/div[2]'
# 邮箱密码
register_password_errtext = By.XPATH, '//div[@class="m-register-box-free"]/div[2]/div[@class="tip f-dn"]'
# 手机错误
register_tel_errtext = By.XPATH, '//div[@class="m-register-box-free"]/div[3]/div[@class="tip f-dn"]'
# 验证码错误
register_code_errtext = By.XPATH, '//div[@class="m-register-box-free"]/div[4]/div[@class="tip f-dn"]'
# 不勾选单选
register_gouxuan_errtext = By.XPATH, '//div[@class="custom-checkbox service error"]/div'
# 手机号码错误
register_telephone_errtext = By.XPATH, '//div[@class="m-register-box-free"]/div[3]/div[2]'
# 空白
white_=By.XPATH,'//div[@class="register-container"]'
** page_email.py**
import unittest
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
import page
from base.base import Base
from page.page_login import PageLogin
class PageEmail(Base):
# 点击写信
def email_click_write_letter(self,write_letter):
self.base_click(page.write_letter)
# 填写收件人
def email_write_emailpath(self,email_path):
self.base_input(page.email_path,email_path)
# 填写主题
def email_write_title(self,email_title):
self.base_input(page.email_title,email_title)
# 填写正文
def email_write_text(self,email_text):
self.base_input(page.email_text,email_text)
# 点击发送
def email_click_button(self,email_p_button):
self.base_click(page.email_p_button)
# 处理收件人异常信息
# 处理主题为空
def page_email_write_email(self,email_path,email_title,email_text):
self.pagelogin=PageLogin()
self.pagelogin.page_login("pengyufeng126","abc123,,")
time.sleep(1)
self.base_click(page.write_letter)
self.email_write_emailpath(email_path)
self.email_write_title(email_title)
iframe1 = self.base_find_element(page.email_frame)
self.driver.switch_to.frame(iframe1)
self.email_write_text(email_text)
self.driver.switch_to.default_content()
self.email_click_button()
time.sleep(2)
**page_login.py **
import time
import page
from base.base import Base
class PageLogin(Base):
# 进入内置页面
# def page_in_frame(self,login_frame):
# self.base_find_element(page.login_frame,login_frame)
# 输入账号
def page_input_email(self, login_email):
# self.base_find_frame(0)
self.base_input(page.login_email, login_email)
# 输入密码
def page_input_password(self, login_password):
self.base_input(page.login_password, login_password)
# 点击登录
def page_click_login(self, login_button):
self.base_click(page.login_button)
# 获取异常信息
def page_err_text(self):
return self.base_get_text(page.login_err_sign)
# 账号密码错误截图
def page_login_err(self):
return self.base_get_png()
'''
登陆功能
'''
def page_login(self, login_email, login_password):
time.sleep(1)
iframe1 = self.base_find_element(page.login_frame)
self.driver.switch_to.frame(iframe1)
self.page_input_email(login_email)
self.page_input_password(login_password)
self.base_click(page.login_button)
time.sleep(2)
# self.page_click_login()
# 点击写信
def email_click_write_letter(self,write_letter):
self.base_click(page.write_letter)
# 填写收件人
def email_write_emailpath(self,email_path):
self.base_input(page.email_path,email_path)
# 填写主题
def email_write_title(self,email_title):
self.base_input(page.email_title,email_title)
# 填写正文
def email_write_text(self,email_text):
self.base_input(page.email_text,email_text)
# 无主题时确认
def email_title_none(self):
self.base_click(page.email_notitle_yes)
# 点击发送
def email_click_button(self,email_p_button):
self.base_click(page.email_p_button)
# 错误截图
def email_err_write(self):
return self.base_get_png()
# 获取邮箱格式错误
def email_err_geshi(self):
return self.base_find_element(page.email_err_geshi).text()
'''
写邮件功能
'''
def page_email_write_email(self, email_path, email_title, email_text):
self.page_login("pengyufeng126", "abc123,,")
time.sleep(1)
self.base_click(page.write_letter)
time.sleep(1)
self.email_write_emailpath(email_path)
self.email_write_title(email_title)
iframe1 = self.base_find_element(page.email_frame)
self.driver.switch_to.frame(iframe1)
time.sleep(1)
self.email_write_text(email_text)
self.driver.switch_to.default_content()
time.sleep(1)
self.base_click(page.email_p_button)
time.sleep(1)
if '确定真的不需要写主题吗?' in self.driver.page_source:
self.base_click(page.email_notitle_yes)
self.base_click(page.email_p_button)
time.sleep(1)
**page_register.py **
import time
import page
from base.base import Base
class PageRegister(Base):
# 点击注册
def page_go_register(self,go_register_button):
self.base_click(page.go_register_button)
# 输入邮箱地址
def page_register_email(self,register_email):
self.base_input(page.register_email,register_email)
# 输入密码
def page_register_password(self,register_password):
self.base_input(page.register_password, register_password)
# 输入手机号
def page_register_tel(self,register_tel):
self.base_input(page.register_tel, register_tel)
# 勾选服务条款
def page_register_select(self,register_alert):
self.base_click(page.register_alert)
# 点击注册
def page_register_button(self,register_button):
self.base_click(page.register_button)
# 返回错误提示
def page_register_err1_text(self):
return self.base_get_text(page.register_email_errtext)
def page_register_err2_text(self):
return self.base_get_text(page.register_password_errtext)
def page_register_err3_text(self):
return self.base_get_text(page.register_code_errtext)
def page_register_err4_text(self):
return self.base_get_text(page.register_telephone_errtext)
# 错误截图
def page_register_get_err(self):
return self.base_get_png()
'''
注册功能
'''
def page_register(self,register_email,register_password,register_tel):
# time.sleep(1)
# iframe1 = self.base_find_element(page.login_frame)
# self.driver.switch_to.frame(iframe1)
# self.base_click(page.go_register_button)
self.page_register_email(register_email)
self.page_register_password(register_password)
self.page_register_tel(register_tel)
# self.base_click(page.register_alert)
self.base_click(page.white_)
time.sleep(1)
self.base_click(page.register_alert)
self.base_click(page.register_button)
time.sleep(1)
业务层(测试):
test_email_write.py
import unittest
from parameterized import parameterized
from page.page_login import PageLogin
def get_data():
return [
("[email protected]","测试","测试邮件","邮件发送成功"),
("","测试","测试邮件","请填写收件人地址后再发送"),
("xxxxxx","测试","测试邮件","该地址格式有误,请双击修改"),
("[email protected]","测试","","")
# ("[email protected]","","测试邮件","邮件发送成功"),
# ("[email protected]","","","邮件发送成功")
]
#xxxxxx为你的邮箱账号
class TestWriteEmail(unittest.TestCase):
# setUp
def setUp(self):
# 实例化对象
self.writeemail=PageLogin()
# tearDown
def tearDown(self):
self.writeemail.driver.quit()
# 登陆测试方法
@parameterized.expand(get_data())
def test_login_write01(self,email_path,email_title,email_text,right_result):
self.writeemail.page_email_write_email(email_path,email_title,email_text)
try:
self.assertIn(right_result, self.writeemail.driver.page_source)
except AssertionError:
self.writeemail.email_err_write()
** test_login.py**
import unittest
from page.page_login import PageLogin
from parameterized import parameterized
def get_data():
return [("xxxxxx","","请输入密码"),
("","abc123,,","请输入账号"),
("xxxxxxx", "abc123,,", "账号或密码错误"),
("xxxxxx","abc123,,",""),
("@@aa","abc123,,","帐号格式错误")]
class TestLogin(unittest.TestCase):
# setUp
def setUp(self):
# 实例化对象
self.login=PageLogin()
# self.driver = webdriver.Chrome()
# self.driver.maximize_window()
# self.driver.get("https://www.126.com/")
# tearDown
def tearDown(self):
self.login.page_login_err()
self.login.driver.quit()
# 登陆测试方法
@parameterized.expand(get_data())
def test_login01(self,email,password,right_result):
self.login.page_login(email,password)
# msg=self.login.page_err_text()
# # print(msg)
# try:
# self.assertEqual(msg,right_result)
# except AssertionError:
# self.login.page_login_err()
try:
# assert right_result in self.login.driver.page_source
self.assertIn(right_result,self.login.driver.page_source,"111")
except AssertionError:
self.login.page_login_err()
**text_register.py **
import unittest
from parameterized import parameterized
from page.page_register import PageRegister
def get_data1():
return [("", "abc123,,", "19xxxxxxxx", "邮箱地址不能为空"),
("12344", "abc123,,", "191xxxxx", "长度应为6~18个字符"),
("12344@", "abc123,,", "191xxxxxx", "只能输入字母、数字、下划线"),
("12345678@", "abc123,,", "191216xxxxx", "只能输入字母、数字、下划线")]
def get_data2():
return [("xxxxxxxx", "", "1912xxxxxxx", "密码不能为空"),
("xxxxxxx", "1", "1912xxxxxxx", "密码长度应为8-16个字符"),
("xxxxxxxxxx", "a1234567", "191xxxxxx", '密码需包含“大小写字母、数字、标点符号”中3种以上的组合')]
def get_data3():
return [("xxxx1xxxx", "abc123,,", "1xxxxxxx", "验证码不能为空")]
def get_data4():
return [("xxxxxxx", "abc123,,", "19xxxxx", "请填写正确的中国大陆地区手机号,其他地区手机号请点击此处")]
def get_data5():
return [("xxxxxxx", "abc123,,", "19xxxxx","注册成功")]
#上方数据需要自己改动
class TestRegister(unittest.TestCase):
# setUp
def setUp(self):
# 实例化对象
self.register = PageRegister()
# tearDown
def tearDown(self):
self.register.driver.quit()
# 注册测试方法 没有账号
@parameterized.expand(get_data1())
def test_register01(self, email, password, tel, right_result):
self.register.page_register(email, password, tel)
result = self.register.page_register_err1_text()
self.assertEqual(right_result, result)
self.register.page_register_get_err()
# 注册测试方法,没有密码
@parameterized.expand(get_data2())
def test_register02(self, email, password, tel, right_result):
self.register.page_register(email, password, tel)
result = self.register.page_register_err2_text()
self.assertEqual(right_result, result)
self.register.page_register_get_err()
# 注册测试方法 没有验证码
@parameterized.expand(get_data3())
def test_register03(self, email, password, tel, right_result):
self.register.page_register(email, password, tel)
result = self.register.page_register_err3_text()
self.assertEqual(right_result, result)
self.register.page_register_get_err()
# 注册测试方法 手机号不完整
@parameterized.expand(get_data4())
def test_register04(self, email, password, tel, right_result):
self.register.page_register(email, password, tel)
result = self.register.page_register_err4_text()
self.assertEqual(right_result, result)
# self.assertIn(right_result, self.register.driver.page_source)
self.register.page_register_get_err()
# @parameterized.expand(get_data5())
# def test_register03(self, email, password, tel, right_result):
# self.register.page_register(email, password, tel)
# self.assertIn(right_result, self.register.driver.page_source, "111")
测试报告:
run_htmlrunner.py
import time
import unittest
from lib.HTMLTestRunner import HTMLTestRunner
suite = unittest.defaultTestLoader.discover("../scripts", pattern="text_register.py")
# suite = unittest.defaultTestLoader.discover("../scripts", pattern="text_email_write.py")
report_dir = "report in {}.html".format(time.strftime("%Y_%m_%d %H_%M_%S"))
with open(report_dir, "wb") as f:
HTMLTestRunner(stream=f, verbosity=2, title="自动化测试报告", description="操作系统 win11").run(suite)
本项目测试报告利用HTMLTestRunner形成测试报告
**‘’‘ 定义测试套件 原方法需要实例化unittestTextRunner() 这里在下面实例化HTMLTextRunner() pattern后写test文件’‘’ **
suite = unittest.defaultTestLoader.discover("../scripts", pattern="text_register.py")
**‘’‘ 定义生成文件位置 若使用unittest 自带报告TextTestRunner需要自己建文件夹!!!用时间函数命名 ’‘’ **
report_dir = "report in {}.html".format(time.strftime("%Y_%m_%d %H_%M_%S"))** ‘’‘HTMLTestRunner是经过原生TextTestRunner代码中加入HTML格式的插件 打开文件并写入数据 在html中必须使用wb!!!必填参数只有stream!!!’‘’ **
with open(report_dir, "wb") as f: HTMLTestRunner(stream=f, verbosity=2, title="自动化测试报告", description="操作系统 win11").run(suite)
版权归原作者 大笨钟的笨 所有, 如有侵权,请联系我们删除。