Selenium Web automation practice case, following the code is really fragrant

item background

https://passport.csdn.net/login CSDN login page

function realization

·  Automatically run use cases

·  Automatically generate test reports

·  Automatic assertion and screenshot

Automatically  send the latest test report to the designated mailbox

·  Separation of data and page elements

·  PageObject+Unittest+ddt data-driven use case

Execution  log, distributed execution

Project Architecture

4Browser  Driver Definition

from common.readFile import ReadFile
from common.logger import Logger
from selenium import webdriver
logger = Logger()
from selenium.webdriver import Remote
class Browser():
    def __init__(self):
        config = ReadFile()
        self.browser = config.readConfig("Browser", "browser")
        self.host = config.readConfig("host","host")
        logger.info("You had select {} host {} browser.".format(self.host,self.browser))
    def driver(self):
        """
        启动浏览器驱动
        :return: 返回浏览器驱动URL
        """
        try:
            # driver = webdriver.Chrome()
            driver = Remote(command_executor='http://' + self.host + '/wd/hub',
                            desired_capabilities={ 'platform': 'ANY',
                                                   'browserName': self.browser,
                                                   'version': "",
                                                   'javascriptEnabled': True
                                                }
                            )
            return driver
        except Exception as msg:
            print("驱动异常-> {0}".format(msg))

5Environmental  preparations before and after use case operation

import unittest
from common.driver import Browser
class StartEnd(unittest.TestCase):
    def setUp(self):
        self.driver = Browser().driver()
        self.driver.implicitly_wait(10)
        self.driver.maximize_window()
    def tearDown(self):
        self.driver.quit()

Tool Method Module

It mainly encapsulates some public methods such as: taking screenshots and finding the latest reports.

import time
from selenium import webdriver
import os,sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
from config import setting
def inser_img(driver):
    # 指定截图存放的根目录路径
    screen_dir = setting.TEST_REPORT + '/imges/'
    rq = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
    screen_name = screen_dir + rq + '.png'
    driver.get_screenshot_as_file(screen_name)
    print('screenshot:' + screen_name)
#查找最新的测试报告
def latest_report(report_dir):
    lists = os.listdir(report_dir)
    lists.sort(key=lambda fn: os.path.getatime(report_dir + '\\' + fn))
    file = os.path.join(report_dir, lists[-1])
    return file
def latest_report_img(report_dir):
    lists = os.listdir(report_dir)
    lists.sort(key=lambda fn: os.path.getatime(report_dir + '\\' + fn))
    file = os.path.join(report_dir, lists[-1])
    return file

Pageobject page object encapsulation

base page class

import time
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from common.logger import Logger
from common.readFile import ReadFile
logger = Logger()
class BasePage():
    "定义一个页面基类,让所有页面都继承这个类,封装一些常用的页面操作方法到这个类"
    def __init__(self, driver):
        self.driver = driver
        config = ReadFile()
        self.baseurl = config.readConfig("BaseUrl", "url")
    def open_url(self, url):
        self.driver.get(self.baseurl + url)
    # 退出浏览器
    def quit_browser(self):
        self.driver.quit()
    # 浏览器前进操作
    def forward(self):
        self.driver.forward()
    # 浏览器后退操作
    def back(self):
        self.driver.back()
    # 隐式等待
    def wait(self, seconds):
        self.driver.implicitly_wait(seconds)
    # 查找元素
    def find_element(self, selector):
        selector_by = selector['find_type']
        selector_value = selector['element_info']
        try:
            if selector_by == 'id':
                el = self.driver.find_element_by_id(selector_value)
            elif selector_by == "n" or selector_by == 'name':
                el = self.driver.find_element_by_name(selector_value)
            elif selector_by == 'cs' or selector_by == 'css_selector':
                el = self.driver.find_element_by_css_selector(selector_value)
            elif selector_by == 'cn' or selector_by == 'classname':
                el = self.driver.find_element_by_class_name(selector_value)
            elif selector_by == "lt" or selector_by == 'link_text':
                el = self.driver.find_element_by_link_text(selector_value)
            elif selector_by == "plt" or selector_by == 'partial_link_text':
                el = self.driver.find_element_by_partial_link_text(selector_value)
            elif selector_by == "tn" or selector_by == 'tag_name':
                el = self.driver.find_element_by_tag_name(selector_value)
            elif selector_by == "x" or selector_by == 'xpath':
                el = self.driver.find_element_by_xpath(selector_value)
            elif selector_by == "ss" or selector_by == 'selector_selector':
                el = self.driver.find_element_by_css_selector(selector_value)
            else:
                raise NameError("Please enter a valid type of targeting elements.")
        except NoSuchElementException  :
            logger.error("{0}页面中未能找到{1}元素".format(self, selector_value))
        return el
    # 输入
    def input(self, selector, text):
        el = self.find_element(selector)
        try:
            el.clear()
            el.send_keys(text)
            logger.info("Had type \' %s \' in inputBox" % text)
        except NameError as e:
            logger.error("Failed to type in input box with %s" % e)
    # 点击
    def click(self, selector):
        el = self.find_element(selector)
        try:
            logger.info("The element \' %s \' was clicked." % el.text)
            el.click()
        except NameError as e:
            logger.error("Failed to click the element with %s" % e)
    @staticmethod
    def sleep(seconds):
        time.sleep(seconds)
        logger.info("Sleep for %d seconds" % seconds)
    def get_text(self,selector):
        el = self.find_element(selector)
        try:
            return el.text
        except NameError as e:
            logger.error("Failed to text the element with %s" % e)
    def switch_frame(self, selector):
        """
        多表单嵌套切换
        :param loc: 传元素的属性值
        :return: 定位到的元素
        """
        try:
            el = self.find_element(selector)
            return self.driver.switch_to_frame(el)
        except NoSuchElementException as e:
            logger.error("查找iframe异常-> {0}".format(e))
    def switch_windows(self, selector):
        """
        多窗口切换
        :param loc:
        :return:
        """
        try:
            el = self.find_element(selector)
            return self.driver.switch_to_window(el)
        except NoSuchElementException as e:
            logger.error("查找窗口句柄handle异常-> {0}".format(e))
    def switch_alert(self):
        """
        警告框处理
        :return:
        """
        try:
            return self.driver.switch_to_alert()
        except NoSuchElementException as e:
            logger.error("查找alert弹出框异常-> {0}".format(e))

