一、总体的框架图:

'''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()
==========================================================================

浙公网安备 33010602011771号