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)

 

大致的結構就是這樣了,不知道說明白了沒。。。。。。接下來就是引入測試報告。明天說。

 

發佈了106 篇原創文章 · 獲贊 22 · 訪問量 27萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章