Python httpインターフェース自動化テストを実現するコード例


オンラインhttpインターフェース自動化テストPythonはたくさんあります。私も憧れの授業でネットで関連した授業を勉強しました。実際にもう一度操作しました。そこでいくつかの総括を行いました。今後の復習に便利です。
インタフェーステストでよく使われるツールはfiddler、postman、jmeterなどがあります。これらのツールを使ってテストする時、よく使われるインターフェースの種類と違いを知る必要があります。例えば、私が使っているpostとget要求は、表面的にはgetを見てデータpostを取得してデータを修正します。両者のパラメータを伝える方式も違います。パラメータを接続しますが、postはHTTPのパッケージにデータを入れています。両者の本質はTCPリンクです。違いはありませんが、HTTPの規定とブラウザ/サーバーの制限によって、アプリケーションの中にいくつかの違いが現れます。具体的にはこのブログを参考にして説明するのが分かりやすいです。これらはツールで直接選択できます。pythonはrequestsパッケージを借りる必要があります。
インターフェースタイプを確定したら、テストデータと設計テスト用例を準備することが必要です。テスト用例は戻り状態応答コードを判断したり、戻りデータを判別することができます。具体的にはpostmanのecho.co llectionを参照して、pythonに対してunittestでテスト用例と追加判定を組織することができます。テストデータの準備については、データと業務をできるだけ分離して、データのパラメータ化をテストします。ツールで変数を追加する形で実現できます。
テストが完了したら生産報告書やメールを送ります。HTMLT estRunnerやsmatplibなども使えます。
私もこの三つの方面からまとめます。
1.インターフェース方法の実現とパッケージ化
requestsライブラリはHTTP要求を実現するのにとても良い助けになります。API参照ドキュメント、ここで私はrunmethod.pyを作成しました。中にはRunMethod類が含まれています。
这里写图片描述
ここで注意したいのは、pythonのデフォルトパラメータとオプションパラメータは、必ず選択されたパラメータの後ろに置いて、対応するデータに対してjsonフォーマットを使って返します。パラメータverify=falseはSSL証明書の検証を無視することを表します。
2.組織テストと生成報告
unittestを使ってテストを組織し、テスト用の例を追加し、断言します。テストレポートはHTMLTS Runner.pyをダウンロードし、pythonインストール経路libの下に置いてもいいです。コードは以下の通りです。

#coding:utf-8
import unittest
import json
import HTMLTestRunner
from mock import mock
#from demo import RunMain
from runmethod import RunMethod
from mock_demo import mock_test
import os
class TestMethod(unittest.TestCase):
	def setUp(self):
		#self.run=RunMain()
		self.run = RunMethod()
	def test_01(self):
		url = 'http://coding.imooc.com/api/cate'
		data = {
			'timestamp':'1507034803124',
			'uid':'5249191',
			'uuid':'5ae7d1a22c82fb89c78f603420870ad7',
			'secrect':'078474b41dd37ddd5efeb04aa591ec12',
			'token':'7d6f14f21ec96d755de41e6c076758dd',
			'cid':'0',
			'errorCode':1001
		}
		#self.run.run_main = mock.Mock(return_value=data)
		res = mock_test(self.run.run_main,data,url,"POST",data)
		#res = self.run.run_main(url,'POST',data)
		print(res)
		self.assertEqual(res['errorCode'],1001,"    ")


	@unittest.skip('test_02')	
	def test_02(self):
		
		url = 'http://coding.imooc.com/api/cate'
		data = {
			'timestamp':'1507034803124',
			'uid':'5249191',
			'uuid':'5ae7d1a22c82fb89c78f603420870ad7',
			'secrect':'078474b41dd37ddd5efeb04aa591ec12',
			'token':'7d6f14f21ec96d755de41e6c076758dd',
			'cid':'0'

		}

		res = self.run.run_main(url,'GET',data)
		self.assertEqual(res['errorCode'],1006,"    ")

	def test_03(self):
		url = 'http://coding.imooc.com/api/cate'
		data = {
			'timestamp':'1507034803124',
			'uid':'5249191',
			'uuid':'5ae7d1a22c82fb89c78f603420870ad7',
			'secrect':'078474b41dd37ddd5efeb04aa591ec12',
			'token':'7d6f14f21ec96d755de41e6c076758dd',
			'cid':'0',
			'status':11
			}

		res = mock_test(self.run.run_main,data,url,'GET',data)
		print(res)
		self.assertGreater(res['status'],10,'    ')

