python基礎(chǔ)之類與對象的應(yīng)用-操作excel

python操作excel

openpyxl

  • 前置說明

    • 安裝openpyxl
    • 只支持.xlsx后綴
  • 創(chuàng)建excel

    • 手動創(chuàng)建:日常手動創(chuàng)建,雙擊excel圖標(biāo)
    • 代碼創(chuàng)建:后面講
  • 打開excel

    image
    from openpyxl import load_workbook
    # 1.打開excel
    wb=load_workbook("test.xlsx")
    # 2.定位表單
    sheet=wb["test001"] #必須傳入表單名,返回表單對象
    # 3.定位但單元格 行列值
    value=sheet.cell(1,1).value #第1行第1列的單元格.值
    #打印單元格的值
    print(value)
    #最大行
    print("最大行:",sheet.max_row)
    #最大列
    print("最大列:",sheet.max_column)
    
image
  • 數(shù)據(jù)從excel中拿出來是什么類型

    #數(shù)據(jù)從excel中拿出來是什么類型
    print("學(xué)號是:",sheet.cell(1,1).value,type(sheet.cell(1,1).value))
    print("分?jǐn)?shù)是:",sheet.cell(1,2).value,type(sheet.cell(1,2).value))
    print("不及格率:",sheet.cell(1,3).value,type(sheet.cell(1,3).value))
    print("住址是:",sheet.cell(1,4).value,type(sheet.cell(1,4).value))
    

    結(jié)果是:數(shù)字還是數(shù)字,其他都是字符

    學(xué)號是: 18 <class 'int'>
    分?jǐn)?shù)是: {"語文":90,"數(shù)字":98,"生物":78} <class 'str'>
    不及格率: 0.3 <class 'float'>
    住址是: 中國上海 <class 'str'>
    
  • eval() 把數(shù)據(jù)類型轉(zhuǎn)換為原本的類型(僅限被轉(zhuǎn)為字符串)

    s="True" #布爾值轉(zhuǎn)為字符串
    print(type(s))  #<class 'str'>
    a=eval(s)#使用eval函數(shù),將字符串類型轉(zhuǎn)為原來的布爾類型
    print(type(a)) #<class 'bool'>
    
  • 封裝一個獲取excel值的工具類

    • 方法一:把數(shù)據(jù)一次取出,調(diào)用一次取出sheet所有數(shù)據(jù)(建議使用)

      from openpyxl import load_workbook
      class GetExcel:
          def __init__(self,file_name,sheet_name):
              self.file_name=file_name
              self.sheet_name=sheet_name
      
          def get_data(self):
              wb=load_workbook(self.file_name)
              sheet=wb[self.sheet_name]
              test_data=[] #每條數(shù)據(jù)要存在列表里
              for i in range(1, sheet.max_row+1):
                  sub_data={}
                  sub_data["age"]=sheet.cell(i,1).value
                  sub_data["score"]=sheet.cell(i,2).value
                  sub_data["percent"]=sheet.cell(i,3).value
                  sub_data["local"]=sheet.cell(i,4).value
                  test_data.append(sub_data)
              return test_data
      
      ex=GetExcel("test.xlsx","test001")
      print("測試數(shù)據(jù):",ex.get_data())
      
    • 方法二:數(shù)據(jù)需要的時候再調(diào)用,調(diào)用一次取出一個單元格數(shù)據(jù)

    ```
    from openpyxl import load_workbook
    class DoExcel:
        """
        獲取excel單元格的值
        """
        def __init__(self,file_name,sheet_name):
            """
            
            :param file_name: excel文件名
            :param sheet_name: sheet名
            """
            self.file_name=file_name
            self.sheet_name=sheet_name
    
        def get_excel(self,i,j):
            """
            
            :param i: 第幾行
            :param j: 第幾列
            :return: 返回對應(yīng)單元格的值
            """
            wb=load_workbook(self.file_name)
            sheet=wb[self.sheet_name]
            return sheet.cell(i,j).value
        
         def get_max_row(self):
            """
            :return: sheet的最大行數(shù)
            """
            return self.sheet_obj.max_row

        def get_max_col(self):
            """
            :return: sheet的最大列數(shù)
            """
            return self.sheet_obj.max_column
            
    if __name__ == '__main__': #測試
        do=DoExcel("test.xlsx","test001")
        print(do.get_excel(1,1))
    ```

