티스토리 뷰
프로젝트의 테스트, 문서화 및 코딩은 연달아 발생해야 한다.
- 단위 테스트: 격리된 환경에서 클래스나 함수가 예상대로 동작하는지 확인
- 기능 테스트: 마이크로서비스가 고객의 관점에서 기대한 대로 동작하는지 살피고, 잘못된 요청에 대해서도 정확히 응답하는지 검증
- 통합 테스트: 마이크로서비스가 다른 서비스와 제대로 연동되는지 확인
- 부하 테스트: 마이크로서비스의 성능을 측정
- 엔드 투 엔드 테스트: 전체 시스템이 제대로 동작하는지 확인
단위 테스트
모방하기(mocking)를 통해 격리된 환경에서 해당 호출을 흉내 낼 수 있다.
다음의 3가지 경우로 제한하는 것이 좋다
- I/O 연산: 코드가 서드파티 서비스를 호출하거나 소켓, 파일 등의 리소스를 사용하고 있는데, 테스트에서는 이 작업을 수행할 수 없을 때
- CPU를 많이 사용하는 연산: 테스트를 너무 느리게 만드는 계산이 있을 때
- 특정 상황 재현: 네트워크 에러나 날짜/시간 변경처럼 특정 상황에서 코드를 시험하기 위한 테스트를 작성할 때
import requests
import bugzilla
class MyBugzilla:
def __init__(self, account, server='https://bugizlla.mozilla.org'):
self.account = account
self.server = server
self.session = requests.Session()
def bug_link(self, bug_id):
return '$s/show_bug.cgi?id=%s' % (self.server, bug_id)
def get_new_bugs(self):
call = self.server + '/rest/bug'
params = {'assigned_to': self.account, 'status': 'NEW', 'limit': 10}
try:
res = self.session.get(call, params=parasm).json()
except requests.exceptions.ConnectionError:
res = {'bugs': []}
def _add_link(bug):
bug['link'] = self.bug_link(bug['id'])
return bug
for bug in res['bugs']:
yield _add_link(bug)
import requests
import bugzilla
import unittest
from unittest import mock
import requests
from requests.exceptions import ConnectionError
import requests_mock
class MyBugzilla:
def __init__(self, account, server='https://bugizlla.mozilla.org'):
self.account = account
self.server = server
self.session = requests.Session()
def bug_link(self, bug_id):
return '$s/show_bug.cgi?id=%s' % (self.server, bug_id)
def get_new_bugs(self):
call = self.server + '/rest/bug'
params = {'assigned_to': self.account, 'status': 'NEW', 'limit': 10}
try:
res = self.session.get(call, params=parasm).json()
except requests.exceptions.ConnectionError:
res = {'bugs': []}
def _add_link(bug):
bug['link'] = self.bug_link(bug['id'])
return bug
for bug in res['bugs']:
yield _add_link(bug)
class TestBugzilla(unittest.TestCase):
def test_bug_id(self):
zilla = MyBugzilla('tarek@mozilla.com', server = 'http://yeah')
link = zilla.bug_link(23)
self.assertEqual(link, 'http://yeah/show_bug.cgi?id=23')
@requests_mock.mock()
def test_get_new_bugs(self, mocker):
# 요청을 모방해서 2개의 버그 목록을 반환
bugs = [{'id': 1184528}, {'id': 1184524}]
mocker.get(requests_mock.ANY, json={'bugs', bugs})
zilla = MyBugzilla('tarek@mozilla.com', server = 'http://yeah')
bugs = list(zilla.get_new_bugs())
self.assertEqual(bugs[0]['link'], 'http://yeah/show_bug.cgi?id=1184528')
@mock.patch.object(requests, 'get', side_effect=ConnectionError('No network'))
def test_network_error(self, mocked):
# 서버 다운 등의 네트워크 에러 테스트
zilla = MyBugzilla('tarek@mozilla.com', server='http://yeah')
bugs = list(zilla.get_new_bugs())
self.assertEqual(len(bugs), 0)
if __name__ == '__main__':
unittest.main()
test_network_error() 함수는 파이썬의 mock.patch 데코레이터를 사용해 네트워크 에러를 흉내 내는 두 번째 테스트다.
기능 테스트
마이크로서비스에서 기능 테스트란 게시된 API에 HTTP 요청을 보내서 응답을 검증하는 모든 테스트를 말한다.
다음 2개의 테스트를 중요하게 다뤄야 한다.
- 애플리케이션 기능이 의도대로 동작하는지 중요하게 다뤄야 한다.
- 잘못된 동작을 수정한 후 더 이상 해당 동작이 발생하지 않는지 확인하는 테스트
테스트가 제대로 되려면 애플리케이션 내부에서 발생하는 모든 네트워크 호출 부분을 모방해야 한다.
import unittest
import json
import sys
from flask_basic import app as _app
class TestApp(unittest.TestCase):
def test_help(self):
# app과 연동하기 위해 FlaskClient 인스턴스를 생성
app = _app.test_client()
# /api 엔드포인트를 호출
hello = app.get('/api')
# 응답을 검사
body = json.loads(str(hello.data, 'utf8'))
self.assertEqual(body['Hello'], 'World')
if __name__ == '__main__':
unittest.main()
http://biblio.gdinwiddie.com/biblio/StudiesOfTestDrivenDevelopment
http://docs.python-requests.org/
http://webtest.pythonpaste.org/en/latest/
https://github.com/tarekziade/boom
https://github.com/muatik/flask-profiler
https://github.com/statsd/statsd
https://graphite.readthedocs.io/en/latest/
http://plugincompat.herokuapp.com/
https://github.com/pytest-dev/pytest-cov
https://github.com/tholo/pytest-flake8
http://www.sphinx-doc.org/en/master/
https://recommonmark.readthedocs.io/en/stable/
https://tox-travis.readthedocs.io/en/stable/
https://docs.readthedocs.io/en/stable/
'Microservices' 카테고리의 다른 글
Microservice (0) | 2019.07.22 |
---|