if __name__ == '__main__':

	filepath = os.getcwd()+'\\report.html'
	fp = open(filepath,'wb+')
	suite = unittest.TestSuite()
	suite.addTest(TestMethod('test_01'))
	suite.addTest(TestMethod('test_02'))
	suite.addTest(TestMethod('test_03'))
	runner = HTMLTestRunner.HTMLTestRunner(stream=fp,title='this is demo test')
	runner.run(suite)
	#unittest.main()
ここでsetUp()方法はテストの前に実行します。同じtearDown()方法があります。テストcaseはtestの先頭で作成して、TestSuit類を使ってテストキットを作成し、caseを追加して、run suiteを実行すればいいです。テストケースが多い場合、複数のテスト種別を生成し、TestLoader().LoadTestsFromTestCase( )を用いてテストケースを生成して、testsuiteに参加して実行することができる。
ここでは勉強したmock方法を使って、mockはアナログデータです。実際にデータを取得することができない時は、mockメソッドを使って、アナログで判別したいデータを生成します。ここでmock_。test方法は同様にパッケージ化された:

#coding:utf-8
from mock import mock
def mock_test(mock_method,request_data,url,method,response_data):
	mock_method = mock.Mock(return_value=response_data)
	res = mock_method(url,method,request_data)
	return res
ここでシミュレーションしたのはself.run.run_です。メインメソッドは、この方法の戻り値をレスポンスに設定します。data、そして最終的に我々が判断するのは、リターンの値resであり、test uuと組み合わせることができる。02コントラスト、

res = self.run.run_main(url,'GET',data)
だからまたパラメータurl、method、request_に入る必要があります。data、最後に該当データを返してもいいです。

res = mock_test(self.run.run_main,data,url,'GET',data)
ここでは、戻ったデータをdataと仮定し、判断条件としてerrorCode==1001及びstatus>10を任意にいくつか追加した。最後にレポートを作成しました。
这里写图片描述
3試験データ処理
この部分は主にテストデータの設計、データ抽出、パラメータ化、およびデータ依存性の解決を含む。ここではやはり慕授業のネット学習の例を例にとって、主にテスト目的と使用手順に基づいて設計しています。
这里写图片描述
ここでまず関連するのは、Excelテーブルの操作について、関連ライブラリimport xlrdを導入し、先に上記表のテスト用例について配置ファイルを作成することである。

class global_var:
	Id = '0'
	request_name = '1'
	url = '2'
	run = '3'
	request_way = '4'
	header = '5'
	case_depend = '6'
	data_depend = '7'
	field_depend = '8'
	data = '9'
	expect = '10'
	result = '11'
列に戻る関数を再定義します。例えばcaseIdとURLを取得します。

def get_id():
	return global_var.Id
def get_url():
	return global_var.url
3.1 Excelファイルを操作する
その後、Excelを操作するモジュールを作成します。主にExcel表の操作を含みます。フォーム、行、列、セルの内容などを取得します。

import xlrd
from xlutils.copy import copy
class OperationExcel:
	def __init__(self,file_name=None,sheet_id=None):
		if file_name:
			self.file_name = file_name
			self.sheet_id = sheet_id	
		else:
			self.file_name = '/dataconfig/case1.xls'
			self.sheet_id = 0
		self.data = self.get_data()
	#  sheets   
	def get_data(self):
		data = xlrd.open_workbook(self.file_name)
		tables = data.sheets()[self.sheet_id]
		return tables
	#        
	def get_lines(self):
		tables = self.data
		return tables.nrows
	#           
	def get_cell_value(self,row,col):
		return self.data.cell_value(row,col)
	#    
	def write_value(self,row,col,value):
		'''  excel  row,col,value'''
		read_data = xlrd.open_workbook(self.file_name)
		write_data = copy(read_data)
		sheet_data = write_data.get_sheet(0)
		sheet_data.write(row,col,value)
		write_data.save(self.file_name)
その中にデータを書いて、運転結果をExcelファイルに書き込むために、まずcopyでファイル全体をコピーして、get_を通じてsheet()が取得するsheetにはwrite()の方法があります。
3.2操作jsonファイル
要求データについては、キーワードに基づいてjsonファイルからフィールドを取り出すので、以下のようにjson形式のデータファイルが必要です。対応要求データの各キーワード:
这里写图片描述
だから、jsonファイルを操作するモジュールを作成する必要があります。