ddt

  • 安裝ddt

  • ddt+unittest進(jìn)行數(shù)據(jù)處理

    • 裝飾器,暫時不用過多了解,不影響函數(shù)的情況下運行

    • ddt示例

      • @ddt 裝飾測試類
      • @data 傳入數(shù)據(jù)
      • @unpack 針對拿到的每一條數(shù)據(jù),根據(jù)逗號進(jìn)行拆分
      from ddt import ddt,unpack,data #導(dǎo)入ddt
      import unittest
      
      test_data=[1,4] #測試數(shù)據(jù)
      test_body=[[3,4],[2,3]]
      test_param=[[3,4],[2,3,7]]
      test_dict=[{"no":1,"name":"anny"},{"no":2,"name":"liu"}]
      
      @ddt #裝飾測試類
      class TestMath(unittest.TestCase):
      
          @data(test_data)
          def test_print_data(self,item): #一條用例
              print("item:",item) #item: [1, 4]
              
          @data(*test_data) #裝飾測試方法,拿到幾條數(shù)據(jù)執(zhí)行幾條用例
          #不定長參數(shù),俗稱:脫外套
          def test_print_data_01(self,item):
              print("item:", item)  # item: 1  item: 4
          
          @data(*test_body) #脫外套只脫一層
          def test_print_data_02(self,item):
              print("item:",item) #item: [3, 4]  item: [2, 3]
              
          @data(*test_body)
          @unpack #針對拿到的每一條數(shù)據(jù),根據(jù)逗號進(jìn)行拆分,
          def test_print_data_03(self,a,b): #參數(shù)個數(shù)對應(yīng)@npack拆分的個數(shù),否則會報錯
              print("a:",a)
              print("b:",b)
          # 輸出: 
          # a: 3 b: 4
          # a: 2 b: 3
          
          
          @data(*test_param)
          @unpack
          #對于每一條測試用例的數(shù)據(jù)不等長時,可以采用默認(rèn)值為None的方式接收避免報錯
          def test_print_data_04(self,a=None,b=None,c=None):
              print("a:",a)
              print("b:",b)
              print("c:",c)    
          
          # 輸出:
          # a: 3 b: 4 c: None
          # a: 2 b: 3 c: 7
          
          @data(*test_dict)
          @unpack
          #對字典進(jìn)行unpack,參數(shù)名與你的字典key對應(yīng)
          def test_print_data_05(self,no,name):
              print("no:",no)
              print("name:",name)
      
      • 使用unpack,data里的參數(shù)記得加*
      • 參數(shù)數(shù)據(jù)過長時,不建議用@unpack,@data拿到后根據(jù)索引取值
      • 光標(biāo)放在代碼最后面再run,不然會報錯
      • 對字典進(jìn)行unpack,參數(shù)名與你的字典key對應(yīng)

DDT與excel結(jié)合使用

  • 加載測試用例時,要使用TestLoader方法加載

總結(jié)unittest+excel

  • 兩種方式
    • 超繼承
    • ddt
  • 思路
    • 自己寫的類
    • unittest單元測試:實現(xiàn)對自己寫的類的測試
    • TestCase測試用例:self.assert斷言、異常處理
    • 參數(shù)化:數(shù)據(jù)可以寫在代碼里,也可以寫在excel里,excel使用openpyxl
      • 處理數(shù)據(jù)寫成類 class GetExcel:
    • 數(shù)據(jù)與unittest結(jié)合起來
      • 超繼承(原理要懂)
      • ddt (推薦使用)

配置文件

用例的可配置

有時,我們需要run不同程度的case、不同模塊的case,所以需要case的一個可配置性

image
from openpyxl import load_workbook
class GetExcel:
    def __init__(self,file_name,sheet_name):
        self.file_name=file_name
        self.sheet_name=sheet_name

    def get_data(self,button="all"):
        """
        約定參數(shù)button,默認(rèn)值為all。
        如果button值為“all”,則表示運行所有的case;
        如果button的值為一個case_id的列表,按照列表里的case_id進(jìn)行運行。
        """
        wb=load_workbook(self.file_name)
        sheet=wb[self.sheet_name]
        test_data=[] #每條數(shù)據(jù)要存在列表里
        for i in range(2, sheet.max_row+1): #第一行是title,所以從第二行開始
            sub_data={}
            sub_data["case_id"] = sheet.cell(i, 1).value
            sub_data["mouble"] = sheet.cell(i, 2).value
            sub_data["age"]=sheet.cell(i,3).value
            sub_data["score"]=sheet.cell(i,4).value
            sub_data["percent"]=sheet.cell(i,5).value
            sub_data["local"]=sheet.cell(i,6).value
            test_data.append(sub_data)
        #對傳入的button值進(jìn)行判斷
        if button == "all":
            finally_data=test_data
        else: #[1,2,3,4]
            finally_data=[]
            for item in test_data:
                if item["case_id"] in button:
                    finally_data.append(item)
        return finally_data

