今天上午做了一个京东的一个项目的总体流程,仅供参考,,,没有断言的用例就是完美的用例
主要:就是首页中搜索商品,然后点击商品,然后将商品加入购物车,加入购物车后点击去购物车结算,去结算
封装类,自己定义包名,方法名我定义的是firefox.py
firefox.py
#-*- coding:utf-8 -*- # 倒包 from selenium import webdriver # 导入休眠包 import time # 导入枚举包 from enum import Enum # 倒包 from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 定义类继承单元测试 class FireFox(object): # 打开浏览器 def firefox_start(self,url): # 打开浏览器 self.driver = webdriver.Firefox() # 设置最大化 self.driver.maximize_window() # 大爱指定网站 self.driver.get(url) # 设置休眠 self.TimeSleep(ENUMS.FIVE_TIME) pass # 关闭浏览器 def firefox_close(self): # 关闭 self.driver.quit() pass # 静态休眠 def TimeSleep(self,number): time.sleep(number) pass # 隐士休眠 def TimeImplay(self,number): self.driver.implicitly_wait(number) pass # 查找控件方式 8 种 def FindID(self,ID): # 使用显示休眠,一共休眠20秒,每隔0.5秒休眠一次, ids = (By.ID,ID) # 休眠 WebDriverWait(self.driver,ENUMS.TWENTY_TIME,ENUMS.ONE_HALF).until(EC.presence_of_element_located(ids)) return self.driver.find_element_by_id(ID) # 根据id设置点击事件 def ClickID(self,ID): self.FindID(ID).click() # 输入内容 def SendkeysID(self,ID,message): self.FindID(ID).send_keys(message) # 查找控件方式 8 种 def FindName(self, name): # 使用显示休眠,一共休眠20秒,每隔0.5秒休眠一次, names = (By.NAME, name) # 休眠 WebDriverWait(self.driver, ENUMS.TWENTY_TIME, ENUMS.ONE_HALF).until(EC.presence_of_element_located(names)) return self.driver.find_element_by_name(name) # 根据id设置点击事件 def ClickName(self, name): self.FindName(name).click() # 输入内容 def SendkeysName(self, name, message): self.FindName(name).send_keys(message) # 查找控件方式 8 种 def FindClass(self, cls): # 使用显示休眠,一共休眠20秒,每隔0.5秒休眠一次, clss = (By.CLASS_NAME, cls) # 休眠 WebDriverWait(self.driver, ENUMS.TWENTY_TIME, ENUMS.ONE_HALF).until(EC.presence_of_element_located(clss)) return self.driver.find_element_by_class_name(cls) # 根据id设置点击事件 def ClickClass(self, cls): self.FindClass(cls).click() # 输入内容 def SendkeysClass(self, cls, message): self.FindClass(cls).send_keys(message) # 查找控件方式 8 种 def FindXpath(self, xpath): # 使用显示休眠,一共休眠20秒,每隔0.5秒休眠一次, xpaths = (By.XPATH, xpath) # 休眠 WebDriverWait(self.driver, ENUMS.TWENTY_TIME, ENUMS.ONE_HALF).until(EC.presence_of_element_located(xpaths)) return self.driver.find_element_by_xpath(xpath) # 查找控件方式 8 种 def FindXpaths(self, xpath): # 使用显示休眠,一共休眠20秒,每隔0.5秒休眠一次, xpaths = (By.XPATH, xpath) # 休眠 WebDriverWait(self.driver, ENUMS.TWENTY_TIME, ENUMS.ONE_HALF).until(EC.presence_of_element_located(xpaths)) return self.driver.find_elements_by_xpath(xpath) # 根据id设置点击事件 def ClickXpath(self, xpaht): self.FindXpath(xpaht).click() # 输入内容 def SendkeysXpath(self, xpaht, message): self.FindXpath(xpaht).send_keys(message) # 查找控件方式 8 种 def FindLink(self, link): # 使用显示休眠,一共休眠20秒,每隔0.5秒休眠一次, links = (By.LINK_TEXT, link) # 休眠 WebDriverWait(self.driver, ENUMS.TWENTY_TIME, ENUMS.ONE_HALF).until(EC.presence_of_element_located(links)) return self.driver.find_element_by_link_text(link) # 根据id设置点击事件 def ClickLink(self, link): self.FindLink(link).click() # 输入内容 def SendkeysLink(self, linl, message): self.FindLink(linl).send_keys(message) # 查找控件方式 8 种 def FindPaty(self, link): # 使用显示休眠,一共休眠20秒,每隔0.5秒休眠一次, links = (By.PARTIAL_LINK_TEXT, link) # 休眠 WebDriverWait(self.driver, ENUMS.TWENTY_TIME, ENUMS.ONE_HALF).until(EC.presence_of_element_located(links)) return self.driver.find_element_by_partial_link_text(link) # 根据id设置点击事件 def ClickPart(self, link): self.FindPaty(link).click() # 输入内容 def SendkeysPart(self, linl, message): self.FindPaty(linl).send_keys(message) # 查找控件方式 8 种 def FindTag(self, tag): # 使用显示休眠,一共休眠20秒,每隔0.5秒休眠一次, tags = (By.TAG_NAME, tag) # 休眠 WebDriverWait(self.driver, ENUMS.TWENTY_TIME, ENUMS.ONE_HALF).until(EC.presence_of_element_located(tags)) return self.driver.find_element_by_tag_name(tag) # 根据id设置点击事件 def ClickTag(self, tag): self.FindTag(tag).click() # 输入内容 def SendkeysTag(self, tag, message): self.FindTag(tag).send_keys(message) # 查找控件方式 8 种 def FindCss(self, css): # 使用显示休眠,一共休眠20秒,每隔0.5秒休眠一次, csses = (By.CSS_SELECTOR, css) # 休眠 WebDriverWait(self.driver, ENUMS.TWENTY_TIME, ENUMS.ONE_HALF).until(EC.presence_of_element_located(csses)) return self.driver.find_element_by_css_selector(css) # 根据id设置点击事件 def ClickCss(self, css): self.FindCss(css).click() # 输入内容 def SendkeysCss(self, css, message): self.FindCss(css).send_keys(message) # 获取title def getTitle(self): return self.driver.title # 获取当前窗口 def getCurrent_Window(self): return self.driver.current_window_handle # 切换窗口的方法 def switch_to_window(self,current): # 获取所有的窗口 allwindows = self.driver.window_handles # 使用for循环进行切换 for window in allwindows: if window != current: self.driver.switch_to.window(window) # 设置点击事件,以及切换窗口的封装 def ClickID_Window(self,ID): # 获取当前窗口 current_window = self.getCurrent_Window() # 进行点击 self.ClickID(ID) # 休眠五秒 self.TimeSleep(ENUMS.FIVE_TIME) # 切换窗口 self.switch_to_window(current_window) # 设置点击事件,以及切换窗口的封装 def ClickName_Window(self, name): # 获取当前窗口 current_window = self.getCurrent_Window() # 进行点击 self.ClickName(name) # 休眠五秒 self.TimeSleep(ENUMS.FIVE_TIME) # 切换窗口 self.switch_to_window(current_window) # 设置点击事件,以及切换窗口的封装 def ClickClass_Window(self, cls): # 获取当前窗口 current_window = self.getCurrent_Window() # 进行点击 self.ClickClass(cls) # 休眠五秒 self.TimeSleep(ENUMS.FIVE_TIME) # 切换窗口 self.switch_to_window(current_window) # 设置点击事件,以及切换窗口的封装 def ClickXpath_Window(self, xpath): # 获取当前窗口 current_window = self.getCurrent_Window() # 进行点击 self.ClickXpath(xpath) # 休眠五秒 self.TimeSleep(ENUMS.FIVE_TIME) # 切换窗口 self.switch_to_window(current_window) # 设置点击事件,以及切换窗口的封装 def ClickTag_Window(self, tag): # 获取当前窗口 current_window = self.getCurrent_Window() # 进行点击 self.ClickTag(tag) # 休眠五秒 self.TimeSleep(ENUMS.FIVE_TIME) # 切换窗口 self.switch_to_window(current_window) # 设置点击事件,以及切换窗口的封装 def ClickCss_Window(self, css): # 获取当前窗口 current_window = self.getCurrent_Window() # 进行点击 self.ClickCss(css) # 休眠五秒 self.TimeSleep(ENUMS.FIVE_TIME) # 切换窗口 self.switch_to_window(current_window) # 设置点击事件,以及切换窗口的封装 def ClickLink_Window(self, link): # 获取当前窗口 current_window = self.getCurrent_Window() # 进行点击 self.ClickLink(link) # 休眠五秒 self.TimeSleep(ENUMS.FIVE_TIME) # 切换窗口 self.switch_to_window(current_window) # 设置点击事件,以及切换窗口的封装 def ClickPart_Window(self, part): # 获取当前窗口 current_window = self.getCurrent_Window() # 进行点击 self.ClickPart(part) # 休眠五秒 self.TimeSleep(ENUMS.FIVE_TIME) # 切换窗口 self.switch_to_window(current_window) # 通过js定位当前窗口 def switch_to_view_js_ID(self,ID): # 执行 js arguments[0].scrollIntoView(); self.driver.execute_script("arguments[0].scrollIntoView();",self.FindID(ID)) pass # 通过js定位当前窗口 def switch_to_view_js_Name(self, name): # 执行 js self.driver.execute_script("arguments[0].scrollIntoView();", self.FindName(name)) pass # 通过js定位当前窗口 def switch_to_view_js_Class(self, cls): # 执行 js self.driver.execute_script("arguments[0].scrollIntoView();", self.FindClass(cls)) pass # 通过js定位当前窗口 def switch_to_view_js_Xpath(self, xpath): # 执行 js self.driver.execute_script("arguments[0].scrollIntoView();", self.FindXpath(xpath)) pass # 通过js定位当前窗口 def switch_to_view_js_Tag(self, tag): # 执行 js self.driver.execute_script("arguments[0].scrollIntoView();", self.FindTag(tag)) pass # 通过js定位当前窗口 def switch_to_view_js_css(self, css): # 执行 js self.driver.execute_script("arguments[0].scrollIntoView();", self.FindCss(css)) pass # 通过js定位当前窗口 def switch_to_view_js_link(self, link): # 执行 js self.driver.execute_script("arguments[0].scrollIntoView();", self.FindLink(link)) pass # 通过js定位当前窗口 def switch_to_view_js_part(self, part): # 执行 js self.driver.execute_script("arguments[0].scrollIntoView();", self.FindPaty(part)) pass # 切换到frame ID def seitch_to_id_frame(self,ID): # 切换到frame里面 self.driver.switch_to.frame(self.FindID(ID)) # 注意 pass没有任何意义,只是在写代码的时候怕报错,用来占位的 pass # 切换到frame Name def seitch_to_name_frame(self, name): # 切换到frame里面 self.driver.switch_to.frame(self.FindName(name)) # 注意 pass没有任何意义,只是在写代码的时候怕报错,用来占位的 pass # 切换到frame Class def seitch_to_class_frame(self, cls): # 切换到frame里面 self.driver.switch_to.frame(self.FindClass(cls)) # 注意 pass没有任何意义,只是在写代码的时候怕报错,用来占位的 pass # 切换到frame xpath def seitch_to_xpath_frame(self, xpath): # 切换到frame里面 self.driver.switch_to.frame(self.FindXpath(xpath)) # 注意 pass没有任何意义,只是在写代码的时候怕报错,用来占位的 pass # 切换到frame tag def seitch_to_tag_frame(self, tag): # 切换到frame里面 self.driver.switch_to.frame(self.FindTag(tag)) # 注意 pass没有任何意义,只是在写代码的时候怕报错,用来占位的 pass # 切换到frame tag def seitch_to_css_frame(self, css): # 切换到frame里面 self.driver.switch_to.frame(self.FindCss(css)) # 注意 pass没有任何意义,只是在写代码的时候怕报错,用来占位的 pass # 封装断言, 查找控件,获取内容,断言前后是不是一致 def AssertEquilClass(self,self1,cls,expect): # 查找控件,获取内容 self.message = self.FindClass(cls).text # 进行断言 self1.assertEqual(self.message,expect) pass # 通过 title去断言 def AssertEquilTitle(self,self1,expect): # 设置休眠,在这里使用强制等待 self.TimeSleep(ENUMS.FIVE_TIME) # 查找控件,获取内容 self.message = self.getTitle() # 进行断言 self1.assertEqual(self.message,expect) pass # 断言数量 def AssertEquilCount(self,self1,cls,number): # 查询一组控件,进行断言 clses = self.FindClasses(cls) # 进行断言 self1.assertEqual(len(clses), number) pass # 断言控件是不是可见 def AssertTrueID(self,self1,ID): # 设置休眠 给网络请求或者逻辑判断的加载时间 self.TimeSleep(ENUMS.FIVE_TIME) # 进行断言 self1.assertTrue(self.FindID(ID).is_displayed()) # 通过 class 查询一组列表的元素 def FindClasses(self,cls): # 查询cls clss = (By.CLASS_NAME,cls) # 设置休眠,同时检查元素的存在 WebDriverWait(self.driver,ENUMS.TWENTY_TIME,ENUMS.ONE_HALF).until(EC.presence_of_element_located(clss)) # 返回查找控件的数量 return self.driver.find_elements_by_class_name(cls) # 通过指定下标进行点击的 def ClickClasses(self,cls,index): # 进行点击 self.FindClasses(cls)[index].click() # 休眠方式有三种 # 1: 强制休眠 强制休眠,当代码执行到该句代码的时候,进行休眠,当休眠结束执行接写来的代码 # 2: 隐式休眠 隐式休眠,当窗口打开,开始计算休眠时间,这里指定的是浏览器的总共休眠时间,如果这里用到1毛,就在总休眠时间里面减去1秒 # 3: 显示休眠 显式休眠,可以设置指定的休眠时间,同时可以设置每隔几秒检查一次元素右没有加载,如果加载了,休眠时间就结束了 # 查询一组切换窗口的方法 def ClickWindowClsses(self,cls,index): # 获取当前窗口 current = self.driver.current_window_handle # 查询一组控件,进行点击 self.ClickClasses(cls,index) # 设置休眠 这里设置休眠的原因是 1: 有的电脑反应慢,点击完成以后,一会才跳转,而我们的代码执行的比较快,所以需要进行休眠一会再获取所有窗口,不然获取的窗口只有一个 # 2: 我们点击完成以后,这里一般有逻辑判断,需要请求网络加载数据需要时间,所以需要休眠 # 使用强制休眠 设置休眠时间 self.TimeSleep(ENUMS.FIVE_TIME) # 获取所有的窗口 all_window = self.switch_to_window(current) # 定义一个枚举类 class ENUMS(Enum): # 二秒 TWO_TIME = 2 # 五秒 FIVE_TIME = 5 # 10 秒 TEN_TIME = 10 # 20 秒 TWENTY_TIME = 20 # 0.5 秒 ONE_HALF = 0.5
这些封装只是一些基础,用到其他的自己封装 我继续了:为了方便我又封装了京东的url urlutil.py
#-*-coding:utf-8-*- # 测试环境分类 3种 # 1: 生产环境 2: 预生成环境 3: 测试环境 # 1: 生产环境 : 就是线上环境,给用户使用的环境就叫做生产环境,一般在这里我们只允许做功能测试,包括手动点击和跑自动化 # 不允许做性能测试,因为用户在使用,性能测试会占用我们的带宽,同时把服务器搞奔溃,所以坚决不允许的,因为生产环境就是企业的命脉 # 带宽就是我们的网速 比如 1M 2M 20M 100M # 2: 预生产环境: 一般情况下预生产环境用来做性能测试使用,用来给生产环境进行调优,最后把这些调优的技术用到生产环境, # 3: 测试环境: 就是开发用来开发和测试用来测试的,也叫内网环境, # http 请求组成 : 协议头: http:// + IP(比如127.0.0.1一般这里被域名替代掉,在生产环境)+ 端口号(在正式的网络环境里面 # 默认端口好是80我们不用去写他,但是在测试环境一般需要写端口号比如 8080 ) + 路径 # 路径如果是get就拼接参数,如果是post就在body里面请求参数就可以了 # 定义类 类关键字 class 函数关节字 def 类实例化的时候执行的方法 __init__ class URL(object): #类实例化的时候执行的方法 #这个就类似于Java里面的构造函数 def _init_(self): pass # 定义类变量 # 在类里面声明的变量叫做类变量,在函数里面声明的变量叫做局部变量 # 声明生产环境的基本地址 JD_SERVELET="" # # 生命预生产环境 # JD_SERVELET = "" # # 声明测试环境 # JD_SERVELET = "" # 京东登陆 JD_LOGIN="https://passport.jd.com/uc/login?ltype=logout" # 京东主页 JD_MAIN = "https://www.jd.com"
我们自己定义单元测试类
比如说我们做的是购物的流程,我定义的就是shop.py
shop.py
# -*- coding:utf-8 -*- # 导入单元测试 import unittest # 导入工具类 from util import firefoxutil, urlutil # 声明类 继承单元测试 class Shop(unittest.TestCase): # 实例化对象的方法 @classmethod def setUpClass(self): # 实例化工具类 self.firefox = firefoxutil.FireFox() # 实例化 url self.URL = urlutil.URL() pass # 打开浏览器 def setUp(self): # 打开京东主页 self.firefox.firefox_start(self.URL.JD_MAIN) pass # 关闭浏览器 def tearDown(self): # 关闭浏览器 # self.firefox.firefox_close() pass # 购物的测试用例 def test_shop(self): # 输入袜子 self.firefox.SendkeysID("key", u"袜子") # 点击查找按钮 self.firefox.ClickClass("button") # 使用js定位 self.firefox.switch_to_view_js_Class("m-list") #打印长度 获取item列表 #理论上在这里我们应该链接数据库去查询列表,看看和页面展示的是不是一致,或者请求接口,看看接口 #返回的数据和页面是不是一致 # 点击搜索按钮,需要加载网络,所以需要时间,可能会造成断言错误,,所以我们需要使用强制休眠,给网络加载数据提供时间 # self.firefox.TimeSleep(firefoxutil.ENUMS.FIVE_TIME) # #进行断言数量 # self.firefox.AssertEquilCount(self,"p-img",49) # 面试题 : 动态元素如何进行定位? # 首先动态元素一般是列表类型,一般通过查询一组元素来返回一个列表,再通过列表的下标进行点击事件 # 通过xpath获取第一个的内容 ems=self.firefox.FindXpaths("//div[@class='gl-i-wrap']/div[4]/a/em")[0].text #打印内容 print ems # 查询一组元素,同时点击指定坐标 self.firefox.ClickWindowClsses("p-img",0) # 使用断言 self.firefox.AssertEquilTitle(self,ems+u"【图片 价格 品牌 报价】-京东") # 进行定位 通过class self.firefox.switch_to_view_js_Class("crumb-wrap") # 通过 css,查找元素进行定位 点击加入购物车按钮 self.firefox.ClickCss("a#InitCartUrl") #进行断言 self.firefox.AssertEquilTitle(self, u"商品已成功加入购物车") # 通过css点击 到购物车结算按钮 self.firefox.ClickCss("a#GotoShoppingCart") # 进行断言 self.firefox.AssertEquilTitle(self, u"我的购物车 - 京东商城") # 点击 去结算按钮 通过 css进行点击 self.firefox.ClickCss("a.submit-btn") # 点击完成提交按钮以后,断言 frame是不是可见,如果可见,说明符合我们的预期,用例通过 self.firefox.AssertTrueID(self,"dialogIframe") # 切换 frame 进行登陆 self.firefox.seitch_to_id_frame("dialogIframe") self.firefox.ClickClass("login-tab-r") self.firefox.SendkeysID("loginname", "18010030176") self.firefox.SendkeysID("nloginpwd", "dong512@al") # 点击登陆 self.firefox.ClickID("loginsubmit") self.firefox.TimeSleep(firefoxutil.ENUMS.FIVE_TIME) self.firefox.AssertEquilTitle(self, u"订单结算页 -京东商城") self.firefox.ClickCss("a.order-submit") self.firefox.AssertEquilTitle(self, u"") 生成测试报告的包suit.py suit.py
#-*- coding:utf-8 -*- # 导入单元测试 import unittest # 导入单元测试 from unit import login,shop # 导入自动化测试报告 import HTMLTestRunner # 导入os包 import os # 设置系统编码格式 # 导入sys import sys # 重新加载 reload(sys) # 设置编码格式 sys.setdefaultencoding("UTF-8") # 注意如果设置以上三句代码,报告有可能还乱码,咱们还需要设置自动化测试报告里面的编码格式 # 实例化套件 suit = unittest.TestSuite() # 将单元测试加入到套件里面 # suit.addTest(unittest.makeSuite(login.Login)) suit.addTest(unittest.makeSuite(shop.Shop)) # 指定自动化测试报告的路径 files = os.getcwd() + "/jd.html" # 设置读写方式 wb 以二进制的方式进行写 rb 以二进制的方式进行读取 rb+ 以二进制的方式既可以读又可以写 filename = open(files,'wb') # 运行自动化测试报告 runner = HTMLTestRunner.HTMLTestRunner(stream=filename,title=u"京东",description=u"京东登陆测试用例") # 运行 runner.run(suit)
到这里差不多就可以运行了,账号密码用自己的,我就不写了,shop里面我主要用的是css如果有自己的方法也是可以的仅供参考。