电商平台 Python + unittest + Selenium

登录正向和反向用例如何区分

1、思路:在测试用例中添加一个标识正向案例和逆向案例的标记:False,True

步骤:

  • 调用登录方法(输入,点击登录)

  • 判断是否正向用例:

    • 判断安全退出是否存在

    • 点击安全退出

    • 点击登录链接

  • 否则:

    • 获取登录异常信息

    • 断言操作

    • 点击异常提示框

  • base

    • 基类

      • page页面的一些公共的方法

        • 点击方法

        • 输入方法

        • 获取文本方法

        • 截图方法

        • 判断元素是否找到

    • 方法以base开头

    • 可以用于下一个项目的

  • page

    • 页面对象

      • 一个页面封装一个对象

        • 继承Base

    • 实现

      • 1、模块名:Page+实际操作模块名称

        • page_login.py

      • 2、页面对象名

        • 以打驼峰方法将模块名抄一遍,去掉下划线

      • 3、方法

        • 涉及到元素,将每个元素单独封装成一个方法

      • 4、组装

        • 根据需求组装以上步骤

    • 登录:

      • 点击登录链接

      • 输入用户名

      • 输入密码

      • 输入验证码

      • 点击登录按键

      • 成功:跳转页面,可以找到退出信息

        • 点击安全退出

        • 并点击登录链接

      • 失败:提示信息弹出

        • 获取提示信息,断言

        • 点击确认

        • 注意有无iframe嵌套以及页面切换

  • 测试脚本

    • 使用夹具,每一次测试用例执行之前初始化driver,点击登录链接

    • 结束后,关闭驱动

Base基类

'''
基类
点击方法
输入方法
获取信息方法
截图方法
提高复用率
'''
import os
os.environ['SE_DRIVER_MIRROR_URL'] = 'https://cdn.npmmirror.com/binaries/chrome-for-testing'
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
class Base:
    def __init__(self):
        self.driver = webdriver.Chrome()
        self.driver.get('http://192.168.174.181/')
​
​
    #查找元素
    def base_find_lement(self,loc,timeout=30,pol=0.5):
        #loc为变量
        return WebDriverWait(self.driver, timeout, pol).until(lambda x:x.find_element(*loc))
​
    #点击
    def base_clik(self,loc):
        self.base_find_lement(loc).click()
    #输入
    def base_input(self,loc,value):
        #查找元素
        ele = self.base_find_lement(loc)
        #清空
        ele.clear()
        #输入元素
        ele.send_keys(value)
    #获取错误信息文本
    def base_get_text(self,loc):
        #查找元素
        return self.base_find_lement(loc).text
        #打印
    #获取截图
    def base_get_image(self):
        self.driver.get_screenshot_as_file('../image/1.png')
        # 判断元素是否存在 方法封装
​
    def base_ele_is_exist(self, loc):
        try:
            self.base_find_lement(loc, timeout=2)
            return True  # 代表元素存在
        except:
            return False  # 代表元素不存在

page类

from selenium.webdriver.common.by import By
from v4 import page
from v4.base.base import Base
​
​
class PageLogin(Base):
    #点击登录链接
    def page_click_login_link(self):
        self.base_clik(page.login_link)
    #输入用户名
    def page_input_usr(self,name):
        self.base_input(page.login_uername,name)
    #输入密码
    def page_input_pwd(self,pwd):
        self.base_input(page.login_pwd,pwd)
    #输入验证码
    def page_input_vrycode(self,code):
        self.base_input(page.login_verify_code,code)
​
    #点击登录
    def page_input_login(self):
        self.base_clik(page.login_link)
    #获取异常信息 确认
    def page_get_erro_info(self):
        self.base_get_text(page.login_err_info)
    def page_click_erro_btn_ok(self):
        self.base_clik(page.login_err_info_ok)
    #截图
    def page_get_screeshot(self):
        self.base_get_image()
​
    #点击安全退出 ---》》推出使用
    def page_click_logout(self):
        self.base_clik(page.login_layout)
    #判断是否登录成功
    def page_is_login_success(self):
        #登录成功,返回True
        #
        return self.base_ele_is_exist(page.login_layout)
​
    #组合业务逻辑(输入+点击登录)
    def  page_login(self,usrname,pwd,verify_code):
        self.page_input_usr(usrname)
        self.page_input_pwd(pwd)
        self.page_input_vrycode(verify_code)
        self.page_input_login()

init.py

