設計から開発までのテストの自動化へのPythonインタフェース

7、Excelデータの読み取り

ユースケースは、データを読み書きデータはxluntilsを使用する必要があり、インストールするxlrdと、Excelで配置されています。

pip install xlrd

pip install xluntils

7.1、設定ファイルを読み込み

Excelのデータを読み込み、我々は、列が比較的固定され、設定ファイルに定義された設定し、その後は、パラメータとして行を、読んで対応する行と列を知っている必要があります。次のように定義されたのconf /設定ファイルは以下のとおりです。

[excel]
case_no=0
case_name=1 is_run=2 case_level=3 case_header=4 case_cookies=5 req_type=6 case_url=7 case_body=8 expect_result=9 operator=10 actual_result=11 test_result=12

unitls / load_conf.py構成方法、列の値を取得するための方法を読んで書きます。文字列識別子の設定項目、設定項目の種類:lood_conf()関数は2つの引数を取ります。例えば、次の整数を読み取るためにはcase_urlをエクセル:lood_conf( "excel.case_url"、 "INT")。返されたクラスexcel_config列の値の方法(下記)に定義されています。

次のように完全なコードは次のとおりです。

import  configparser

'''
read conf from setting.conf
@:parameter:identstr,value_type
value_type:"int" or "str"
'''
def lood_conf(identstr,value_type): cf = configparser.ConfigParser() cf.read("../config/settings.conf") idenlist = identstr.split('.') if value_type == "int": try: value = cf.getint(idenlist[0],idenlist[1]) return value except (configparser.NoSectionError ,configparser.NoOptionError) as e: print(e) if value_type == "str": try: value = cf.get(idenlist[0],idenlist[1]) return value except (configparser.NoSectionError ,configparser.NoOptionError) as e: print(e) ''' 获取url,request body等的列号 ''' class excel_config(): #获取用例编号的列 def caseno_col(self): return lood_conf("excel.case_no","int") def casename_col(self): return lood_conf("excel.case_name","int") def isrun_col(self): #print(lood_conf("excel.is_run","int")) return lood_conf("excel.is_run","int") def level_col(self): return lood_conf("excel.case_level","int") def header_col(self): return lood_conf("excel.case_header","int") def cookies_col(self): return lood_conf("excel.case_cookies","int") def reqtype_col(self): return lood_conf("excel.req_type","int") def caseurl_col(self): return lood_conf("excel.case_url","int") def casebody_col(self): return lood_conf("excel.case_body","int") def expectresult_col(self): return lood_conf("excel.expect_result","int") def actualresult_col(self): return lood_conf("excel.actual_result","int") def testresult_col(self): return lood_conf("excel.test_result","int") def test_operator_col(self): return lood_conf("excel.operator","int") 

7.1、Excelのクラスの操作を書きます

unitls / excel_tool.pyケースは、ユースケース方法等番号、名前、定義を選択ライン渡す必要があります。OK、値:ライトバックテスト結果は、実際の結果がライトバック方式は、2つの引数が必要です。次のように完全なコードは次のとおりです。

#coding:utf-8
import xlrd
from untils.log_trace import *
from xlutils.copy import copy
from untils.load_conf import excel_config

class excel_tool():

    def __init__(self,excel_name): self.curr_excel = xlrd.open_workbook(excel_name) self.table = self.curr_excel.sheet_by_index(0) #print(self.table.cell(1,1).value) #实例化excel_config self.config = excel_config() self.rows = self.table.nrows self.excel_name = excel_name #获取用例编号 def get_caseno(self,row): caseno = self.table.cell(row,self.config.caseno_col()).value if caseno: return caseno else: logging.info("case no is null") return None #获取用例名称 def get_casename(self,row): casename = self.table.cell(row,self.config.casename_col()).value return casename #获取是否运行标志 def get_runflag(self,row): run_flag = self.table.cell(row,self.config.isrun_col()).value return run_flag #获取用例级别 def get_caselevel(self,row): caselevel = self.table.cell(row,self.config.level_col()).value return caselevel #获取请求url def get_caseurl(self,row): caseurl = self.table.cell(row,self.config.caseurl_col()).value return caseurl #获取请求body def get_casebody(self,row): case_body = self.table.cell(row,self.config.casebody_col()).value return case_body #获取header def get_headerflag(self,row): headerflag = self.table.cell(row,self.config.header_col()).value return headerflag #获取coocikes def get_cookiesflag(self,row): cookiesflag = self.table.cell(row,self.config.cookies_col()).value return cookiesflag #获取请求类型 def get_methodtype(self,row): method_type = self.table.cell(row,self.config.reqtype_col()).value return method_type #获取预期结果 def get_expectres(self,row): expect_res = self.table.cell(row,self.config.expectresult_col()).value return expect_res #获取测试结果 def get_testres(self,row): test_res= self.table.cell(row,self.config.testresult_col()).value return test_res #获取操作符 def get_operator(self,row): operator = self.table.cell(row,self.config.test_operator_col()).value return operator #回写测试结果到excel def write_testres(self,row,value): wbook = copy(xlrd.open_workbook(self.excel_name)) sheet = wbook.get_sheet(0) sheet.write(row, self.config.testresult_col(), value) wbook.save(self.excel_name) #回写实际结果 def write_actualres(self,row,value): wbook = copy(xlrd.open_workbook(self.excel_name)) sheet = wbook.get_sheet(0) sheet.write(row, self.config.actualresult_col(), value) wbook.save(self.excel_name) 