if __name__ == '__main__':
    ex=GetExcel("testdata.xlsx","Sheet1")
    print("測試數(shù)據(jù):",ex.get_data()) #所有數(shù)據(jù)
    print("測試數(shù)據(jù):", ex.get_data([1,3])) #第一條、第三條測試數(shù)據(jù)
配置文件

平常工作中可能會常見到.properties .config .ini .log4j(.log4j是java中的配置文件,python不用)結(jié)尾的文件,這些都是配置文件。python中有configparser模塊可以去讀取配置信息

  • 配置文件的規(guī)范

    • 新建一個文件以.config結(jié)尾,.properties、.ini都可以
    • section 片段,配置文件中用[]區(qū)分,表示不同區(qū)域的數(shù)據(jù)
    • option=value,鍵值對,相當(dāng)于key:value
    #case.config文件
    
    [BUTTON] #section
    button=all #option=value
    
    [PYTHON11] #section
    num=30  #option、value
    monitor=小月 #option=value 
    
  • 讀取配置文件

    import configparser
    
    cf=configparser.ConfigParser()
    cf.read("case.config",encoding="utf-8")
    
    #獲取配置文件的數(shù)據(jù)
    # 方法一
    res_1=cf.get("BUTTON","button") #(section,option)獲取對應(yīng)option的value
    print(res_1) #all
    # 方法二
    res_2=cf["BUTTON"]["button"]
    print(res_2) #all
    
    #獲取所有的section
    res_3=cf.sections()
    print(res_3) #['BUTTON', 'PYTHON11']
    
    #獲取option和value,每對以元組形式返回在一個列表里
    res_4=cf.items("PYTHON11")
    print(res_4) #[('num', '30'), ('monitor', '小月')]
    
  • 數(shù)據(jù)類型

    直接獲取的數(shù)據(jù)類型都是字符串,使用eval()轉(zhuǎn)換為原始數(shù)據(jù)類型

    res_1 = cf.get("BUTTON", "button")
    print(type(res_1)) #<class 'str'>
    res_2=cf.get("PYTHON11", "num")
    print(type(res_2)) #<class 'str'>
    
    #使用eval()轉(zhuǎn)換為原始數(shù)據(jù)類型
    res_3 =cf.get("python11", "num")
    print(type(eval(res_3)))
    
  • 封裝為一個工具類

    • tools文件夾中寫入配置文件case.config
      [BUTTON]
      button=all
      #button=[1,2]
      
      
    • tools文件夾中寫一個工具類class ReadConfig:
      import configparser
      
      class ReadConfig:
          def read_config(self,file_name,section,option):
              cf=configparser.ConfigParser()
              cf.read(file_name,encoding="utf-8")
              return eval(cf.get(section,option))
      
      
      if __name__ == '__main__':
          rc=ReadConfig()
          res=rc.read_config("case.config","BUTTON","button")
          print(res) #all
      
    • 原來的do_excel工具類要加以修改,加入讀取配置文件
      from openpyxl import load_workbook
      from API_AUTO.tools import read_config
      
      class GetExcel:
          def __init__(self,file_name,sheet_name):
              self.file_name=file_name
              self.sheet_name=sheet_name
      
      def get_data(self):
          #讀取配置文件
          button=read_config.ReadConfig().read_config("case.config","BUTTON","button")
          wb=load_workbook(self.file_name)
          sheet=wb[self.sheet_name]
          test_data=[] #每條數(shù)據(jù)要存在列表里
          for i in range(2, sheet.max_row+1):
              sub_data={}
              sub_data["case_id"] = sheet.cell(i, 1).value
              sub_data["mouble"] = sheet.cell(i, 2).value
              sub_data["age"]=sheet.cell(i,3).value
              sub_data["score"]=sheet.cell(i,4).value
              sub_data["percent"]=sheet.cell(i,5).value
              sub_data["local"]=sheet.cell(i,6).value
              test_data.append(sub_data)
      
          if button == "all":
              finally_data=test_data
          else: #[1,2,3,4]
              finally_data=[]
              for item in test_data:
                  if item["case_id"] in button:
                      finally_data.append(item)
          return finally_data
      
      if __name__ == '__main__':
      
          ex=GetExcel("testdata.xlsx","Sheet1")
          print("測試數(shù)據(jù):",ex.get_data())
      
      這樣根據(jù)給配置文件button配置不同的值,all或者case_id的列表,run不同的數(shù)據(jù)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容