Python UI 自动化 simple framework

UI 自动化 简单框架搭分层结构如下(该框架基于ZenTao网站):

UI framework 简单整合,分为以下几层:
common 框架底层
config  配置文件层
logs   日志层
report 测试报告层
runner 执行层
testcase 测试用例层---> 子套件 ---> 测试用例
webdriver 驱动层

备注:邮件,日志,执行层都是之前封装好的,直接拿过来使用即可。

common 框架底层:

Python UI 自动化 simple framework

email_utils.py

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header

def send_email_fujian(fujian_path,file_name):
    mail_host = "smtp.qq.com"  # 设置服务器
    mail_user = "xx@qq.com"  # 用户名
    mail_pass = "xxxxx"  # 口令

    sender = 'xxx@qq.com'
    receivers = ['xxx@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱

    # 创建一个带附件的实例
    message = MIMEMultipart()
    message['From'] = Header("测试报告", 'utf-8')
    message['To'] = Header("测试", 'utf-8')
    subject = 'Python SMTP 邮件测试'
    message['Subject'] = Header(subject, 'utf-8')

    # 邮件正文内容
    message.attach(MIMEText('这是Python 邮件发送测试……', 'plain', 'utf-8'))

    # 构造附件
    att1 = MIMEText(open(fujian_path, 'rb').read(), 'base64', 'utf-8')
    att1["Content-Type"] = 'application/octet-stream'
    # 这里的filename可以任意写,写什么名字,邮件中显示什么名字
    att1["Content-Disposition"] = 'attachment; filename=report.html'
    message.attach(att1)

    try:
        smtpObj = smtplib.SMTP()
        smtpObj.connect(mail_host, 25)  # 25 为 SMTP 端口号
        smtpObj.login(mail_user, mail_pass)
        smtpObj.sendmail(sender, receivers, message.as_string())
        print("邮件发送成功")
    except smtplib.SMTPException:
        print("Error: 无法发送邮件")

HTMLTestRunner.py 生成测试报告类,网上直接搜索下载使用即可。

Python UI 自动化 simple framework

config 配置文件层

config.ini 配置文件内容为:

[name]
name1 = test
name2 = dev01
name3 = dev02
name4 = test01
name5 = test02

[password]
password1 =xxx123
password2 =xxx123
password3 = xxx123
password4 = xxx123
password5 = xxx123

[zentao_url]
url = http://xx.xxx.xxx.xx/zentao/www/index.php?m=user&f=login

config_utils.py 读取配置内容为:

# 读取配置文件
import configparser, os
config_path = os.path.join(os.path.dirname(__file__), 'config.ini')

class ConfigUtils:
    def __init__(self, cof_path):
        self.config_path = cof_path
        self.conf = configparser.ConfigParser()
        self.conf.read(self.config_path, encoding='utf-8')

    @property
    def get_zentao_url(self):
        return self.conf.get('zentao_url', 'url')

    @property
    def get_name_01(self):
        return self.conf.get('name', 'name1')

    @property
    def get_name_02(self):
        return self.conf.get('name', 'name2')

    @property
    def get_password_01(self):
        return self.conf.get('password', 'password1')

    @property
    def get_password_02(self):
        return self.conf.get('password', 'password2')


config_obj = ConfigUtils(config_path)

logs 层

log_utils.py 日志类:

import logging, os

logs_path = os.path.join(os.path.dirname(__file__), 'python.log')

class LogUtils:
    def __init__(self, log_path=logs_path):
        self.logger = logging.getLogger('写入日志')
        self.logger.setLevel(level=logging.INFO)
        file_log = logging.FileHandler(log_path, encoding='utf-8')
        formatter = logging.Formatter("%(asctime)s -- %(filename)s -- %(levelname)s -- %(message)s")
        file_log.setFormatter(formatter)
        self.logger.addHandler(file_log)

    def info(self, message):
        return self.logger.info(message)

    def error(self, message):
        return self.logger.error(message)

    def debug(self, message):
        return self.logger.debug(message)

    def critical(self, message):
        return self.logger.critical()

    def warning(self, message):
        return self.logger.warning(message)

logs_obj = LogUtils()

生成的日志为:

Python UI 自动化 simple framework

report 测试报告 自动生成

runner 执行层:

run_all_cases.py :

import unittest, HTMLTestRunner, time,os,sys
from common.email_utils import send_email_fujian

if __name__ == '__main__':
    current_path = os.path.dirname(__file__)
    case_path = os.path.join(os.path.dirname(__file__),'../test_cases/')

    all_case = unittest.defaultTestLoader.discover(start_dir=case_path,
                                                   pattern='*_case.py',
                                                   top_level_dir=None)
    main_suit = unittest.TestSuite()
    main_suit.addTest(all_case)

    report_path = current_path + '/../reports/TestReport_' + time.strftime('%Y-%m-%d_%H_%M_%S ', time.localtime(time.time())) + '.html'
    fp = open(report_path, 'w', encoding='utf-8')
    runner = HTMLTestRunner.HTMLTestRunner(stream=fp,
                                           title="ZenTao UI 测试报告",
                                           description="ZenTao UI 用例执行情况")
    runner.run(main_suit)
    send_email_fujian(report_path,'TestReport_' + time.strftime('%Y-%m-%d_%H_%M_%S ', time.localtime(time.time())) + '.html')

testcase 测试用例层---> 子套件 ---> 测试用例

目录接口为:

Python UI 自动化 simple framework

login_success_case.py

import unittest,os, time
from selenium import webdriver
from selenium.webdriver.common.by import By
from config.config_utils import config_obj
from logs.log_utils import logs_obj

driver_path = os.path.join(os.path.dirname(__file__), '../../webdriver/chromedriver.exe')


class LoginSuccessCase(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path=driver_path)
        logs_obj.info('加载浏览器驱动')
        self.driver.maximize_window()
        logs_obj.info('浏览器最大化')
        self.driver.implicitly_wait(10)
        logs_obj.info('隐式等待十秒钟')
        self.driver.get(config_obj.get_zentao_url)
        logs_obj.info('加载禅道的url')

    def tearDown(self):
        self.driver.find_element(By.CSS_SELECTOR,'span.user-name').click()
        self.driver.find_element(By.LINK_TEXT,'退出').click()
        time.sleep(3)
        logs_obj.info('等待3秒钟')
        self.driver.quit()
        logs_obj.info('关闭驱动')

    def test_login_case_01(self):
        self.driver.find_element(By.NAME, 'account').send_keys(config_obj.get_name_01)
        self.driver.find_element(By.NAME, 'password').send_keys(config_obj.get_password_01)
        self.driver.find_element(By.ID, 'submit').click()
        #断言span.user-name
        actual_result = self.driver.find_element(By.CSS_SELECTOR,'span.user-name').text
        self.assertEqual(actual_result,'测试用户','测试用户 登录失败')

    def test_login_case_02(self):
        self.driver.find_element(By.ID, 'account').send_keys(config_obj.get_name_02)
        self.driver.find_element(By.NAME, 'password').send_keys(config_obj.get_password_02)
        self.driver.find_element(By.ID, 'submit').click()
        # 断言
        actual_result = self.driver.find_element(By.CSS_SELECTOR, 'span.user-name').text
        self.assertEqual(actual_result, '开发人员1', '开发人员1 登录失败')

login_success_case.py

import unittest, os, time
from selenium import webdriver
from selenium.webdriver.common.by import By
from config.config_utils import config_obj
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver_path = os.path.join(os.path.dirname(__file__), '../../webdriver/chromedriver.exe')


class LoginFailCase(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path=driver_path)
        self.driver.maximize_window()
        self.driver.implicitly_wait(30)
        self.driver.get(config_obj.get_zentao_url)

    def tearDown(self):
        self.driver.find_element(By.CSS_SELECTOR, 'span.user-name').click()
        self.driver.find_element(By.LINK_TEXT, '退出').click()
        time.sleep(3)
        self.driver.quit()

    def test_login_fail_case_03(self):
        self.driver.find_element(By.NAME, 'account').send_keys(config_obj.get_name_01)
        self.driver.find_element(By.NAME, 'password').send_keys('newdream12')
        self.driver.find_element(By.ID, 'submit').click()
        # 断言span.user-name
        self.assertTrue(WebDriverWait(self.driver, 10).until(EC.alert_is_present()))

    def test_login_fail_case_04(self):
        self.driver.find_element(By.NAME, 'account').send_keys(config_obj.get_name_02)
        self.driver.find_element(By.NAME, 'password').send_keys('newdream12')
        self.driver.find_element(By.ID, 'submit').click()
        # 断言
        self.assertTrue(WebDriverWait(self.driver,10).until(EC.alert_is_present()))

my_success_case.py

import unittest, os, time
from selenium import webdriver
from selenium.webdriver.common.by import By
from config.config_utils import config_obj
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver_path = os.path.join(os.path.dirname(__file__), '../../webdriver/chromedriver.exe')


class LoginFailCase(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path=driver_path)
        self.driver.maximize_window()
        self.driver.implicitly_wait(30)
        self.driver.get(config_obj.get_zentao_url)

    def tearDown(self):
        self.driver.find_element(By.CSS_SELECTOR, 'span.user-name').click()
        self.driver.find_element(By.LINK_TEXT, '退出').click()
        time.sleep(3)
        self.driver.quit()

    def test_login_fail_case_03(self):
        self.driver.find_element(By.NAME, 'account').send_keys(config_obj.get_name_01)
        self.driver.find_element(By.NAME, 'password').send_keys('newdream12')
        self.driver.find_element(By.ID, 'submit').click()
        # 断言span.user-name
        self.assertTrue(WebDriverWait(self.driver, 10).until(EC.alert_is_present()))

    def test_login_fail_case_04(self):
        self.driver.find_element(By.NAME, 'account').send_keys(config_obj.get_name_02)
        self.driver.find_element(By.NAME, 'password').send_keys('newdream12')
        self.driver.find_element(By.ID, 'submit').click()
        # 断言
        self.assertTrue(WebDriverWait(self.driver,10).until(EC.alert_is_present()))

product_success_suit.py

# -- coding: utf-8 --
# @Time : 2022/7/8 16:47
# -- coding: utf-8 --
# @Time : 2022/7/8 16:37
import unittest, os, time
from selenium import webdriver
from selenium.webdriver.common.by import By
from config.config_utils import config_obj

driver_path = os.path.join(os.path.dirname(__file__), '../../webdriver/chromedriver.exe')


class ProductSuccessSuit(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path=driver_path)
        self.driver.maximize_window()
        self.driver.implicitly_wait(30)
        self.driver.get(config_obj.get_zentao_url)

    def tearDown(self):
        time.sleep(3)
        self.driver.quit()

    def test_product_case_06(self):
        self.driver.find_element(By.NAME, 'account').send_keys(config_obj.get_name_01)
        self.driver.find_element(By.NAME, 'password').send_keys(config_obj.get_password_01)
        self.driver.find_element(By.ID, 'submit').click()
        time.sleep(3)
        self.driver.find_element(By.LINK_TEXT, '产品').click()
        actual_result = self.driver.find_element(By.LINK_TEXT, '产品').text
        self.assertEqual(actual_result, '产品', '进入产品模块失败')

webdriver 驱动层:根据电脑上的浏览器种类以及版本下载对应的版本驱动即可:

Python UI 自动化 simple framework

执行run_all_case.py文件生成的测试报告为:

Python UI 自动化 simple framework

最后会在封装的email_utils.py封装的send_email_fujian函数中的receivers的邮箱中收到测试报告。

展开阅读全文

页面更新:2024-05-17

标签:断言   套件   框架   测试报告   浏览器   邮箱   邮件   测试   产品   日志

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top