図8に示すように、ケースの組立

Excelベースの操作で、簡単にデータを読み取り、その結果を埋め戻すことができます。一実施形態で組み立て次、unitlsに/ run_main.py。組立前に、フラグRUNを取得します:

  • 実行フラグが場合は、skiiped付いExcelにテスト結果をバックフィル組み立てることなく、Nです。
  • 実行フラグがYであり、ユースケースは組み立て、および予想と実際の結果を比較するために始めた実行します。
  • ユースケースによって行われ、例はパス、バックフィルテストと実際の結果、実際の結果が返されるインターフェイスが付いて。
  • 失敗例のケースを使用してテストと実際の結果埋め戻し、失敗した標識使用します。

インタフェースは、この問題は、上記のプロセスでは、必要性は、問題を見つけて、ユースケースの実行ログを表示するために、簡単なロギングを高めるために、後に解決され、run_main.pyで死亡書き込むには、認証ヘッダーを使用する必要があります。次のように完全なコードは次のとおりです。

#coding:utf-8
from untils.excel_tool import excel_tool
from untils.send_request import send_request
from untils.log_trace import *
from untils.check_result import CheckResult
import  json
headers = {
    "X-Token":"0a6db4e59c7fff2b2b94a297e2e5632e"
}

class runner(): def __init__(self): self.excel = excel_tool("../testcase/test.xls") self.check = CheckResult() def join_case(self): global skip_list,sucess_list,failed_list,skip_list sucess_list = [] sucess_list = [] failed_list = [] skip_list = [] for row in range(1,self.excel.rows): no = self.excel.get_caseno(row) url = self.excel.get_caseurl(row) isrun = self.excel.get_runflag(row) name = self.excel.get_casename(row) level = self.excel.get_caselevel(row) data = self.excel.get_casebody(row) expect_res = self.excel.get_expectres(row) method = self.excel.get_methodtype(row) hasheader = self.excel.get_headerflag(row) operator = self.excel.get_operator(row) if isrun == "Y": logging.info("Begin to run test case : %s,case number :%s" %(name,no)) logging.info("Request method type is :%s" %method) logging.info("Request URL:%s" %url) logging.info("Request Body:%s" %json.dumps(json.loads(data),sort_keys=True,indent=2)) res = send_request(method,url,data=data,headers=headers) is_sucess = self.check.cmpdict(eval(expect_res),eval(res.text),operator) print(is_sucess) if is_sucess: sucess_list.append(name) #回写测试结果 self.excel.write_testres(row,"pass") #回写实际结果 self.excel.write_actualres(row,res.text) logging.info("Test case %s run sucess." %name) else: failed_list.append(name) print("fail",is_sucess) #回写测试结果 self.excel.write_testres(row,"failed") #回写实际结果 self.excel.write_actualres(row,res.text) logging.error("Test case %s run fail." %name) logging.info("Response is:%s" %json.dumps(res.json(),sort_keys=True,indent=2)) else: skip_list.append(name) self.excel.write_testres(row,"skipped") def sum(self): total = len(sucess_list)+len(failed_list) + len(skip_list) failed = len(failed_list) sucess = len(sucess_list) logging.info("-----------------------------------------------------------") logging.info("本次一共运行:%s 个用例" %total) logging.info("本次运行通过:%s 个用例" %sucess) logging.info("本次运行跳过:%s 个用例" %len(skip_list)) logging.info("跳过的用例:%s" %skip_list) logging.info("-----------------------------------------------------------") 

