框架特点:每个模块各司其职(搞清楚每个模块的职责),每个模块又要互相联系(搞清楚模块与模块的调用关系)
学习自动化测试框架的关键:
1.搞清楚框架各个部分的功能和作用
2.搞清楚各个部分之间的调用关系
myunit.py
import unittest
from selenium import webdriver
from common.util import logger,Util
class MyUnit(unittest.TestCase):
def setUp(self) -> None:
logger.info('=======启动测试setUp=========')
self.driver=webdriver.Chrome()
self.driver.get(Util.get_conf()['testUrl'])
self.driver.implicitly_wait(10)
def tearDown(self) -> None:
logger.info('=======结束测试tearDown=========')
self.driver.quit()
util.py
import csv
import yaml
import logging.config
class Util:
@classmethod
def get_conf(cls):
with open('../config/conf.yaml','r',encoding='utf-8') as f:
data=yaml.load(f,Loader=yaml.FullLoader)
return data #以字典格式返回配置文件中的内容
@classmethod
def get_screenshot(cls,driver,path):
driver.get_screenshot_as_file(path)
@classmethod
def get_testdata_by_row(cls,csv_file,line):
logging.info('========开始读取csv file=======')
with open(csv_file, 'r' ,encoding='utf-8') as f:
reader=csv.reader(f)
for index,row in enumerate(reader,1):
if index == line:
return row
conf_file=Util.get_conf()['loggerConfigPath']
logging.config.fileConfig(conf_file)
logger=logging.getLogger()
if __name__=='__main__':
# logger.info('hello world')
print(Util.get_testdata_by_row(Util.get_conf()['testData'],1))
conf.yaml
loggerConfigPath: ../config/logger.conf
screenshotPath: ../screenshots/
testUrl: 'http://192.168.2.200:8080/woniusales'
testData: ../data/login.csv
caseDir: ../test_case
reportDir: ../reports
logger.conf
[loggers]
keys=root,infoLogger
[logger_root]
level=DEBUG
handlers= consoleHandler,fileHandler
[logger_infoLogger]
handlers=consoleHandler,fileHandler
qualname=infoLogger
propagae=0
[handlers]
keys=consoleHandler,fileHandler
[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=form02
args=(sys.stdout,)
[handler_fileHandler]
class=FileHandler
level=INFO
formatter=form01
args=('../log/woniusale.log','a')
[formatters]
keys=form01,form02
[formatter_form01]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
[formatter_form02]
format=%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s
login.csv
basepage.py
class BasePage:
def __init__(self,driver):
self.driver=driver
def find_element(self,*loc):
return self.driver.find_element(*loc)
def find_elements(self, *loc):
return self.driver.find_elements(*loc)
loginpage.py
from pages.basepage import BasePage
from selenium.common.exceptions import NoSuchElementException
from common.util import logger,Util
import time
class LoginPage(BasePage):
username=('id','username')
password=('id','password')
verifycode=('id','verifycode')
login_btn=('xpath','//button[contains(@onclick,"doLogin")]')
welcome_msg=('xpath','//ul[contains(@contains(@class,"navbar-right"))]/li[1]/a')
def login_action(self,un,pw,vc):
logger.info('======开始进行登录操作=======')
logger.info('输入用户名{}'.format(un))
self.find_element(*self.username).send_keys(un)
logger.info('输入密码{}'.format(pw))
self.find_element(*self.password).send_keys(pw)
logger.info('输入验证码{}'.format(vc))
self.find_element(*self.verifycode).send_keys(vc)
logger.info('点击登录按钮')
self.find_element(*self.login_btn).click()
def check_login_status(self):
now = time.strftime('%Y-%m-%d %H %M %S')
try:
str_welcome=self.find_element(*self.welcome_msg).text
except NoSuchElementException:
logger.error('======登录失败========')
Util.get_screenshot(self.driver,Util.get_conf()['screenshotPath']+now+'.png')
return False
else:
if 'admin' in str_welcome:
logger.info('========登录成功========')
return True
else:
logger.error('=======登录失败========')
Util.get_screenshot(self.driver, Util.get_conf()['screenshotPath'] + now + '.png')
return False
membermanagepage.py
import time
from common.util import logger,Util
from pages.basepage import BasePage
class MemberManagePage(BasePage):
phone=('id','customerphone')
name=('id','customername')
add_btn=('xpath','//button[@onclick="addCustomer()"]')
search_btn=('xpath','button[contains(@onclick,"searchCustomer")]')
result_list=('xpath','//tbody[@id="customerList"]/tr')
member_manage_link=('link text','会员管理')
def goto_member_manage(self):
logger.info('======点击会员管理=====')
self.find_element(*self.member_manage_link).click()
def add_action(self,phone,name): #新增会员操作
logger.info("======开始新增会员======")
logger.info('输入手机号',phone)
self.find_element(*self.phone).send_keys(phone)
logger.info('输入会员昵称',name)
self.find_element(*self.name).clear()
self.find_element(*self.name).send_keys(name)
logger.info('点击新增会员按钮')
self.find_element(*self.add_btn).click()
def check_add_action(self,phone):
now = time.strftime('%Y-%m-%d %H %M %S')
self.find_element(*self.phone).clear()
logger.info('输入查询手机号',phone)
self.find_element(*self.phone).send_keys(phone)
logger.info('点击查询按钮')
time.sleep(1)
self.find_element(*self.search_btn).click()
time.sleep(1)
results=self.find_element(*self.result_list)
if len(results)>1:
logger.info('已找到会员记录,新增会员成功')
return True
else:
logger.error('未找到新增会员记录,新增会员失败')
Util.get_screenshot(self.driver, Util.get_conf()['screenshotPath'] + now + '.png')
return False
test_login.py
from common.myunit import MyUnit
from pages.loginpage import LoginPage
from common.util import Util
class LoginTest(MyUnit):
def test_login_success(self):
lp=LoginPage(self.driver)
data=Util.get_testdata_by_row(Util.get_conf()['testData'],1)
lp.login_action(data[0],data[1],data[2])
self.assertTrue(lp.check_login_status())
def test_login_failed_without_username(self):
lp=LoginPage(self.driver)
data=Util.get_testdata_by_row(Util.get_conf()['testData'],2)
lp.login_action(data[0],data[1],data[2])
self.assertFalse(lp.check_login_status())
test_member_manage.py
from common.myunit import MyUnit
from pages.membermanagepage import MemberManagePage
from pages.loginpage import LoginPage
class MemberManage(MyUnit):
def test_add_member_success(self):
lg=LoginPage(self.driver)
lg.login_action('admin','admin123','0000')
mmp=MemberManagePage(self.driver)
mmp.goto_member_manage()
mmp.add_action('13277777777','tester1')
self.assertTrue(mmp.check_add_action('13277777777'))
run.py
import sys
path=r'D:\pythonProject11'
sys.path.append(path)
import time
import unittest
from HTMLTestRunner_cn import HTMLTestRunner
from common.util import Util
test_dir=Util.get_conf()['caseDir']
report_dir=Util.get_conf()['reportDir']
dis=unittest.defaultTestLoader.discover(test_dir,pattern='test*.py')
now=time.strftime('%Y-%m-%d %H %M %S')
report_name=report_dir+'/'+now+' test_report.html'
runner=HTMLTestRunner(
title='woniusales自动化测试报告',
description='v0.1测试报告',
stream=open(report_name,'wb'),
verbosity=2
)
runner.run(dis)
run.bat
@echo off
d:
cd D:\pythonProject11\test_run
D:\Python3.8\python run.py
pause
以linux命令行方式运行