【web测试】实战1:去哪儿网购买火车票|优化|po模式
- 测试用例设计
- 1.项目计划
- 2.测试用例
- 项目实战脚本
- 基本代码
- 优化
- 代码重构
- base_function.py
- qunaer_book.py
- test_qunaer_book.py
- data.xlsx
- po模式
- 目录
- base.py
- function.py
- book_ticket_page.py
- book_list_page.py
- book_order_page.py
- test_book.py
测试用例设计
1.项目计划
- 制定测试计划
对象 (What)——什么事情
场所 (Where)——什么地点
时间和程序 (When)——什么时候
人员 (Who)——责任人
为什么(Why)——原因
方式 (How)——如何
通盘考虑能遇见的活动集合及异常风险等问题,提早构思弥补方案 - 测试范围
项目的测试范围,个人的测试范围 - 项目设定目标
- 规划活动
项目简介 | 自动化地实现在去哪儿网订购火车票的目的 |
---|---|
项目启动前置条件 | 1.去哪儿网正常工作 2.自动化测试环境准备完毕 |
项目覆盖场景 | 1.火车票查询页面 2.车次列表页面 3.订票页面 |
2.测试用例
项目实战脚本
- 需求分析
- 业务场景覆盖
- 业务分拆多个页面
- 页面元素分析
- 难点分析
基本代码
from selenium import webdriver
import timefrom selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keysdriver = webdriver.Chrome("chromedriver.exe")
url = "https://www.qunar.com/"
driver.get(url)
driver.maximize_window()
driver.implicitly_wait(5)
action = ActionChains(driver)# 进入“火车票”栏
driver.find_element(By.XPATH, "//*[@id='js_nva_cgy']/li[3]").click()
time.sleep(2)
# 始发站“北京”
driver.find_element(By.NAME, "fromStation").send_keys("北京")
time.sleep(1)
# 点击空白处
action.move_by_offset(0, 0)
action.click()
action.perform()
# 到达站“济南”
driver.find_element(By.NAME, "toStation").send_keys("济南")
time.sleep(2)
# 点击空白处
action.move_by_offset(0, 0)
action.click()
action.perform()
# 定位到“日期”
el_date = driver.find_element(By.NAME, "date")
# 两种删除方法:
# for i in "2022-05-22":
# el_date.send_keys(Keys.BACKSPACE)
el_date.send_keys(Keys.CONTROL, "a")
el_date.send_keys(Keys.BACKSPACE)time.sleep(1)
# 输入日期
el_date.send_keys("2022-05-22")
time.sleep(2)
# 点击空白处
action.move_by_offset(0, 0)
action.click()
action.perform()
# 点击“查询”
driver.find_element(By.NAME, "stsSearch").click()# 点击购买
driver.find_element(By.XPATH, "//*[@id='list_listInfo']/ul[2]/li[2]/div/div[7]/a[1]/span").click()
driver.implicitly_wait(8)# 输入姓名,身份证
driver.find_element(By.NAME, "contact_name").send_keys("张三")
driver.find_element(By.NAME, "contact_phone").send_keys("132809199806011427")time.sleep(4)
driver.quit() # 推出
优化
- 设置出发日期
from datetime import date, datetime, timedelta# n是第几天,n=1 明天,n=2 后天
def date_n(n):# 今天的日期+偏移量return str(date.today() + timedelta(days=int(n)))# 设置出发日期 n从今天往后的第几天
date_1 = date_n(2)
# print(date_1)
- 封装 driver.find_element()
# 封装
def name(element):return driver.find_element(By.NAME, element)def xpath(element):return driver.find_element(By.XPATH, element)
代码重构
- 测试代码层 测试
- 业务代码层 业务
- 基础代码层 准备环境
base_function.py
# 基础代码层
from datetime import date, timedelta
from selenium import webdriver
from selenium.webdriver.common.by import By
import xlrddef date_n(n):# 今天的日期+偏移量return str(date.today() + timedelta(days=int(n)))# driver独立出来
driver = webdriver.Chrome("chromedriver.exe")def get_driver():return driver# 封装find_element
def byname(element):return driver.find_element(By.NAME, element)def xpath(element):return driver.find_element(By.XPATH, element)# url
def open_url(url):driver.get(url)driver.maximize_window()# quit
def close():driver.close()# 读测试用例文件
# ishead 是否有标题,默认没有,如果有则跳过第0行,读取第1行
def read_excel(filename, index, ishead=False):xlsx = xlrd.open_workbook(filename)sheet = xlsx.sheet_by_index(index)data = []for i in range(sheet.nrows):if i == 0:if ishead:continuedata.append(sheet.row_values(i))return data# if __name__ == '__main__':
# print(read_excel("data.xlsx", 0, True))
qunaer_book.py
# 业务代码层
import timefrom selenium.webdriver import ActionChains, Keys
from qunaer.base_function import *def book_ticket(start, end, n, name,id):# 每执行一条用例就新创建一个driverdriver = get_driver()url = "https://www.qunar.com/"open_url(url)driver.implicitly_wait(5)action = ActionChains(driver)# 进入“火车票”栏xpath("//*[@id='js_nva_cgy']/li[3]").click()time.sleep(2)# 选择出发城市el_start = byname("fromStation")el_start.send_keys(Keys.CONTROL, "a")el_start.send_keys(Keys.BACKSPACE)el_start.send_keys(start)time.sleep(1)# 点击空白处action.move_by_offset(0, 0)action.click()action.perform()# 选择到达城市el_end = byname("toStation")el_end.send_keys(Keys.CONTROL, "a")el_end.send_keys(Keys.BACKSPACE)el_end.send_keys(end)time.sleep(2)# 点击空白处action.move_by_offset(0, 0)action.click()action.perform()# 设置出发日期 n从今天往后的第几天date_1 = date_n(n)# print(date_1)# 修改出发日期el_date = byname("date")# 两种删除方法:# for i in "2022-05-22":# el_date.send_keys(Keys.BACKSPACE)el_date.send_keys(Keys.CONTROL, "a")el_date.send_keys(Keys.BACKSPACE)time.sleep(1)el_date.send_keys(date_1)time.sleep(1)# 点击空白处action.move_by_offset(0, 0)action.click()action.perform()# 点击查询byname("stsSearch").click()# 点击购买xpath("//*[@id='list_listInfo']/ul[2]/li[2]/div/div[7]/a[1]/span").click()driver.implicitly_wait(8)# 输入姓名,身份证byname("contact_name").send_keys(name)byname("contact_phone").send_keys(id)time.sleep(2)# close()
test_qunaer_book.py
# 测试层
from qunaer.qunaer_book import book_ticket
from qunaer.base_function import read_excel
import pytestdata = read_excel("data.xlsx", 0, True)# 参数化
@pytest.mark.parametrize(["start", "end", "n", "name", "id"], data)
def test_book_ticket(start, end, n, name, id):# start = "北京"# end = "厦门"# n = 2# name = "张三"# id = 12001199709091234book_ticket(start, end, n, name, id)if __name__ == '__main__':pytest.main(["-s", "test_qunaer_book.py"])
data.xlsx
po模式
page object 页面对象模型:把页面当成对象,把页面中的业务放到一起,web app 中会用到
优点:
- 页面分层 ,将页面元素和业务逻辑进行区分
- 方便复用对象
- 每个页面都是一个独立的测试用例
- 自动化变得更容易
base层:基础的内容
common层:读取文件,日期处理,公共
data层:数据的文件
logs层:日志
po层:页面的逻辑(业务)代码
testcase层:测试层,存放测试代码
reports层:存放测试报告
config:配置文件
目录
base.py
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.by import Byclass Base():def __init__(self, driver):self.driver = driver # type:WebDriverdef byname(self, element):return self.driver.find_element(By.NAME, element)def xpath(self, element):return self.driver.find_element(By.XPATH, element)def open_url(self, url):self.driver.get(url)self.driver.maximize_window()def close(self):self.driver.quit()
function.py
from datetime import date, timedelta
import xlrddef read_excel(filename, index, ishead=False):xlsx = xlrd.open_workbook(filename)sheet = xlsx.sheet_by_index(index)data = []for i in range(sheet.nrows):if i == 0:if ishead:continuedata.append(sheet.row_values(i))return datadef date_n(n):# 今天的日期+偏移量return str(date.today() + timedelta(days=int(n)))
book_ticket_page.py
import time
from selenium.webdriver import ActionChains, Keys
from qunaer_po.base.base import Base# 查询车次页class BookTicket(Base):def wait(self):return self.driver.implicitly_wait(5)def book_into(self):return self.xpath("//*[@id='js_nva_cgy']/li[3]")def book_start(self):return self.byname("fromStation")def book_end(self):return self.byname("toStation")def move_click(self):action = ActionChains(self.driver)action.move_by_offset(0, 0)action.click()action.perform()def book_date(self, date):self.byname("date").send_keys(Keys.CONTROL, "a")self.byname("date").send_keys(Keys.BACKSPACE)self.byname("date").send_keys(date)def book_button(self):return self.byname("stsSearch")def book_ticket(self, start, end, date):# 打开url# url = "https://www.qunar.com/"# self.open_url(url)self.wait()# 进入“火车票”栏self.book_into().click()time.sleep(1)# 选择出发城市self.book_start().send_keys(start)time.sleep(1)# 点击空白处self.move_click()time.sleep(1)# 选择到达城市self.book_end().send_keys(end)time.sleep(1)# 点击空白处self.move_click()time.sleep(1)# 修改出发日期self.book_date(date)time.sleep(1)# 点击空白处self.move_click()time.sleep(1)# 点击查询self.book_button().click()time.sleep(2)
book_list_page.py
# 车次列表页
from qunaer_po.base.base import Base
import timeclass BookList(Base):def book_buy(self):return self.xpath("//*[@id='list_listInfo']/ul[2]/li[2]/div/div[7]/a[1]/span")def book_list(self):self.book_buy().click()time.sleep(2)
book_order_page.py
# 车票预订页
import timefrom qunaer_po.base.base import Baseclass BookOrder(Base):def book_name(self):return self.byname("contact_name")def book_id(self):return self.byname("contact_phone")def book_order(self, name, id):self.book_name().send_keys(name)time.sleep(1)self.book_id().send_keys(id)time.sleep(2)
test_book.py
import pytestfrom qunaer_po.po.book_ticket_page import BookTicket
from qunaer_po.po.book_list_page import BookList
from qunaer_po.po.book_order_page import BookOrder
from selenium import webdriver
from qunaer_po.common.function import read_excel, date_ndata = read_excel("../data/data.xlsx", 0, True)class Test_Book():def setup(self):self.driver = webdriver.Chrome("../chromedriver.exe")url = "https://www.qunar.com/"self.driver.get(url)self.driver.maximize_window()@pytest.mark.parametrize(["start", "end", "n", "name", "id"], data)def test_01(self, start, end, n, name, id):ticket = BookTicket(self.driver)ticket.book_ticket(start, end, date_n(n))list_b = BookList(self.driver)list_b.book_list()order = BookOrder(self.driver)order.book_order(name, id)def teardown(self):self.driver.quit()if __name__ == '__main__':pytest.main(["-s", "test_book.py"])
测试运行中,如何确定上一步正确?
可以设置断言,进入下一页后,查看url地址中有无本页的某段信息,有则说明上一步成功。获取当前url信息 driver.current_url( )