pytest公司项目实战之测试目录架构搭建

写了项目的一个demo,目前只写了其中的一个模块(product),目录结构如下

common主要放一些公共方法,

common

----parseconfig 是解析ini用  

----s_packaging 封装的一些方法 conf

conf 配置文件

----config.ini  公共配置数据

----config.py  环境变量配置

financial 财务模块

product  商品模块

----product.ini  商品数据文件

----test_category.py 测试用例文件

conftest 固件函数

pytest.ini 执行配置文件 暂时还没用到

最后的执行用例test_category.py ,这些实现的目的,主要是为了方便用例的易读性。让初级测试也能知道每一步到底是做了什么。

# coding:utf-8
"""
author:zhouxuan
@project--file : erp2 -->test_category.py
2019/12/31 10:35
@Desc:分类管理
"""
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from common.parseconfig import parseConfig
from common.s_packaging import packaging
from conf.config import PRODUCT_DIR,COMMON_DIR
import os
class Test_Category():
    @pytest.mark.parametrize('login',[('商品管理','分类管理')],indirect=True)
    def test_add(self,login):
        driver=login
        product=packaging('test_cateorgy',PRODUCT_DIR)
        product.click_obj(driver,'添加分类')
        product.write_obj(driver,'分类名称','通信产品')
        product.write_obj(driver,'显示顺序',1)
        product.write_obj(driver,'中文报关名称','小米手机')
        product.write_obj(driver,'英文报关名称','mi9max')
        product.click_obj(driver,'保存(新增)')
        success=packaging('common',COMMON_DIR)
        success.wait_element_appear(driver,'成功提示')


if __name__ == '__main__':
    pytest.main(['-s','test_category.py'])

用例对应的测试界面如下

再结合conftest中的login,用例在引用固件login的时候,设置indirect为true,是为了将‘login’当做函数执行,且login中,有两个变量,所以我们也传递了两个变量('商品管理','分类管理')过去。

# coding:utf-8
"""
author:zhouxuan
@project--file : erp2 -->conftest.py
2019/12/31 9:57
@Desc:
"""
from selenium import webdriver
from conf.config import *
from selenium.webdriver.common.keys import Keys
import pytest
from selenium.webdriver.common.action_chains import ActionChains
import time
@pytest.fixture()
def login(request):
    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.implicitly_wait(2)
    driver.get(SYS_URL)
    driver.find_element(value='username').send_keys('*****')
    driver.find_element(value='password').send_keys('******',Keys.ENTER)
    time.sleep(6)
    value= request.param
    target_element=driver.find_element_by_link_text(value[0])
    ActionChains(driver).move_to_element(target_element).perform()
    driver.find_element_by_link_text(value[1]).click()
    yield driver
    # driver.quit()

再说明下最后的用例是如何实现的,可以看到用例都是调用了packaging()类,packaging类具体如下:

# coding:utf-8
"""
author:zhouxuan
2019/12/30 10:57
PyCharm 封装常用的方法
"""
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.remote.webdriver import By
from selenium.webdriver.common.keys import Keys
from common.parseconfig import parseConfig


class packaging():
    def __init__(self,sections,ini_dir):
        self.sections=sections
        self.ini_dir=ini_dir
        self.parse=parseConfig(self.sections,self.ini_dir)

    def wait_element_appear(self,driver,ini_key,timeout=10):
        by, value = self.parse.split_content(ini_key)
        paraser_by(by)
        WebDriverWait(driver, timeout, 1,).until(lambda x: x.find_element(eval(by),value).is_displayed())

    def write_obj(self,driver,ini_key,*args):
        by, value = self.parse.split_content(ini_key)
        paraser_by(by)
        driver.find_element(eval(by),value).send_keys(*args)

    def click_obj(self,driver,ini_key):
        by,value=self.parse.split_content(ini_key)
        paraser_by(by)
        driver.find_element(eval(by),value).click()

    def waiting_obj(self,driver,ini_key):
        by, value = self.parse.split_content(ini_key)
        paraser_by(by)
        self.wait_element_appear(self,driver, timeout=10, by=eval(by), value=value)

def paraser_by(by):
    if by == 'By.XPATH':
        by = By.XPATH
    elif by == 'By.ID':
        by = By.ID
    elif by == 'By.NAME':
        by = By.NAME
    return by



if __name__ == '__main__':
    click_obj('dfd',[1,2])

我们以def click_obj(self,driver,ini_key):
        by,value=self.parse.split_content(ini_key)
        paraser_by(by)
        driver.find_element(eval(by),value).click()为例子说明  

这里的操作就是找到元素,再点击。by为获取元素的方式by.id,by.xpath等,value就是对应的id,xpath的值了。by,value来自于

self.parse.split_content(ini_key)

self.parse=parseConfig(self.sections,self.ini_dir) 继续看parseConfig()
# coding:utf-8
"""
author:zhouxuan
@project--file : erp2 -->parseconfig.py
2019/12/31 15:01
@Desc:
"""
from configobj import ConfigObj
class parseConfig():
    def __init__(self,section,config_dir):
        """
        :param section: ini文件的主题
        :param config_dir: ini文件的路径
        """
        self.file=config_dir
        self.section= section
        self.configfile=ConfigObj(self.file,encoding='utf-8')
    def get_all_sections(self):
        #获取所有的section
        return self.configfile.sections
    def get_all_options(self):
        #获取指定的section内容
        return self.configfile[self.section]
    def split_content(self,option):
        #拆解对应的数据
        section = self.section
        try:
            xpath_result = self.configfile[section][option]
            if '$' in xpath_result:
                xpath_result=self.configfile[section][xpath_result]
            if '>>' in xpath_result:
                return xpath_result.split('>>')
            else:
                return ['By.XPATH',xpath_result]  #默认xpath格式
        except Exception as  e:
            print ('error',e)

if __name__ == '__main__':

    value = parseConfig('test_baidu')
    print (value)

    # print (value.get_all_sections())
    # print (value.get_all_options())
    print (value.split_content('设置'))

 

这里就是对ini文件的解析,我们看看ini文件的格式product.ini

[test_cateorgy]
添加分类=//*[@id="buttonFrame"]/div/ul/li/a
分类名称=//*[@id="category.categoryName"]/input
显示顺序=//*[@id="category.categoryOrder"]/input
中文报关名称=//*[@id="category.declareCnName"]/input
英文报关名称=//*[@id="category.declareEnName"]/input
保存(新增)=//span[@id="ButtonSave"]/a
保存并继续新建=//*[@id="ButtonSave_Continue"]/a
成功提示=//div[@class='mt5']//span[@class='ico_agreen left']

,我们以key,value的形式来说明,其中key就对应到了我们测试用例中的信息,value就是元素的路径,这里我默认的是xpath路径,如果是非xpath的时候,就要把方式和路径都写到ini文件中,并且用>>来分割,对应的代码就是这段

 if '>>' in xpath_result:
                return xpath_result.split('>>')

通过packaging类中的split_content的函数,返回的就是by,value了。把by  value写过去,就能执行driver.find_element(eval(by),value).click()了。最后显示到脚本中的格式就变成了

product.click_obj(driver,ini文件中的key)

 

大致的结构就是这样了,不知道说明白了没。。。。。。接下来就是引入测试报告。明天说。

 

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值