import json
class OperetionJson:
	def __init__(self,file_path=None):
		if file_path == None:
			self.file_path = '/dataconfig/user.json'
		else:
			self.file_path = file_path
		self.data = self.read_data()
	#  json  
	def read_data(self):
		with open(self.file_path) as fp:
			data = json.load(fp)
			return data
	#         
	def get_data(self,id):
		print(type(self.data))
		return self.data[id]
読み书き操作はjson.load(),json.dump()から伝わってきたのがファイルの文脈です。
3.3試験データを取得する
Excelとjsonの操作モジュールを定義した後、私達はそれを私達のテストフォームに適用して、データモジュールを取得することを定義します。

from util.operation_excel import OperationExcel
import data.data_config
from util.operation_json import OperetionJson
class GetData:
	def __init__(self):
		self.opera_excel = OperationExcel()
	#   excel  ,     case  	
	def get_case_lines(self):
		return self.opera_excel.get_lines()
	#      
	def get_is_run(self,row):
		flag = None
		col = int(data_config.get_run())
		run_model = self.opera_excel.get_cell_value(row,col)
		if run_model == 'yes':
			flag = True
		else:
			flag = False
		return flag
	#    header
	def is_header(self,row):
		col = int(data_config.get_header())
		header = self.opera_excel.get_cell_value(row,col)
		if header != '':
			return header
		else:
			return None
	#      
	def get_request_method(self,row):
		col = int(data_config.get_run_way())
		request_method = self.opera_excel.get_cell_value(row,col)
		return request_method
	#  url
	def get_request_url(self,row):
		col = int(data_config.get_url())
		url = self.opera_excel.get_cell_value(row,col)
		return url
	#      
	def get_request_data(self,row):
		col = int(data_config.get_data())
		data = self.opera_excel.get_cell_value(row,col)
		if data == '':
			return None
		return data
	#         data  
	def get_data_for_json(self,row):
		opera_json = OperetionJson()
		request_data = opera_json.get_data(self.get_request_data(row))
		return request_data
	#      
	def get_expcet_data(self,row):
		col = int(data_config.get_expect())
		expect = self.opera_excel.get_cell_value(row,col)
		if expect == '':
			return None
		return expect
	def write_result(self,row,value):
		col = int(data_config.get_result())
		self.opera_excel.write_value(row,col,value)
このモジュールは、Excel操作クラスを実例化してテストフォームを操作し、それぞれテスト運転に必要な各種条件を取得します。
3.4判断条件
ここで一つのcaseが通過するかどうかを判断すると、実際の結果と予想される結果を比較することになります。例えば、状態コードstatusが200であるかどうか、または戻りデータにあるフィールドが含まれているかどうかを確認します。

import json
import operator as op
class CommonUtil:
	def is_contain(self, str_one,str_two):
		'''
		                  
		str_one:      
		str_two:       
		'''
		flag = None
		#     res      ,unicode  string  
		if isinstance(str_one,unicode):
			str_one = str_one.encode('unicode-escape').decode('string_escape')
		return op.eq(str_one,str_two)
		if str_one in str_two:
			flag = True
		else:
			flag = False
		return flag

	def is_equal_dict(self,dict_one,dict_two):
		'''          '''
		if isinstance(dict_one,str):
			dict_one = json.loads(dict_one)
		if isinstance(dict_two,str):
			dict_two = json.loads(dict_two)
		return op.eq(dict_one,dict_two)

したがって、我々はexpecデータと対応するデータを得て、このカテゴリのis_contain()メソッドを呼び出して判断することができます。
3.5データ依存問題
私たちが実行するcaseの対応するデータが前のcaseのリターンデータに依存する場合、case 12の対応するデータrequest_data[ ]の値はcase 11のリターンデータresponse_data[ ]に更新すべきであるように、対応するデータを更新する必要がある。まずcase 11を実行してリターンデータを入手し、case 12の該当データを書き込んで、まずExcelを操作するモジュールを更新して加入します。

#        
	def get_cols_data(self,col_id=None):
		if col_id != None:
			cols = self.data.col_values(col_id)
		else:
			cols = self.data.col_values(0)
		return cols
	#     caseid       
	def get_row_num(self,case_id):
		num = 0
		cols_data = self.get_cols_data()
		for col_data in cols_data:
			if case_id in col_data:
				return num
			num = num+1
	#    ,       
	def get_row_values(self,row):
		tables = self.data
		row_data = tables.row_values(row)
		return row_data
	#     caseid         
	def get_rows_data(self,case_id):
		row_num = self.get_row_num(case_id)
		rows_data = self.get_row_values(row_num)
		return rows_data
