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로 받을 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# -*- 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}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

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

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

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

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

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

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

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에 아래와 같이 작성합니다.

1
2
3
4
5
6
7
8
9
10
11
12
# API Test
This is sample spec for API Test.
## login scenario
* "account" "password" .
* "account" AccessTokenr "accessToken" .
* .
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

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

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

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


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

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

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


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








Comments