LoginPage.py - CNDS login page

from  pageObject.basePage import *
from selenium import webdriver
from common.readFile import ReadFile
from config import setting
login_el = ReadFile().readYaml(setting.TEST_Element_YAML + '/' + 'login.yaml')
data = ReadFile().readYaml(setting.TEST_DATA_YAML + '/' + 'login_data.yaml')
class CndsPage(BasePage):
    '''登录页面'''
    url = '/login'
    # 定位器,通过元素属性定位元素对象
    #选择账号密码登录
    chanlelogin_loc = login_el['testcase'][0]
    # 账号输入框
    username_loc = login_el['testcase'][1]
    # 密码输入框
    pwd_loc = login_el['testcase'][2]
    # 单击登录
    login_accout_loc = login_el['testcase'][3]
    def accout_login(self,accout,passwd):
        self.open_url(self.url)
        self.click(self.chanlelogin_loc)
        self.input(self.username_loc,accout)
        self.input(self.pwd_loc,passwd)
        self.click(self.login_accout_loc)
    # 定位器,通过元素属性定位检查项元素对象
    user_login_success_loc = login_el['check'][0]
    accout_id_loc = login_el['check'][1]
    accout_pawd_error_loc = login_el['check'][2]
    # 账号或密码错误提示
    def accout_passwd_error(self):
        return self.get_text(self.accout_pawd_error_loc)
    # 登录成功,跳转到个人资料页,获取用户名
    def get_account(self):
        self.click(self.user_login_success_loc)
        time.sleep(2)
    def user_login_success(self):
        return self.find_element(self.accout_id_loc).text

Organizing Test Cases

·  Click to log in if the user name and password are correct

·  The user name is correct, the password is wrong, click to log in

import unittest
from common import function,myUnit,readFile
from pageObject.loginPage import CndsPage
from time import sleep
from common.logger import Logger
from config import setting
import ddt
log = Logger()
testData= readFile.ReadFile().readYaml(setting.TEST_DATA_YAML + '/' + 'login_data.yaml')
@ddt.ddt
class LoginTest(myUnit.StartEnd):
    # @unittest.skip('skip this case')
    """CNDS登录测试"""
    def user_login_verify(self,account,passwd):
        """
        用户登录
        :param :account 账号
        :param passwd: 密码
        :return:
        """
        CndsPage(self.driver).accout_login(account,passwd)
    @ddt.data(*testData)
    def test_login_normal(self,datayaml):
        log.info("test_login1_normal is start run...")
        self.user_login_verify(datayaml['data']['accout'],datayaml['data']['passwd'])
        sleep(3)
        #断言与截屏
        po = CndsPage(self.driver)
        if datayaml['screenshot'] == 'login_success':
            po.get_account()
            function.inser_img(self.driver)
            self.assertEqual(po.user_login_success(), datayaml['check'][0], "登录成功,返回实际结果是->: {0}".format(po.user_login_success()))
        else:
            function.inser_img(self.driver)
            self.assertEqual(po.accout_passwd_error(), datayaml['check'][0],"登录失败,返回实际结果是->: {0}".format(po.accout_passwd_error()))
        print("test_login1_normal is test end!")

Executing Test Cases

import unittest
from  common.function import latest_report
from  common.sendMail import *
from config import setting
from thridLib.HTMLTestRunner import HTMLTestRunner
import time
import os,sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
report_dir = setting.TEST_REPORT + '/report/'
def add_case(test_path=setting.TEST_DIR):
    discover = unittest.defaultTestLoader.discover(test_path, pattern="test*.py")
    return discover
def run_case(all_case,result_path=report_dir):
    print("start run testcase...")
    now = time.strftime("%Y-%m-%d %H_%M_%S")
    report_name = result_path + '/' + now + 'result.html'
    print("start write report...")
    #HTMLTestRunner测试报告
    with open(report_name, 'wb') as f:
        runner = HTMLTestRunner(stream=f, title='测试报告', description='用例执行情况')  # 定义测试报告
        runner.run(all_case)  # 执行测试用例
    f.close()
    print("find latest report...")
    # 查找最新的测试报告
    report = latest_report(result_path)
    # 邮件发送报告
    print("send email report...")
    send_mail(report)
    print("test end!")
if __name__ == '__main__':
    cases = add_case()
    run_case(cases)

Finally: The complete software testing video tutorial below has been sorted out and uploaded, and friends who need it can get it by themselves [Guaranteed 100% free]

Software Testing Interview Documentation

We must study to find a high-paying job. The following interview questions are the latest interview materials from first-tier Internet companies such as Ali, Tencent, and Byte, and some Byte bosses have given authoritative answers. Finish this set The interview materials believe that everyone can find a satisfactory job.

Guess you like

Origin blog.csdn.net/AI_Green/article/details/132481300