動作確認実施例の結果を図9に示すように、

期待される結果辞書、辞典、実際、オペレータ:untils / run_main.py方法cmpdictに()が期待と実際の結果の一致を確認するために使用され、それは3つの引数を必要とします。例で製造した方法は、チェック結果をcheck_result.py。現在、2つだけのオペレータ、辞書を入れ子にすることはできません辞書、平等とNOTEQUAL、期待される結果をサポートしています。以下のように、完全なコードは次のとおりです。

from untils.log_trace import *
class  CheckResult():
    def dict_value(self,key,actual):
        try:
            if key in actual: return actual[key] else: for keys in actual: return self.dict_value(key,actual[keys]) except Exception as e: logging.error(e) return None def cmpdict(self,expect,actual,equal): logging.info("Begin to check result of testcase.") is_dict = isinstance(expect,dict) and isinstance(actual,dict) if is_dict: if equal == "equal": for key in expect.keys(): if expect[key] == self.dict_value(key,actual): logging.info("%s is equal to %s" %(expect[key],self.dict_value(key,actual))) return True else: logging.error("%s is not equal to %s" %(expect[key],self.dict_value(key,actual))) return False if equal == "notequal": for key in expect.keys(): if key != self.dict_value(key,actual): logging.info("%s is not equal to %s" %(expect[key],self.dict_value(key,actual))) return True else: logging.error("%s is equal to %s" %(expect[key],self.dict_value(key,actual))) return False else: logging.error("Operator :%s is not support now,you can define it in file[check_result.py]" %equal) else: logging.error("Expect or actual result is not dict,check it in excel. ")

ケースで操作10、

エクセルのTest.xlsをの名前を作成し、テストケースのパスの下に置き、そしてExcelでテストケースの作成。インタフェースの開発を参照してください:CRUDの記事:Djangoの開発にシンプルなインターフェイスを使用して、たとえば、私が使用するつもりです、:

それをテストするuntils_test.pyインポートrun_mianモジュールuntils /:

from untils.run_main import runner
if __name__ == "__main__":
    #test_send_request() runner = runner() runner.join_case() runner.sum()

untils_test.py実行し、その結果を表示するために、Excelに行きます:

次のようにパステストレポートの操作ログを参照してください。

