don't stop believing

API 자동화 테스트 예제 작성과 설명 2 (python) 본문

Testing Automation/Gauge

API 자동화 테스트 예제 작성과 설명 2 (python)

Tongchun 2018. 6. 7. 18:06

이제 뭔가를 새로 작성해 보겠습니다.

기존 example 코드는 그대로 두고 새로 API 테스트 코드와 sepc을 작성해 보겠습니다.


macaron API 서버에 get과 post method를 사용해 데이터를 보내고 받으면서 API들을 테스트 할 겁니다.

API 호출은 python으로 작성됩니다.

먼저 step_impl 폴더에 macaronlib.pycall_api.py 파일을 새로 만들어 주세요. macaronlib.py 파일에는 http.client 모듈을 사용해 데이터를 주고받는 함수들을 만들겁니다. 그리고 call_api.py에는 실제 macaron API 서버에서 정의한데로 API를 호출하는 함수를 만들겠습니다.


macaronlib.py파일에 아래와 같이 작성해 주세요.

참고로 macaronAPI 서버는 docker image로 받을 수 있습니다.

# -*- coding:utf-8 -*- import http.client import urllib.parse as parse import json import sys, time # 서버 rul 정보를 리턴합니다. def serverUrl(): macaronAPIServerURL = "192.168.0.111:10260" return macaronAPIServerURL # http post 호출 method (Beta Open API와 https 통신을 합니다.) def http_post_getData(method, url_path, params, headers): macaronServer = serverUrl() conn = http.client.HTTPConnection(macaronServer) try: params = json.dumps(params) conn.request(method, url_path, params, headers) except OSError as err: print('서버 연결에 실패했습니다.') print(err) sys.exit(9) response = conn.getresponse() status_code = response.status if status_code == 200: data = str(json.loads(response.read().decode("utf-8"))) else: data = response.read().decode("utf-8") conn.close() return (status_code, data) # API의 header 정보를 Dict 형태로 변환합니다. def get_headers(**kwargs): headers = {'Content-type': 'application/json;charset=UTF-8'} for name, value in kwargs.items(): headers.update({name: value}) return headers # get Method를 호출합니다. def getCall(path, accessToken): if accessToken is None: headers = get_headers() else: headers = get_headers(accessToken=accessToken) status_code, data = http_post_getData("GET", path, "", headers) if status_code == 200: # print(data) data = data.replace('"', '\\"') data = data.replace("'", "\"") data = data.replace("False", "false") data = data.replace("True", "true") jsonData = json.loads(data) # extract a result result = jsonData['result'] else: jsonData = data time.sleep(2) return {'code': status_code, 'result': result, 'data': jsonData} # Post Method를 호출합니다. def postCall(path, requestBody, accessToken): if accessToken is None: headers = get_headers() else: headers = get_headers(accessToken=accessToken) status_code, data = http_post_getData("POST", path, requestBody, headers) if status_code == 200: data = data.replace('"', '\\"') data = data.replace("'", "\"") data = data.replace("False", "false") data = data.replace("True", "true") jsonData = json.loads(data) # extract a accessToken tokenPath = ["/v1/auth/login", "/v1/system/login", "/v1/auth/change/accesstoken"] if path in tokenPath: accessToken = jsonData['data']['accesstoken'] else: accessToken = "" # extract a result result = jsonData['result'] else: jsonData = data time.sleep(2) return {'code': status_code, 'result': result, 'data': jsonData, 'token': accessToken}

이제 call_api.py 파일 차례입니다.

call_api.py에서는 macaronlib.py을 모듈로 인식하게 하고 import macaronlib로 불러와야 합니다.

파일에 가장먼저 아래 코드를 적습니다.

import sys
sys.path.insert(0, "/Users/tongchunkim/Documents/Gauge/macaron/step_impl")

위 코드는 해당 경로 하위에 있는 python 파일들을 인식하게 하는 코드입니다.

만약 Windows에서 작업하신다면 step_impl 폴더까지의 전체 경로를 지정해 주시면 됩니다.


위 코드 아래부터 gauge 모듈을 불러오고 사용할 함수를 작성하면 됩니다.

