zoukankan      html  css  js  c++  java
  • 学习pytest+allureUI自动化记录

    前段时间记录了一下pytest接口自动化测试,今天来记录pytest+allureUI自动化了 ,还是直接上代码吧。

    目录

    case#存放测试用例
    common#存放测试公共方法
    data#存放测试数据、定位元素
    logs#存放日志文件
    pages#存放页面页面元素,操作步骤
    report#存放测试报告
    getpathinfo.py#读取当前目录
    pytest#pytest配置文件
    requirements.txt#依赖包
    

    学习框架

    pytest单元测试框架+allure生成测试报告

    结构设计

    1.每一个页面的所有用例组合在一个测试类里面生成一个py文件

    2.将每个页面用例的操作步骤封装在一个测试类里面生成一个py文件

    3.将测试数据,定位元素存放在yml文件中

    4.通过allure生成测试报告

    学习内容

    1.pytes单元测试框架

    2.allure生成测试报告

    3.yml文件存放测试数据通过parametrize进行参数化

    4.无界面运行测试用例

    练习代码

    getpathinfo.py #获取当前路径

    import os
    
    def get_path():
        curpath = os.path.dirname(os.path.realpath(__file__))
        return curpath
    
    if __name__ == '__main__':
        print("测试路径",get_path())
    getpathinfo.py

    pytest.ini #存放pytest配置文件

    #pytest.ini
    [pytest]
    
    #addopts = -v --reruns 1 --html=./report/report.html --self-contained-html
    #addopts = -v --reruns 1 --alluredir ./report/allure_raw
    #addopts = -v -s -p no:warnings --reruns 1 --pytest_report ./report/Pytest_Report.html
    pytest.ini

    requirements.txt  #存放导入依赖包(pip install -r requirements.txt安装依赖包)

    allure-pytest==2.8.15
    allure-python-commons==2.8.15
    appdirs==1.4.4
    APScheduler==3.6.3
    atomicwrites==1.3.0
    attrs==19.3.0
    BeautifulReport==0.1.2
    beautifulsoup4==4.8.1
    black==19.10b0
    certifi==2019.9.11
    cffi==1.14.0
    chardet==3.0.4
    Click==7.0
    colorama==0.4.3
    colorlog==4.1.0
    crypto==1.4.1
    cryptography==2.9.2
    filetype==1.0.7
    Flask==1.1.1
    har2case==0.3.1
    HttpRunner==1.5.8
    idna==2.8
    importlib-metadata==1.6.0
    itsdangerous==1.1.0
    Jinja2==2.10.3
    jmespath==0.9.5
    loguru==0.4.1
    lxml==4.5.0
    MarkupSafe==1.1.1
    more-itertools==8.2.0
    Naked==0.1.31
    numpy==1.17.4
    packaging==20.3
    parameterized==0.7.1
    ParamUnittest==0.2
    pathspec==0.8.0
    Pillow==6.2.1
    pluggy==0.13.1
    py==1.8.1
    pycparser==2.20
    pycryptodome==3.9.4
    pydantic==1.5.1
    Pygments==2.6.1
    PyMySQL==0.9.3
    pyparsing==2.4.7
    Pypubsub==4.0.3
    pytest==5.4.2
    pytz==2019.3
    pywin32==227
    PyYAML==5.1.2
    regex==2020.5.14
    requests==2.22.0
    requests-toolbelt==0.9.1
    robotframework==3.1.2
    robotframework-ride==1.7.4.1
    schedule==0.6.0
    selenium==3.141.0
    send-email==201212
    shellescape==3.4.1
    six==1.13.0
    soupsieve==1.9.5
    toml==0.10.1
    typed-ast==1.4.1
    tzlocal==2.0.0
    urllib3==1.25.7
    wcwidth==0.1.9
    Werkzeug==0.16.0
    win32-setctime==1.0.1
    wxPython==4.0.7.post2
    xlrd==1.2.0
    zipp==3.1.0
    requirements.txt

    common/base.py #存放公共方法

    from selenium import webdriver
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from  selenium.webdriver.support.select import Select
    from selenium.webdriver.common.action_chains import ActionChains
    from selenium.common.exceptions import NoSuchElementException
    from selenium.common.exceptions import NoSuchFrameException
    from selenium.common.exceptions import StaleElementReferenceException
    from selenium.common.exceptions import ElementNotVisibleException
    from selenium.common.exceptions import TimeoutException
    from common.log import Log
    
    class LocatorTypeError(Exception):
        pass
    class ElementNotFound(Exception):
        pass
    
    class Base():
        '''基于原生selenium二次封装'''
        log = Log()
        def __init__(self,driver:webdriver.Chrome,timeout = 10,t = 0.5):
            url = "http://********"
            self.base_url = url
            self.driver = driver
            self.timeout = timeout
            self.t = t
    
        def find(self, locator):
            """定位到元素,返回元素对象,没定位到,Timeout异常"""
            if not isinstance(locator, tuple):
                raise LocatorTypeError("参数类型错误,locator必须是元祖类型:loc = ('id','value1')")
            else:
                self.log.info("正在定位元素信息:定位方式->%s,value值->%s" % (locator[0], locator[1]))
                #print("正在定位元素信息:定位方式->%s,value值->%s" % (locator[0], locator[1]))
                try:
                    ele = WebDriverWait(self.driver, self.timeout, self.t).until(EC.presence_of_element_located(locator))
                except TimeoutException as msg:
                     raise ElementNotFound("定位元素出现超时!")
                return ele
    
        def finds(self,locator):
            '''复数定位,返回elements对象 list'''
            if not isinstance(locator,tuple):
                raise LocatorTypeError('参数类型错误,locator必须是元组类型:loc = ("id","value")')
            else:
                self.log.info("正在定位元素信息:定位方式->%s,value值->%s" % (locator[0], locator[1]))
                #print("正在定位元素信息:定位方式->%s,value值->%s"%(locator[0],locator[1]))
                try:
                    eles = WebDriverWait(self.driver, self.timeout, self.t).until(EC.presence_of_all_elements_located(locator))
                except TimeoutException as msg:
                    raise ElementNotFound("定位元素出现超时!")
                return eles
    
        def writein(self,locator,text = ""):
            '''写入文本'''
            ele = self.find(locator)
            if ele.is_displayed():
                ele.send_keys(text)
            else:
                raise ElementNotVisibleException("元素不可见或者不唯一无法输入")
    
        def click(self,locator):
            '''点击元素'''
            ele = self.find(locator)
            if ele.is_displayed():
                ele.click()
            else:
                raise ElementNotVisibleException("元素不可见或者不唯一无法点击")
    
        def clear(self,locator):
            '''清空输入框文本'''
            ele = self.find(locator)
            if ele.is_displayed():
                ele.clear()
            else:
                raise ElementNotVisibleException("元素不可见或者不唯一")
    
        def is_selected(self,locator):
            '''判断元素是否被选中,返回bool值'''
            ele  = self.find(locator)
            r = ele.is_selected()
            return r
    
        def is_element_exist(self,locator):
            '''是否找到'''
            try:
                self.find(locator)
                return True
            except :
                return False
    
        def is_title(self,title = ""):
            '''返回bool值'''
            try:
                result = WebDriverWait(self.driver,self.timeout,self.t).until(EC.title_is(title))
                return result
            except :
                return False
    
        def is_title_contains(self, title=''):
            """返回bool值"""
            try:
                result = WebDriverWait(self.driver, self.timeout, self.t).until(EC.title_contains(title))
                return result
            except:
                return False
    
        def is_text_in_element(self,locator,text = ''):
            '''返回bool值'''
            if not isinstance(locator,tuple):
                raise LocatorTypeError("参数类型错误,locator必须是元祖类型:loc = ('id','value1')")
            try:
                result = WebDriverWait(self.driver, self.timeout, self.t).until(
                    EC.text_to_be_present_in_element(locator, text))
                return result
            except :
                return False
    
        def is_value_in_element(self,locator,value = ""):
            if not isinstance(locator, tuple):
                raise LocatorTypeError("参数类型错误,locator必须是元祖类型:loc = ('id','value1')")
            try:
                result = WebDriverWait(self.driver, self.timeout, self.t).until(
                    EC.text_to_be_present_in_element_value(locator, value))
                return result
            except:
                return False
    
        def is_alert(self,timeout = 8):
            try:
                result = WebDriverWait(self.driver, timeout, self.t).until(EC.alert_is_present())
                return result
            except:
                return False
    
        def get_title(self):
            """获取title"""
            return self.driver.title
    
        def get_text(self, locator):
            """获取文本"""
            if not isinstance(locator, tuple):
                raise LocatorTypeError("参数类型错误,locator必须是元祖类型:loc = ('id','value1')")
            try:
                t = self.find(locator).text
                return t
            except:
                self.log.info("获取text失败,返回''")
                #print("获取text失败,返回''")
                return ""
    
        def get_attribute(self, locator, name):
            """获取属性"""
            if not isinstance(locator, tuple):
                raise LocatorTypeError("参数类型错误,locator必须是元祖类型:loc = ('id','value1')")
            try:
                element = self.find(locator)
                return element.get_attribute(name)
            except:
                self.log.info("获取%s属性失败,返回''" % name)
                #print("获取%s属性失败,返回''" % name)
                return ''
    
        def js_focus_element(self,locator):
            '''聚焦元素'''
            if not isinstance(locator,tuple):
                raise LocatorTypeError("参数类型错误")
            target = self.find(locator)
            self.driver.execute_script("arguments[0].scrollIntoView();", target)
    
        def js_scroll_top(self):
            '''滚到顶部'''
            js = "window.scrollTo(0,0)"
            self.driver.execute_script(js)
    
        def js_scroll_end(self,x = 0):
            '''滚到底部'''
            js = "window.scrollTo(%s, document.body.scrollHeight)" % x
            self.driver.execute_script(js)
    
        def select_by_index(self,locator,index =0):
            '''通过索引,index是索引第几个,从0开始,默认第一个'''
            if not isinstance(locator,tuple):
                raise LocatorTypeError("参数类型错误")
            element = self.find(locator)
            Select(element).select_by_index(index)
    
        def select_by_value(self, locator, value):
            """通过value属性"""
            if not isinstance(locator, tuple):
                raise LocatorTypeError("参数类型错误")
            element = self.find(locator)
            Select(element).select_by_value(value)
    
        def select_by_text(self,locator,text):
            """通过文本值定位"""
            element = self.find(locator)
            Select(element).select_by_visible_text(text)
    
        def switch_iframe(self, id_index_locator):
            """切换iframe"""
            try:
                if isinstance(id_index_locator, int):
                    self.driver.switch_to.frame(id_index_locator)
                elif isinstance(id_index_locator, str):
                    self.driver.switch_to.frame(id_index_locator)
                elif isinstance(id_index_locator, tuple):
                    ele = self.find(id_index_locator)
                    self.driver.switch_to.frame(ele)
            except:
                self.log.info("iframe切换异常")
                #print("iframe切换异常")
    
        def switch_handle(self,window_name):
            self.driver.switch_to.window(window_name)
    
        def switch_alert(self):
            r = self.is_alert()
            if not r:
                self.log.info("alert不存在")
                #print("alert不存在")
            else:
                return r
    
        def move_to_element(self, locator):
            """鼠标悬停操作"""
            if not isinstance(locator, tuple):
                raise LocatorTypeError("参数类型错误")
            ele = self.find(locator)
            ActionChains(self.driver).move_to_element(ele).perform()
    
    if __name__ == '__main__':
        driver = webdriver.Chrome()
        web = Base(driver)
        driver.get("https://www.baidu.com")
        loc_1 = ("id", "kw")
        web.writein(loc_1, "hello")
        driver.close()
    base.py

    common/log.py #生成日志文件

    import logging,time
    import os
    import getpathinfo
    
    path = getpathinfo.get_path()#获取本地路径
    log_path = os.path.join(path,'logs')# log_path是存放日志的路径
    # 如果不存在这个logs文件夹,就自动创建一个
    if not os.path.exists(log_path):os.mkdir(log_path)
    
    class Log():
        def __init__(self):
            #文件的命名
            self.logname = os.path.join(log_path,'%s.log'%time.strftime('%Y_%m_%d'))
            self.logger = logging.getLogger()
            self.logger.setLevel(logging.DEBUG)
            #日志输出格式
            self.formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    
        def __console(self,level,message):
            #创建一个fileHander,用于写入本地
            fh = logging.FileHandler(self.logname,'a',encoding='utf-8')
            fh.setLevel(logging.DEBUG)
            fh.setFormatter(self.formatter)
            self.logger.addHandler(fh)
    
            #创建一个StreamHandler,用于输入到控制台
            ch = logging.StreamHandler()
            ch.setLevel(logging.DEBUG)
            ch.setFormatter(self.formatter)
            self.logger.addHandler(ch)
    
            if level == 'info':
                self.logger.info(message)
            elif level == 'debug':
                self.logger.debug(message)
            elif level == 'warning':
                self.logger.warning(message)
            elif level == 'error':
                self.logger.error(message)
            #避免日志重复
            self.logger.removeHandler(fh)
            self.logger.removeHandler(ch)
            #关闭打开文件
            fh.close()
    
        def debug(self,message):
            self.__console('debug',message)
    
        def info(self,message):
            self.__console('info',message)
    
        def warning(self,message):
            self.__console('warning',message)
    
        def error(self,message):
            self.__console('error',message)
    
    if __name__ == '__main__':
        log = Log()
        log.info('测试')
        log.debug('测试')
        log.warning('测试')
        log.error('测试')
    log.py

    common/read_yml.py #读取yml文件

    import os
    import yaml
    import getpathinfo
    
    class ReadYaml():
        def __init__(self,filename):
            path = getpathinfo.get_path()#获取本地路径
            self.filepath = os.path.join(path,'data')+"/"+filename#拼接定位到data文件夹
    
        def get_yaml_data(self):
            with open(self.filepath,'r',encoding='utf-8')as f:
                #调用load方法加载文件流
                return yaml.load(f,Loader=yaml.FullLoader)
    
    if __name__ == '__main__':
        data = ReadYaml("login_page.yml").get_yaml_data()
        username = data["test_login_element"][0]
        print(tuple(username))
    read_yml.py

    pages #存放测试页面操作步骤、断言(写了简单两个)

    from common.base import Base
    from common.read_yml import ReadYaml
    testelement = ReadYaml("login_page.yml").get_yaml_data()
    
    class LoginPage(Base):
        loc1 = tuple(testelement["test_login_element"][0])#用户名
        loc2 = tuple(testelement["test_login_element"][1])#密码
        loc3 = tuple(testelement["test_login_element"][2])#登录
        # 判断元素
        loc4 = tuple(testelement["test_login_element"][3])#登录成功断言
        loc5 = tuple(testelement["test_login_element"][4])#登录失败断言
    
        def input_username(self, text="admin"):
            '''输入用户名'''
            self.writein(self.loc1, text)
    
        def input_password(self, text="yoyo123456"):
            '''输入用户名'''
            self.writein(self.loc2, text)
    
        def click_button(self):
            '''点击登录按钮'''
            self.click(self.loc3)
    
        def login(self, user="admin", password="yoyo123456"):
            '''登录'''
            self.driver.get(self.base_url)
            self.input_username(user)
            self.input_password(password)
            self.click_button()
    
        def is_login_success(self, expect_text='后台页面'):
            text = self.get_text(self.loc4)
            self.log.info("获取到断言元素的文本内容:%s"%text)
            return expect_text == text
    
        def is_login_fail(self, expect_text='请输入正确的用户名和密码'):
            text = self.get_text(self.loc5)
            self.log.info("获取到断言元素的文本内容:%s"%text)
            return expect_text in text
    
    if __name__ == '__main__':
        from selenium import webdriver
        driver = webdriver.Chrome()
        web = LoginPage(driver)
        web.login()
        result = web.is_login_fail()
        print("登录结果:", result)
        assert result
        driver.quit()
    login_page.py
    from common.base import Base
    from common.read_yml import ReadYaml
    testelement = ReadYaml("add_account_page.yml").get_yaml_data()
    
    class Add_Account(Base):
    
        loc1 = tuple(testelement["test_account_element"][0])  # 银行卡账户
        loc2 = tuple(testelement["test_account_element"][1])  # 添加银行卡账户
        loc3 = tuple(testelement["test_account_element"][2])  # 卡号
        loc4 = tuple(testelement["test_account_element"][3])  # 姓名
        loc5 = tuple(testelement["test_account_element"][4])  # 电话
        loc6 = tuple(testelement["test_account_element"][5])  # 邮箱
        loc7 = tuple(testelement["test_account_element"][6])  # 城市
        loc8 = tuple(testelement["test_account_element"][7])  # 性别
        loc9 = tuple(testelement["test_account_element"][8])  # 保存
        loc10 = tuple(testelement["test_account_element"][9]) # 新增成功校验
        loc11 = tuple(testelement["test_account_element"][10]) #账号为空校验
        loc12 = tuple(testelement["test_account_element"][11]) #姓名为空校验
    
        def click_account(self):
            '''点击银行卡账号'''
            self.finds(self.loc1)[0].click()
    
        def click_add_account(self):
            '''点击添加银行卡账号'''
            self.click(self.loc2)
    
        def input_card_num(self,text = "123456"):
            '''输入卡号'''
            self.writein(self.loc3,text)
    
        def input_name(self,text = " "):
            '''输入姓名'''
            self.writein(self.loc4,text)
    
        def input_phone(self,text = "123456"):
            '''输入电话'''
            self.writein(self.loc5,text)
    
        def input_mail(self,text = "123456"):
            '''输入邮箱'''
            self.writein(self.loc6,text)
    
        def input_city(self,text = "测试"):
            '''输入城市'''
            self.writein(self.loc7,text)
    
        def input_sex(self,text = ""):
            '''输入性别'''
            self.writein(self.loc8,text)
    
        def click_save(self):
            '''点击保存'''
            self.click(self.loc9)
    
        def is_add_success(self, expect_text='添加成功'):
            text = self.get_text(self.loc10)
            self.log.info("获取到断言元素的文本内容:%s" %text)
            return expect_text in text
    
        def is_add_fail1(self, expect_text='这个字段是必须的'):
            '''账号为空断言'''
            text = self.get_text(self.loc11)
            self.log.info("获取到断言元素的文本内容:%s" %text)
            return expect_text in text
    
        def is_add_fail2(self, expect_text='这个字段是必须的'):
            '''姓名为空断言'''
            text = self.get_text(self.loc12)
            self.log.info("获取到断言元素的文本内容:%s" %text)
            return expect_text in text
    
    if __name__ == '__main__':
        from pages.login_page import LoginPage
        from selenium import webdriver
        driver = webdriver.Chrome()
        driver.maximize_window()
        web = LoginPage(driver)
        web.login()
        account = Add_Account(driver)
        account.click_account()
        account.click_add_account()
        account.input_card_num()
        account.input_name()
        account.input_phone()
        account.input_mail()
        account.input_city()
        account.input_sex()
        account.click_save()
        account.is_add_fail()
        driver.quit()
        
    add_account_page.py

    case/conftest.py #存放前置操作,设置无界面模式

    import platform
    
    from selenium import webdriver
    from pages.login_page import LoginPage
    import pytest
    import time
    from common.log import Log
    from selenium.webdriver.chrome.options import Options
    log = Log()
    @pytest.fixture(scope="session")
    def login_fixtrue(driver):
        #登录前置操作
        #driver = webdriver.Chrome()
        #driver.maximize_window()
        web = LoginPage(driver)
        web.login()
        return driver
    def pytest_addoption(parser):
        '''添加命令行参数'''
        parser.addoption('--headless', action = "store",
                         default = 'no', help = 'set chrome headless option yes or no'
        )
    @pytest.fixture(scope="session")
    def driver(request):
        """定义全局driver fixture,给其它地方作参数调用"""
        if platform.system()=='Windows':
            chrome_options = Options()
            chrome_options.add_argument('--window-size=1920,1080')  # 设置当前窗口的宽度,高度
            chrome_options.add_argument('--headless')  # 无界面
            print("当前运行的操作系统为windows")
            _driver = webdriver.Chrome(chrome_options=chrome_options)
        else:
            print('当前运行的操作系统为linux')
            chrome_options = Options()
            chrome_options.add_argument('--window-size=1920,1080')  # 设置当前窗口的宽度,高度
            chrome_options.add_argument('--no-sandbox')#解决DevToolsActivePort文件不存在报错问题
            chrome_options.add_argument('--disable-gpu')#禁用GPU硬件加速,如果软件渲染器没有就位,则GPU进程将不会启动
            chrome_options.add_argument('--disable-dev-shm-usage')
            chrome_options.add_argument('--headless')  # 无界面
            _driver = webdriver.Chrome(chrome_options=chrome_options)
    
        def end():
            print("全部用例执行完后 teardown quit dirver")
            time.sleep(5)
            _driver.quit()
        request.addfinalizer(end)
        return _driver
    conftest.py

    case/test_login.py #存放登录页面测试用例

    import allure
    import pytest
    from common.log import Log
    from common.read_yml import ReadYaml
    from pages.login_page import LoginPage
    from selenium import webdriver
    testdata = ReadYaml('login_page.yml').get_yaml_data()#读取数据
    
    class Test_login():
    
        log = Log()
    
        @allure.feature("功能点:用户登录页面")
        @allure.story("用例:用户登录")
        @pytest.mark.parametrize("username,password,msg",testdata["test_login_success_data"],
                                 ids = ["正确用户名密码登录"])
        @pytest.mark.skip('跳过该成功用例')
        def test_success_login(self,driver,username,password,msg):
            #driver = webdriver.Chrome()
            web = LoginPage(driver)
            web.login(user=username,password=password)
            result = web.is_login_success(expect_text=msg)
            self.log.info("登录结果:%s"%result)
            assert result
            #driver.quit()
    
        @allure.feature("功能点:用户登录页面")
        @allure.story("用例:用户登录")
        @pytest.mark.parametrize("username,password,msg", testdata["test_login_fail_data"],
                                 ids=["正确用户名错误密码登录",
                                      "错误用户名正确密码登录"])
        def test_fail_login(self,driver,username,password,msg):
            #driver = webdriver.Chrome()
            web = LoginPage(driver)
            web.login(user=username,password=password)
            result = web.is_login_fail(expect_text=msg)
            self.log.info("登录结果:%s"%result)
            assert result
    test_login.py

    case/test_add_account.py #存放添加账户页面测试用例

    import allure
    import pytest
    from common.log import Log
    from common.read_yml import ReadYaml
    from pages.add_account_page import Add_Account
    testdata = ReadYaml('add_account_page.yml').get_yaml_data()#读取测试数据
    
    class Test_Add_Account():
        log = Log()
    
        @allure.feature("功能点:添加银行卡账户")
        @allure.story("用例:添加银行卡账户")
        @pytest.mark.parametrize("card_num,name,phone,mail,city,sex,msg",testdata["test_add_account_data1"],
                                 ids=["正常添加"])
        def test_add_account(self, login_fixtrue,card_num, name, phone,mail,city,sex,msg):
            driver = login_fixtrue
            account = Add_Account(driver)
            with allure.step("点击银行卡账户,跳转添加账户页面"):
                account.click_account()
            with allure.step("点击添加账户按钮,进入编辑页面"):
                account.click_add_account()
            with allure.step("输入账户号"):
                account.input_card_num(text=card_num)
            with allure.step("输入姓名"):
                account.input_name(text=name)
            with allure.step("输入手机号"):
                account.input_phone(text=phone)
            with allure.step("输入邮箱"):
                account.input_mail(text=mail)
            with allure.step("输入城市"):
                account.input_city(text=city)
            with allure.step("输入性别"):
                account.input_sex(text=sex)
            with allure.step("点击保存"):
                account.click_save()
            with allure.step("获取结果: 获取页面实际结果,判断是否添加成功"):
                result = account.is_add_success(expect_text=msg)
                self.log.info("断言结果:%s"%result)
            with allure.step("断言:判断是否添加成功"):
                assert result == True
            #driver.quit()
    
        @allure.feature("功能点:添加银行卡账户")
        @allure.story("用例:添加银行卡账户")
        @pytest.mark.parametrize("card_num,name,phone,mail,city,sex,msg",testdata["test_add_account_data2"],
                                 ids=["账号为空添加"])
        def test_add_account1(self, login_fixtrue,card_num, name, phone,mail,city,sex,msg):
            driver = login_fixtrue
            account = Add_Account(driver)
            with allure.step("点击银行卡账户,跳转添加账户页面"):
                account.click_account()
            with allure.step("点击添加账户按钮,进入编辑页面"):
                account.click_add_account()
            with allure.step("输入账户号"):
                account.input_card_num(text=card_num)
            with allure.step("输入姓名"):
                account.input_name(text=name)
            with allure.step("输入手机号"):
                account.input_phone(text=phone)
            with allure.step("输入邮箱"):
                account.input_mail(text=mail)
            with allure.step("输入城市"):
                account.input_city(text=city)
            with allure.step("输入性别"):
                account.input_sex(text=sex)
            with allure.step("点击保存"):
                account.click_save()
            with allure.step("获取结果: 获取页面实际结果,判断是否添加成功"):
                result = account.is_add_fail1(expect_text=msg)
                self.log.info("断言结果:%s"%result)
            with allure.step("断言:判断是否添加成功"):
                assert result == True
            #driver.quit()
    
        @allure.feature("功能点:添加银行卡账户")
        @allure.story("用例:添加银行卡账户")
        @pytest.mark.parametrize("card_num,name,phone,mail,city,sex,msg", testdata["test_add_account_data3"],
                                 ids=["姓名为空添加"])
        def test_add_account2(self, login_fixtrue, card_num, name, phone, mail, city, sex, msg):
            driver = login_fixtrue
            account = Add_Account(driver)
            with allure.step("点击银行卡账户,跳转添加账户页面"):
                account.click_account()
            with allure.step("点击添加账户按钮,进入编辑页面"):
                account.click_add_account()
            with allure.step("输入账户号"):
                account.input_card_num(text=card_num)
            with allure.step("输入姓名"):
                account.input_name(text=name)
            with allure.step("输入手机号"):
                account.input_phone(text=phone)
            with allure.step("输入邮箱"):
                account.input_mail(text=mail)
            with allure.step("输入城市"):
                account.input_city(text=city)
            with allure.step("输入性别"):
                account.input_sex(text=sex)
            with allure.step("点击保存"):
                account.click_save()
            with allure.step("获取结果: 获取页面实际结果,判断是否添加成功"):
                result = account.is_add_fail2(expect_text=msg)
                self.log.info("断言结果:%s" % result)
            with allure.step("断言:判断是否添加成功"):
                assert result == True
            # driver.quit()
    test_add_account.py

    data/add_account_page.yml #存放添加账户页面测试数据,定位元素

    test_account_element:
      - ["xpath",'//*[@href="/xadmin/hello/card/"]']
      - ["xpath",'//*[@id="content-block"]/div[1]/div[2]/div/a']
      - ["xpath",'//*[@id="id_card_id"]']
      - ["xpath",'//*[@id="id_card_user"]']
      - ["xpath",'//*[@id="id_carddetail-0-tel"]']
      - ["xpath",'//*[@id="id_carddetail-0-mail"]']
      - ["xpath",'//*[@id="id_carddetail-0-city"]']
      - ["xpath",'//*[@id="id_carddetail-0-address"]']
      - ["xpath",'//*[@id="card_form"]/div[2]/button']
      - ["xpath",'//*[@id="content-block"]/div[2]']
      - ["xpath",'//*[@id="error_1_id_card_id"]']
      - ["xpath",'//*[@id="error_1_id_card_user"]']
    
    test_add_account_data1:
      -  ["123456","秋水1","123456","123456","测试","","添加成功"]
    test_add_account_data2:
      -  [" ","秋水2","123456","123456","测试","","这个字段是必须的"]
    test_add_account_data3:
      -  ["123456"," ","123456","123456","测试","","这个字段是必须的"]
    add_account_page.yml

    report/allure_raw #测试报告(运行命令:allure serve report/allure_raw)

    记录完毕,生成allure报告在pytest.ini中有写,解开注释即可,pytest运行生成报告,或者pytest --alluredir ./report/allure_raw 

  • 相关阅读:
    Python排序算法(一)——快速排序
    jupyter运行py文件(py文件和ipynb文件互转)
    Jupyter notebook工具栏隐藏和jupyter notebook主题更改
    Python中print和return的区别
    500 : Internal Server Error(jupyter)
    PEP8 python规范神器
    Python分析微信好友性别比例和省份城市分布比例
    xpath 的使用
    scrapy实验1 爬取中国人寿官网新闻,保存为xml
    数据可视化matplotlib、seaborn、pydotplus
  • 原文地址:https://www.cnblogs.com/MrqiuS/p/13226210.html
Copyright © 2011-2022 走看看