Sat, 11 May 2019 19:37:56 INFO check_result.py [line:16]  Begin to check result of testcase. Sat, 11 May 2019 19:37:56 ERROR check_result.py [line:38] Operator :e1qual is not support now,you can define it in file[check_result.py] Sat, 11 May 2019 19:37:56 INFO run_main.py [line:37] Begin to run test case : 查询文章,case number :1.0 Sat, 11 May 2019 19:37:56 INFO run_main.py [line:38] Request method type is :GET Sat, 11 May 2019 19:37:56 INFO run_main.py [line:39] Request URL:http://127.0.0.1:9000/articles Sat, 11 May 2019 19:37:56 INFO run_main.py [line:40] Request Body:{} Sat, 11 May 2019 19:37:56 INFO send_request.py [line:25] {'X-Token': '0a6db4e59c7fff2b2b94a297e2e5632e'} Sat, 11 May 2019 19:37:56 INFO check_result.py [line:16] Begin to check result of testcase. Sat, 11 May 2019 19:37:56 INFO check_result.py [line:22] BS.200 is equal to BS.200 Sat, 11 May 2019 19:37:56 INFO run_main.py [line:52] Test case 查询文章 run sucess. Sat, 11 May 2019 19:37:56 INFO run_main.py [line:62] Response is:{ "all_titles": { "Hello": "alive", "amy1": "alive", "modifytest": "alive", "useasge of ddt": "alive" }, "msg": "query articles sucess.", "status": "BS.200" } Sat, 11 May 2019 19:37:56 INFO run_main.py [line:37] Begin to run test case : 新增文章,case number :2.0 Sat, 11 May 2019 19:37:56 INFO run_main.py [line:38] Request method type is :POST Sat, 11 May 2019 19:37:56 INFO run_main.py [line:39] Request URL:http://127.0.0.1:9000/articles/ Sat, 11 May 2019 19:37:56 INFO run_main.py [line:40] Request Body:{ "content": "useasge of ddt", "title": "useasge of ddt" } Sat, 11 May 2019 19:37:56 INFO send_request.py [line:25] {'X-Token': '0a6db4e59c7fff2b2b94a297e2e5632e'} Sat, 11 May 2019 19:37:56 INFO check_result.py [line:16] Begin to check result of testcase. Sat, 11 May 2019 19:37:56 ERROR check_result.py [line:25] BS.200 is not equal to BS.400 Sat, 11 May 2019 19:37:56 ERROR run_main.py [line:60] Test case 新增文章 run fail. Sat, 11 May 2019 19:37:56 INFO run_main.py [line:62] Response is:{ "msg": "title aleady exist,fail to publish.", "status": "BS.400" } Sat, 11 May 2019 19:37:56 INFO run_main.py [line:37] Begin to run test case : 修改文章,case number :3.0 Sat, 11 May 2019 19:37:56 INFO run_main.py [line:38] Request method type is :POST Sat, 11 May 2019 19:37:56 INFO run_main.py [line:39] Request URL:http://127.0.0.1:9000/articles/7 Sat, 11 May 2019 19:37:56 INFO run_main.py [line:40] Request Body:{ "content": "modify test", "title": "modify test" } Sat, 11 May 2019 19:37:56 INFO send_request.py [line:25] {'X-Token': '0a6db4e59c7fff2b2b94a297e2e5632e'} Sat, 11 May 2019 19:37:57 INFO check_result.py [line:16] Begin to check result of testcase. Sat, 11 May 2019 19:37:57 ERROR check_result.py [line:25] BS.200 is not equal to BS.300 Sat, 11 May 2019 19:37:57 ERROR run_main.py [line:60] Test case 修改文章 run fail. Sat, 11 May 2019 19:37:57 INFO run_main.py [line:62] Response is:{ "msg": "article is not exists,fail to modify.", "status": "BS.300" } Sat, 11 May 2019 19:37:57 INFO run_main.py [line:37] Begin to run test case : 删除文章,case number :4.0 Sat, 11 May 2019 19:37:57 INFO run_main.py [line:38] Request method type is :DELETE Sat, 11 May 2019 19:37:57 INFO run_main.py [line:39] Request URL:http://127.0.0.1:9000/articles/7 Sat, 11 May 2019 19:37:57 INFO run_main.py [line:40] Request Body:{} Sat, 11 May 2019 19:37:57 INFO send_request.py [line:25] {'X-Token': '0a6db4e59c7fff2b2b94a297e2e5632e'} Sat, 11 May 2019 19:37:57 INFO check_result.py [line:16] Begin to check result of testcase. Sat, 11 May 2019 19:37:57 ERROR check_result.py [line:25] BS.200 is not equal to BS.300 Sat, 11 May 2019 19:37:57 ERROR run_main.py [line:60] Test case 删除文章 run fail. Sat, 11 May 2019 19:37:57 INFO run_main.py [line:62] Response is:{ "msg": "article is not exists,fail to delete.", "status": "BS.300" } Sat, 11 May 2019 19:37:57 INFO run_main.py [line:74] ----------------------------------------------------------- Sat, 11 May 2019 19:37:57 INFO run_main.py [line:75] 本次一共运行:5 个用例 Sat, 11 May 2019 19:37:57 INFO run_main.py [line:76] 本次运行通过:1 个用例 Sat, 11 May 2019 19:37:57 INFO run_main.py [line:77] 本次运行跳过:1 个用例 Sat, 11 May 2019 19:37:57 INFO run_main.py [line:78] 跳过的用例:['新增文章缺少title'] Sat, 11 May 2019 19:37:57 INFO run_main.py [line:79] ----------------------------------------------------------- 

11まとめ

フレームワークは、ついに実行されますが、まだ多くの問題が残さ。

  • 多くの地元のコードは、この背後にゆっくりとロバスト最適化ではありません。例チェックオペレータのサポートもあまり使用しています。
  • 行われなければ、電子メールモジュールを送信します。
  • ヘッダは、どのように問題を解決するには?
  • Excelで書かれた多くの要求されたボディは、それは非常にきれいではありませんか?これは、ファイルを読むために一定の場所から行うことができます。
  • エクセル、何の必須テストはありませんか?これは、チェック結果を実行する前に行うことができ、必要な不足している、実行しないでください。
  • 第2の使用ケースは、リターンの最初のユースケースに依存している場合、最も重要なポイントは、ユースケースは、次の解決、依存痛いポイントとなっています。

おすすめ

転載: www.cnblogs.com/cs1188/p/11516946.html