from selenium.webdriver.common.by import By
login_link= By.LINK_TEXT,'登录'
login_uername = By.ID,'username'
login_pwd = By.ID,'password'
login_verify_code = By.ID,'verify_code'
login_btn = By.CSS_SELECTOR,'a[class="J-login-submit"]'
login_err_info = By.CSS_SELECTOR,'[class="layui-layer-content layui-layer-padding"]'
login_err_info_ok = By.CSS_SELECTOR,'.layui-layer-btn0'
login_layout = By.CSS_SELECTOR,'[href="/Home/user/logout.html"]'

测试脚本

import unittest
​
from v4.page.page import PageLogin
from parameterized import parameterized
​
def get_data():
    return [('13188888761','12345','8888','验证码错误','False'),
            ('13188888763', '12345', '8888', '验证码错误','False')
            ]
class TestLogin(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        #打开浏览器,初始化driver
​
        cls.login = PageLogin()
        #点击登录链接
        cls.login.page_click_login_link()
​
    @classmethod
    def tearDownClass(cls) -> None:
        #关闭驱动对象
        cls.login.driver.quit()
    @parameterized.expand(get_data())
    def test_login_ok(self,usrname,pwd,verfify_code,expect_result,success):
        #调用登录方法
           if success:
              try:
                  self.assertTrue(self.login.page_is_login_success())
                  self.login.page_click_logout()
              except:
                    self.login.page_get_screeshot()
​
               #判断安全退出是否存在-存在,点击,退出;不存在,
               #获取安全退出
           else:
               self.login.page_login(usrname, pwd, verfify_code)
               # 获取登录提示信息
               msg = self.login.page_get_erro_info()
​
               try:
                   self.assertIn(expect_result, msg)
               except:
                   self.login.page_get_screeshot()

搜索正向和反向用例如何区分

1、思路:在测试用例中添加一个标识正向案例和逆向案例的标记:False,True(可以搜到,不可以搜到)

步骤:

  • 使用cookie绕过验证码进行登录

  • 能搜到:

    • 在搜索框输入关键词

    • 点击搜索按钮

    • 点击加购按钮

    • 跳转出现架构成功的信息,断言(注意有iframe需要进行切换)

    • 回到原界面

  • 不能搜到

    • 在搜索框输入关键词

    • 点击搜索按钮

    • 点击加购按钮

    • 出现提示购物车为空,继续购物的信息(无跳转)

  • base

    • 基类

      • page页面的一些公共的方法

        • 点击方法

        • 输入方法

        • 获取文本方法

        • 截图方法

        • 判断元素是否找到

    • 方法以base开头

    • 可以用于下一个项目的

  • page

    • 页面对象

      • 一个页面封装一个对象

        • 继承Base

    • 实现

      • 1、模块名:Page+实际操作模块名称

        • page_login.py

      • 2、页面对象名

        • 以打驼峰方法将模块名抄一遍,去掉下划线

      • 3、方法

        • 涉及到元素,将每个元素单独封装成一个方法

      • 4、组装

        • 根据需求组装以上步骤

    • 搜索:

      • cookie绕过验证码进行登录

      • 输入关键词

      • 点击搜索按键

      • 成功:跳转页面

        • 点击加购

        • 弹出提示信息(注意iframe嵌套)

      • 失败:提示信息弹出

        • 获取提示信息,断言

  • 测试脚本

    • 使用夹具,每一次测试用例执行之前初始化driver

    • 结束后,关闭驱动

  • 参数化

    • 读取json文件

base基类

from selenium.webdriver.support.wait import WebDriverWait
from selenium import webdriver
import os
import time
os.environ['SE_DRIVER_MIRROR_URL'] = 'https://cdn.npmmirror.com/binaries/chrome-for-testing'
​
class Base:
    def __init__(self):
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(5)
        self.driver.get('http://192.168.174.187/')
​
​
    #点击
    def base_click(self,loc):
        self.base_find_element(loc).click()
​
    #找元素
    def base_find_element(self,loc,timeout=60,pol=0.5):
        return WebDriverWait(self.driver, timeout, pol).until(lambda x: x.find_element(*loc))
​
    #登录模块
    def base_get_cookie(self,cookie):
​
        self.driver.add_cookie(cookie)
        time.sleep(2)
        self.driver.refresh()
​
​
​
    def base_is_exits(self,loc):
        try:
            self.base_find_element(loc)
            return True
        except:
            return False
    #输入
    def bese_input(self,loc,value):
        ele = self.base_find_element(loc)
        ele.clear()
        ele.send_keys(value)
​
    #获取截图
    def base_get_screen(self):
        self.driver.get_screenshot_as_file('../images/{}.png'.format(time.strftime("%Y-%m-%d-%H-%M-%S")))
​
    #获取提示信息
    def base_get_info(self,loc):
        return self.base_find_element(loc).text
​
​
    def base_to_defualt(self):
        self.driver.switch_to.default_content()

page_search.py

import time
​
from selenium.webdriver.support import expected_conditions as EC
​
import page
from base.base import Base
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
​
class PageSearch(Base):
    #搜索,输入小米8
    def page_search_input(self,value):
        self.bese_input(page.search_input,value)
​
    #点击搜索
    def page_search_click(self):
        self.base_click(page.search_input_click)
​
    #加购物车
    #href="javascript:void(0);"加入购物车
    def page_search_success(self):
        self.base_click(page.add_shop_cart)
​
    #不成功提示信息
    # ncyekjl
    def page_search_false(self):
        try:
            self.base_is_exits(page.add_cart_dis_msg)
            return False
        except:
            return True
    #添加成功的信息
    def page_add_cart_msg(self):
        self.base_get_info(page.add_cart_msg)
​
    #跳转
    def page_to_ifram(self):
        WebDriverWait(self.driver, 10).until(
            EC.frame_to_be_available_and_switch_to_it((By.ID, page.cart_iframe))
        )
        print("成功切换到框架")
​
    #点击继续购物,并返回原来的界面
    def page_continue_shopping(self):
        self.base_click(page.add_cart_ok_btn)
        time.sleep(4)
        self.driver.quit()
​
​
​
    #获取添加失败的信息
    def page_get_dis_img(self):
        self.base_get_info(page.add_cart_dis_msg)
​
    #获取截图
    def page_get_screen(self):
        self.base_get_screen()
​
    #组合(输入+点击)
    def page_search(self,value):
​
        self.page_search_input(value)
        self.page_search_click()

init.py

from selenium.webdriver.common.by import By
​
search_input=By.CSS_SELECTOR,'.ecsc-search-input'
search_input_click = By.CSS_SELECTOR,'.ecsc-search-button'
add_shop_cart = By.XPATH, '//a[@href="javascript:void(0);" and text()="加入购物车"]'
add_cart_msg = By.XPATH,'/html/body/div/div/div/table/tbody/tr[1]/td/div/div/div[2]/span'
add_cart_ok_btn = By.CSS_SELECTOR,'.go-shopping'
add_cart_dis_msg = By.CSS_SELECTOR,'.ncyekjl'
cart_iframe ='layui-layer-iframe1'

test_search.py

import unittest
import time
from parameterized import parameterized
​
​
from page.page_search import PageSearch
from tool.read_info import read_to_info
​
class TestSerch(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
​
    #初始化对象
        cls.pagesearh = PageSearch()
        cls.pagesearh.base_get_cookie({"name":"PHPSESSID","value":"u5ttsabho4f04trd5hi11glvr5"})
    @classmethod
    def tearDownClass(cls) -> None:
        time.sleep(3)
        cls.pagesearh.driver.quit()
​
    @parameterized.expand(read_to_info())
    def test_searche(self,vaule,success,expect):
​
        if success:
            # 搜索成功
            self.pagesearh.page_search(vaule)
            # 添加购物车
            self.pagesearh.page_search_success()
            #跳转
            self.pagesearh.page_to_ifram()
            #h获取信息,断言
​
            result = self.pagesearh.page_add_cart_msg()
​
            try:
                self.assertIn(result, expect)
            except:
                self.pagesearh.page_get_screen()
            finally:
                self.pagesearh.page_continue_shopping()
​
​
            # 点击继续购物的按钮
        else:
            self.pagesearh.page_search(vaule)
        #搜索不成功
            res = self.pagesearh.page_get_dis_img()
            try:
                self.assertIn(res,expect)
        #提示信息,断言
​
            except:
                self.pagesearh.page_get_screen()

read_info.py

import json
​
def read_to_info():
    data_list = []
    with open('../data/info.json','r',encoding='utf-8') as f:
        res = json.load(f)
        for item in res:
            v = item.values()
            temp = tuple(v)
            data_list.append(temp)
    return data_list
if __name__ == '__main__':
    print(read_to_info())

生成测试报告

import unittest
from htmltestreport import HTMLTestReport
suite = unittest.TestLoader().discover('../scripts', 'test*.py')
runner = HTMLTestReport('测试报告.html')
runner.run(suite)

info.json

[
    {
        "goods": "小米6",
        "success": false,
        "info": "抱歉没找到您要搜索的商品,换个条件试试"
    },
    {
        "goods": "小米8",
        "success": true,
        "info": "添加成功"
    },
     {
        "goods": "安徒生童话",
        "success": true,
        "info": "添加成功"
    },
     {
        "goods": "汽车",
        "success": true,
        "info": "添加成功"
    },
     {
        "goods": "大米",
        "success": true,
        "info": "添加成功"
    }
]
Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