import sys sys.path.insert(0, "/Users/tongchunkim/Documents/Gauge/macaron/step_impl") from getgauge.python import step, before_step, after_scenario from getgauge.python import Messages from getgauge.python import DataStoreFactory import macaronlib as macaron # -------------------------- # Gauge step implementations # -------------------------- def user_login(account, password): path = "/v1/auth/login" requestBody = {"id": "tongchun", "password": "ngle3596"} response = macaron.postCall(path, requestBody, None) accessToken = response['token'] DataStoreFactory.scenario_data_store().put('accessToken', accessToken) Messages.write_message("AccessToken: " + response['token']) assert response['result'] == 0 def valid_accesstoken(account, accessToken): path = "/v1/auth/accesstoken" requestBody = {"id": "tongchun"} accessToken = DataStoreFactory.scenario_data_store().get('accessToken') response = macaron.postCall(path, requestBody, accessToken) Messages.write_message("Stored AccessToken: " + accessToken) assert response['result'] == 0 def all_crew(): path = "/v1/crew" response = macaron.getCall(path, None) Messages.write_message("call all crews") assert response['result'] == 0

user_login() 함수를 계정과 비번으로 macaronAPI 서버에 로그인하는 함수입니다.

valid_accesstoken() 함수는 login 후 전달받은 accesstoken을 검증하는 함수입니다.

all_crew() 함수는 macaronAPI 서버에 등록된 회원정보를 불러오는 함수입니다.


위 3개 함수로 gauge를 학습하겠습니다.

여기까지는 python 작성만 한 상태입니다. 이제 gauge가 python 함수를 인식하고 호출할 수 있게 해줘야 합니다.


이제 spec을 정리하겠습니다.

specs 폴더에 apitest.spec 파일을 생성합니다.

spec 파일을 작성하는 방법은 gauge documentation 페이지에 잘 성명되어 있습니다.

https://docs.gauge.org/latest/writing-specifications.html


apitest.spec에 아래와 같이 작성합니다.

# API Test

This is sample spec for API Test.

## login scenario

* 계정 "account"와 비번 "password"로 로그인 합니다.

* 계정 "account"에 대한 AccessTokenr값 "accessToken"을 검증합니다.

* 모든 사원 정보를 불러옴니다.

spec 파일의 가정 처음에는 # 으로 시작하는 specification header가 하나 존재해야 합니다.

그 아래 ## 으로 시작하는 scenario가 여러개 올 수 있습니다.

실제 함수를 호출하는 step은 * 로 시작합니다.


위 apitest.spec 파일에는 하나의 scenario와 3개의 step이 있습니다.

step을 python함수와 연결해야 합니다. 연결은 python 함수 위에 @step() 이라는 decorator을 추가해 사용합니다.


위 3개의 step을 call_api.py에 있는 함수에 decorator를 사용해 연결합니다.

import sys
sys.path.insert(0, "/Users/tongchunkim/Documents/Gauge/macaron/step_impl")

from getgauge.python import step, before_step, after_scenario
from getgauge.python import Messages
from getgauge.python import DataStoreFactory
import macaronlib as macaron

# --------------------------
# Gauge step implementations
# --------------------------

@step("계정 <account>와 비번 <password>로 로그인 합니다.")
def user_login(account, password):
	path = "/v1/auth/login"
	requestBody = {"id": "tongchun", "password": "ngle3596"}
	response = macaron.postCall(path, requestBody, None)
	accessToken = response['token']
	DataStoreFactory.scenario_data_store().put('accessToken', accessToken)
	Messages.write_message("AccessToken: " + response['token'])
	assert response['result'] == 0

@step("계정 <account>에 대한 AccessTokenr값 <accesstoken>을 검증합니다.")
def valid_accesstoken(account, accessToken):
	path = "/v1/auth/accesstoken"
	requestBody = {"id": "tongchun"}
	accessToken = DataStoreFactory.scenario_data_store().get('accessToken')
	response = macaron.postCall(path, requestBody, accessToken)
	Messages.write_message("Stored AccessToken: " + accessToken)
	assert response['result'] == 0

@step("모든 사원 정보를 불러옴니다.")
def all_crew():
	path = "/v1/crew"
	response = macaron.getCall(path, None)
	Messages.write_message("call all crews")
	assert response['result'] == 0 

위 decorator를 적용한 코드에서 보면 @step() 안에 < >로 받은 변수를 python 함수에 전달할 수 있습니다.


이제 다시 apitest.spec파일에 가서 실제 테스트에 사용할 계정과 비번 등을 넣어줍니다.








Comments