つまり、私たちは依頼したcaseIdを通じて対応する行番号を見つけて、行全体の内容を手に入れます。私たちはデフォルトで列0の内容(caseId)を取得し、列全体を循環して依存caseIdをいくつかの行に見つけて、行全体のデータを返します。すなわち、方法get_rows_data(case_id)を実現します。その後、実行と更新を行います。依存データを専門に扱うモジュールを作成します。また、依存データを取得するためには、取得データモジュールを下記のように更新する必要があります。

#       key
	def get_depend_key(self,row):
		col = int(data_config.get_data_depend())
		depent_key = self.opera_excel.get_cell_value(row,col)
		if depent_key == "":
			return None
		else:
			return depent_key
	#     case  
	def is_depend(self,row):
		col = int(data_config.get_case_depend())
		depend_case_id = self.opera_excel.get_cell_value(row,col)
		if depend_case_id == "":
			return None
		else:
			return depend_case_id
	#        
	def get_depend_field(self,row):
		col = int(data_config.get_field_depend())
		data = self.opera_excel.get_cell_value(row,col)
		if data == "":
			return None
		else:
			return data
方法を、依存データを専門に扱うモジュールに適用する。

from util.operation_excel import OperationExcel
from base.runmethod import RunMethod
from data.get_data import GetData
from jsonpath_rw import jsonpath,parse
class DependdentData:
	def __init__(self,case_id):
		self.case_id = case_id
		self.opera_excel = OperationExcel()
		self.data = GetData()
	#  case_id    case_id     
	def get_case_line_data(self):
		rows_data = self.opera_excel.get_rows_data(self.case_id)
		return rows_data
	#      ,    
	def run_dependent(self):
		run_method = RunMethod()
		row_num = self.opera_excel.get_row_num(self.case_id)
		request_data = self.data.get_data_for_json(row_num)
		#header = self.data.is_header(row_num)
		method = self.data.get_request_method(row_num)
		url = self.data.get_request_url(row_num)
		res = run_method.run_main(method,url,request_data)
		return json.loads(res)#            json        
	#     key         case   ,    
	def get_data_for_key(self,row):
		depend_data = self.data.get_depend_key(row)
		response_data = self.run_dependent()
		json_exe = parse(depend_data)
		madle = json_exe.find(response_data)
		return [math.value for math in madle][0]
ここで、jsonspathは、xpathのようなマルチレベルのデータを見つけるために用いられ、すなわち、依存フィールドによって表される階層関係によって、戻りデータに対応する値を見つけ、最後にcaseを実行すると、データを更新する。
3.6メインフロー
上記のすべてのモジュールを導入して、メインモジュールを作成します。

from util.operation_excel import OperationExcel
from base.runmethod import RunMethod
from data.get_data import GetData
from jsonpath_rw import jsonpath,parse
class DependdentData:
	def __init__(self,case_id):
		self.case_id = case_id
		self.opera_excel = OperationExcel()
		self.data = GetData()
	#  case_id    case_id     
	def get_case_line_data(self):
		rows_data = self.opera_excel.get_rows_data(self.case_id)
		return rows_data
	#      ,    
	def run_dependent(self):
		run_method = RunMethod()
		row_num = self.opera_excel.get_row_num(self.case_id)
		request_data = self.data.get_data_for_json(row_num)
		#header = self.data.is_header(row_num)
		method = self.data.get_request_method(row_num)
		url = self.data.get_request_url(row_num)
		res = run_method.run_main(method,url,request_data)
		return json.loads(res)#            json        
	#     key         case   ,    
	def get_data_for_key(self,row):
		depend_data = self.data.get_depend_key(row)
		response_data = self.run_dependent()
		json_exe = parse(depend_data)
		madle = json_exe.find(response_data)
		return [math.value for math in madle][0]
これによりテスト実行を完了し、結果を統計し、データ依存問題を解決しました。
ここでPythtonのhttpインターフェース自動化テストを実現するためのコード例についての記事を紹介します。Pythttpインターフェースの自動化テストの内容については、以前の文章を検索したり、下記の関連記事を引き続き閲覧したりしてください。これからもよろしくお願いします。