一、总体的框架图:
'''ini是一种配置文件
在ui自动化测试中配置文件的种类
ini、Excel、.py、yaml、txt'''
'''1、先创建一个discz项目
在创建一个cofing包==存放所有配置文件信息(比如项目路径和数据,用例的路径)
可以封装路径
在创建一个Data包==放数据(测试数据)
在Data包中创建一个TestData目录(放测试数据)
测试环境的一些url地址和账号密码可以放在TestDta中
在创建一个repot包==存放测试报告
在repot包中创建一个Testrepot目录(存放报告)
在创建一个public公共公开的包(存放一些功能用例)
在public包中创建pages存放元素层流程层(封装所有页面的公共方法,基类)
在public包中创建utils包(处理公共类公共函数都存放在此)
可以在utils中来读取pages中封装的登录的流程(封装读取ini文件或者EXCEL表格的工具类和工具函数
在创建一个TestCase用例包用来存放用例
编写测试用例
在创建一个run_all用来运行
通过运行测试用例中封装好的用例在运行然后在repot中生成测试报告
框架的思想:把整个用例进行拆分
==========================================================
一、config
配置config包
[project] project_path =C:\Users\Administrator\PycharmProjects\untitled1\discuz [env] url = http://cms.duoceshi.cn/cms/manage/login.do username = admin password = 123456 [email]
import os import time from discuz.public.utils.ReadConfigIni import ReadConfigIni #导入ReadConfigIni类 #获取项目的绝对路径 project_path = os.path.dirname(os.path.dirname(__file__)) print(project_path) #项目绝对路径 project_path = os.path.dirname(os.path.dirname(__file__)) print(project_path) #config绝对路径 config_path = os.path.join(project_path,'cofing') print(config_path) #data绝对路径 data_path = os.path.join(project_path,'data') # print(data_path) #pages绝对路径 pages_path = os.path.join(project_path,'public','pages') print(pages_path) #utils绝对路径 utils_path = os.path.join(project_path,'public','utils') print(utils_path) #repot绝对路径 repot_path = os.path.join(project_path,'repot') # print(repot_path) #run绝对路径 run_path = os.path.join(project_path,'run') print(run_path) #testcase绝对路径 testcase_path = os.path.join(project_path,'testcase') print(testcase_path) #以上路径我们进阶下就ok
==========================================================
二、data
========================================================
三、public
BaseTestCase.py文件
pages:
from selenium import webdriver #导入selenium 引用webdrvier方法 import time #导入time模块 import unittest #导入单元测试框架 class BaseTestcase(unittest.TestCase): #所有页面的公共方法都封装在BaseTestcase这个类中、简称基类一切类的父类需求打开浏览器-输入网址-定位百度输入框元素-输入内容-点击按钮''' @classmethod #类的开始 def set_drvier(cls,driver):#设置drvier对象,需要保证每个用例的执行都是用的同一个drvier对象java当中的设计模块式-单例模式''' cls.driver=driver #cls.drvier就是BaseTestcase这个类的类变量''' # driver=webdriver.Chrome()#为了调试 @classmethod def get_drvier(cls): return cls.driver @classmethod def find_element(cls,element):#封装定位元素的工具方法包含id name class link xpath css等''' # baidu=('id','kw')==传元组 type=element[0] #取element索引为0 value=element[1] #取element索引为1 try: #尝试运行这些代码如果代码报错抛异常 if type =='id'or type=='Id' or type =='ID': elem=cls.driver.find_element_by_id(value) elif type =='name' or type =='Name' or type =='NAME': elem=cls.driver.find_element_by_name(value) elif type =='class' or type =='Class' or type=='CLASS': elem=cls.driver.find_element_by_class_name(value) elif type =='xpath' or type =='Xpath' or type=='XPATH': elem=cls.driver.find_element_by_xpath(value) elif type =='css' or type =='Css' or type=='CSS': elem=cls.driver.find_element_by_css_selector(value) else: raise NameError('请输入正确的参数') except Exception: #如果上面代码定位元素出错,然后这里就会捕捉异常信息 raise NameError('捕捉异常'+str(element)) return elem #把元素返回上去,如果没有抛异常则把属性返回给类函数调用处本身 @classmethod def send_keys(cls,element,text): #封装一个输入 element.send_keys(text) #找到元素后通过.send_keys输入text内容 @classmethod def click(cls,element): #封装一个click点击 element.click() @classmethod def sleep(cls,sec): #封装了一个线程等待 return time.sleep(sec) @classmethod def max_window(cls): #封装了一个窗口最大化 return cls.driver.maximize_window() @classmethod def wait(cls,time): return cls.driver.implicitly_wait(time) @classmethod #封装一个关闭当前浏览器 def close(cls): return cls.driver.close()
==============================================================
Page_Element.py
'''
此模块是为了存放所有页面的元素
Java当中的设计模式:
PO设计模式 ==》全称叫做page object(页面对象模型)
把所有页面上的元素都作为对象的或者类的属性
PO的优势:
1.把元素和流程、案例可以分离
2.让代码的耦合度降低
3.可以让代码更加容易维护
'''
class Page_Element:
#登录模块
userName = ('id','ls_username') #用户名
passWord = ("id","ls_password") #密码
loginBtn = ("css",".pn") #登录按钮
loginOut = ("link","退出") #定位到退出
#模块管理
moduleManage = ("link","模块管理") #定位到模块管理
submit = ("id","submit") #定位到提交
==================================================================
utils:
Login_Data.py
''' 此模块是用来读取Excel文件中的内容 ''' from discuz.public.utils.ReadExcel import ReadExcel #导入ReadExcel类 class Login_Data: @staticmethod def get_url(): ''' 获取测试的url地址 根据ReadExcel类创建对象需要传入2个参数:1个是文件名称、1个是哪一个Sheet页面 Sheet1中的S是一个大写的S''' url = ReadExcel("Data.xlsx","Sheet1").read_excel(1,0) return url #http://192.168.254.129/bbs @staticmethod def get_username(): '''获取测试的账号''' username = ReadExcel("Data.xlsx","Sheet1").read_excel(1,1) return username #admin @staticmethod def get_password(): '''获取测试的密码''' password = ReadExcel("Data.xlsx","Sheet1").read_excel(1,2) return int(password) #把浮点型数据转换为int整型 123456 if __name__ == '__main__': print(Login_Data.get_url()) print(Login_Data.get_username()) print(Login_Data.get_password())
ReadConfigIni.py
#在python当中有一个模块configparser是用来处理ini文件 #pip install configparser #第一种安装方式 import configparser from discuz.config.globalconfig import * class ReadConfigIni: def __init__(self,filename): ''' 这个工具类主要是用来读取ini文件的 :param filename: ''' self.cf = configparser.ConfigParser() #创建configparser类的对象 self.cf.read(filename) def getConfigValue(self,config,name): #获取config 文件的内容 ''' 读取section和option对应的value值 ''' value = self.cf.get(config,name) return value r=ReadConfigIni(os.path.join(config_path,'cofingini')) #传值,我们要去config文件中config的文件 print(r.getConfigValue("path","project_path"))
ReadExcel.py
#此模块是用来读取Excel文档的
#pip install xlrd
import xlrd
import os
from discuz.config.globalconfig import data_path #导入data数据的绝对路径
#data_path的结果为:E:\pycharm\discuz\Data\TestData
class ReadExcel:
def __init__(self,filename,sheetname): #一个构造函数
'''
封装了读取Excel文档的工具类
'''
datapath = os.path.join(data_path,filename) #已经拿到了要读取的Excel文件绝对路径的文件名
self.workbook = xlrd.open_workbook(datapath) #读取Excel文档、并且生成一个对象
self.sheetName = self.workbook.sheet_by_name(sheetname)
def read_excel(self,rownum,colnum):
'''
封装了读取Excel文档具体行和列的工具方法
'''
value = self.sheetName.cell(rownum,colnum).value
return value
r=ReadExcel(data_path,"sheet1")
print(r.read_excel(1,0))
==========================================================
report
========================================================
import unittest from discuz.run_all.HTMLTestRunner3_New import HTMLTestRunner from discuz.TestCase.login import TestLogin from discuz.config.globalconfig import * def auto_run(): # suite = unittest.TestSuite() #创建一个套件、容器 用来装测试用例 # suite.addTests([TestLogin('testLogin')]) discore=unittest.defaultTestLoader.discover(start_dir=project_path,pattern='log*.py') f = open(port_path,"wb") run=HTMLTestRunner(stream=f,title='Discuz论坛项目UI自动化测试报告',description='用例执行情况如下',tester='小钱') run.run(discore) if __name__ == '__main__': auto_run()
=======================================================
TestCase
from discuz.public.pages.BaseTestCase import BaseTestcase #导入BaseTestCase类 import unittest from selenium import webdriver from discuz.public.utils.Login_Data import Login_Data as login #导入Login_Data类并且取别名为login from discuz.public.pages.Page_Element import Page_Element as p #导入Page_Element类并且取别名为p url = login.get_url() #拿到了url地址 username = login.get_username() #拿到了username的值为admin pwd = login.get_password() #拿到了密码 123456 class TestLogin(BaseTestcase): @classmethod def setUpClass(cls): '''测试之前的准备工作''' driver = webdriver.Chrome() #创建一个driver对象 BaseTestcase.set_drvier(driver) #通过父类调用set_driver类方法把driver对象传给父类作为类变量 @classmethod def tearDownClass(cls): BaseTestcase.sleep(3) # def testLogin(self): driver = BaseTestcase.get_drvier() #通过父类调用get_driver类方法拿到driver对象==》打开的浏览器 driver.get(url) #打开论坛的地址 driver.maximize_window() #最大化窗口 BaseTestcase.wait(20) #设置隐式等待 #1.输入用户名 userName = BaseTestcase.find_element(p.userName) BaseTestcase.send_keys(userName,username) #2.输入密码 passWord = BaseTestcase.find_element(p.passWord) BaseTestcase.send_keys(passWord,pwd) #3.点击登录按钮 loginBtn = BaseTestcase.find_element(p.loginBtn) BaseTestcase.click(loginBtn) #4.关闭当前浏览器 # BaseTestcase.sleep(4) #等待4秒 # BaseTestcase.close() #关闭当前浏览器 if __name__ == '__main__': unittest.main()
==========================================================================