SlideShare a Scribd company logo
니름: 쉬운SOA 단위테스트
파이콘한국 2017
강효준kanghyojun.org
https://github.com/spoqa/nirum
니름에대하여소개합니다
니름의장점
니름사용방법
서비스지향설계(SOA)에서단위테스트
간단하게 단위테스트소개
다른서비스에의존하는단위테스트구현법
니름을사용해여러서비스에걸친단위테스트를쉽게 작성하는법
니름(Nirum)
오픈소스프로젝트https://github.com/spoqa/nirum
이영도소설"눈물을마시는새"에서이름을따옴
인터페이스정의언어(IDL) 컴파일러
마이크로서비스를위한원격 프로시져호출(RPC) 프레임워크
니름IDL이필요한이유
Python에 class 가 없다면?
def store_location(lat: float, lng: float) -> Mapping:
row = db.execute('''
SELECT name, lat, lng FROM store
WHERE earth_distance(
ll_to_earth(lat, lng),
ll_to_earth(:lat, :lng)
) <= 1.0
''', lat=lat, lng=lng)
return {
'name': row['name'],
'lng': float(row['lng']),
'lat': float(row['lat']),
}
위도/경도와매장의정보를하나로묶을수없음
 class 가 없을때속성추가하기
def store_location(lat: float, lng: float) -> Mapping:
...
return {..., 'closed': bool(row['closed'])}
def store_name(name: str) -> Mapping:
...
return {..., 'closed': bool(row['closed'])}
추상화수준이낮은상태
함수의인자가 반복되므로, 여러번고쳐써야하고 실수할확률이큼
 class 로구현하기
class Coord:
def __init__(self, lat: float, lng: float):
self.lat = lat
self.lng = lng
class Store:
def __init__(self, name: str, coord: Coord):
self.name = name
self.coord = coord
def store_location(coord: Coord) -> Store:
...
return Store(...)
def store_name(name: str) -> Store:
...
return Store(...)
 class 로객체의속성을묶어줌
새로운속성추가하기
class Store:
def __init__(self, name: str, coord: Coord, closed: bool):
self.name = name
self.closed = closed
self.coord = coord
def store_location(coord: Coord) -> Store:
...
return Store(...)
def store_name(name: str) -> Store:
...
return Store(...)
매장의폐업여부속성이추가되더라도클래스만고침
안고치면 TypeError 가 알려줌
함수를다른서비스로분리하기
payload = request.get_json()
if 'coord' not in payload:
raise ValueError()
if not isinstance(payload['coord'], dict):
raise ValueError()
...
응답에요청한값이존재하는지확인해야함
값이내가 원하는형식의값인지확인해야함
문자열, 정수, 시각(RFC 3339)
역직렬화(Deserialize)
if 'lat' not in payload['coord']:
raise ValueError()
if not isinstance(payload['coord']['lat'], float):
raise ValueError()
if 'lng' not in payload['coord']:
raise ValueError()
if not isinstance(payload['coord']['lng'], float):
raise ValueError()
store_location(
Coord(lat=payload['coord']['lat'],
lng=payload['corordinate']['lng'])
)
역직렬화는지루하다
형식에맞는지검사하는코드가 반복되고 많아짐
다른서비스에요청하게 바뀌면서데이터를구조를알기 어려워짐
결국  class 없이프로그래밍하는것과 같음
니름사용하기
record coord (
# Coordinator
float32 lat,
# latitude
float32 lng,
# longitude
);
필요한개념의모양(인터페이스)을정의
이파일을원하는언어로컴파일할수있음
Python으로바뀐니름
class Coord(object):
__slots__ = ('lat', 'lng')
__nirum_record_behind_name__ = 'coord'
__nirum_field_names__ = name_dict_type([
('lat', 'lat'),
('lng', 'lng')
])
def __init__(self, lat: float, lng: float):
...
def __nirum_serialize__(self) -> Mapping[str, Any]:
...
@classmethod
def __nirum_deserialize__(cls, value) -> 'Coord':
...
니름사용하여직렬화(Serialize)/역직렬화하기
coord = deserialize_meta(Coord, request_json)
store_location(coord)
print(serialize_meta(coord))
# {"_type": "coord", "lat": 37.5137, "lng": 127.0582}
니름에정의한 coord 의형식에맞추어서JSON으로부터 Coord 의인스턴스를생성
니름이생성한 Coord 클래스와인스턴스가 역직렬화/직렬화를쉽게 해줌
니름, 원격 프로시져호출(RPC) 프레임워크
여러서비스끼리통신하기
서비스지향설계(SOA)에서는기능단위로여러서비스나눔
나누어진서비스의기능을잘엮어서필요한서비스를만듦
여러서비스끼리통신하기 (2)
통신할방법은다양하지만, 스포카에서는HTTP로통신함
요청서비스는인스턴스를JSON으로직렬화하고  requests 사용해서요청
응답서비스는JSON을역직렬화하여인스턴스로만들고 원하는작업을수행함
백엔드서비스
@app.route('/', methods=['GET'])
def store_location():
if 'lat' not in request.args:
raise BadRequest('`lat` is required.')
if 'lng' not in requst.args:
raise BadRequest('`lng` is required.')
try:
lat = float(request.args['lat'])
except ValueError:
raise BadRequest('`lat` expected to be `float`.')
...
역직렬화코드와알맞은형식이아닐때에러메시지를적어주는코드가 대부분임
백엔드서비스(2)
...
rows = db.execute(
'''
SELECT name, lat, lng FROM store
WHERE earth_distance(
ll_to_earth(lat, lng),
ll_to_earth(:lat, :lng)
) <= 1.0
''',
lat=lat, lng=lng
)
return jsonify([
{'name': r[0], 'lat': r[1], 'lng': r[2]}
for r in rows
])
결과값을원하는형식으로맞추는작업이필요
프론트엔드서비스
@app.route('/<float:lat>,<float:lng>/', methods=['GET'])
def store_location(lat: float, lng: float):
payload = {'lat': lat, 'lng': lng}
response = get('http://store-service.com/',
params=payload)
if not response.ok:
raise InternalServerError()
payload = response.json()
...
백엔드서비스가 정의한형식에맞춰서직렬화해야함
백엔드서비스에서응답이잘왔는지확인함
프론트엔드서비스(2)
if 'name' not in payload:
...
if 'closed' not in payload:
...
return render_template(
'stores.html',
name=payload['name'],
closed=payload['closed']
)
원하는형태로사용하기 위해형식검사
Back to the Slide 11
if 'lat' not in payload['coord']:
raise ValueError()
if not isinstance(payload['coord']['lat'], float):
raise ValueError()
...
역직렬화는지루하다
결국  class 없이프로그래밍하는것과 같음
Back to the Slide 11 (2)
서비스지향설계(SOA)에서는여러개의내부서비스가 통신하기 때문에, 다른외부서비스와통신하는
것과 다름없음
인터페이스정의언어(IDL)을사용하지않으면프로그램의절반은형식을검사하는코드
결국  class 없이프로그래밍하는것과 같음
서비스지향설계(SOA)에서는이렇게 코드를구현할수밖에없을까?
니름RPC 사용하기
record store (
text name,
);
service store-service (
store location (coord coord),
);
서비스에필요한메서드의모양을정의함
컴파일하면서비스구현과 요청에필요한인터페이스가 만들어짐.
 service 컴파일결과
class StoreService(service_type):
def location(coord: Coord) -> Store:
raise NotImplementedError()
class StoreService_Client(client_type, StoreService):
...
컴파일된결과는상속받아서WSGI 애플리케이션으로만들수있음
만들어진WSGI 애플리케이션에 StoreService_Client 를사용해서바로요청할수있음.
 service 구현
from store_schema import StoreService
class StoreServiceImpl(StoreService):
def location(coord: Coord) -> Store:
row = db.execute(
'''
SELECT name, lat, lng FROM store
WHERE earth_distance(
ll_to_earth(lat, lng),
ll_to_earth(:lat, :lng)
) <= 1.0
''',
lat=coord.lat, lng=coord.lng
)
return Store(name=row[0],
coord=Coord(lat=row[1], lng=row[2]))
if __name__ == '__main__':
app = WsgiApp(StoreServiceImpl())
...
 client 사용
s = StoreService_Client(
HttpTransport(url)
)
@app.route('/<float:lat>,<float:lng>/', methods=['GET'])
def store_location(lat: float, lng: float):
store = s.location(coord=Coord(lat=lat, lng=lng))
return render_template(
'stores.html', store=store
)
니름RPC가 좋은점
서비스가 받는인자의형식과 반환하는값의형식의모양을모두정의해서직렬화/역직렬화로직이없음
서비스응답의상태체크도니름이자동으로만든클라이언트가 대신해줌
귀찮을일들을프로그래머대신해줌
단위테스트에니름적용하기
단위테스트란?
특정단위의코드가 의도한대로동작하는지확인하는테스트기법
Python에선pytest 같은서드파티(third‑party) 라이브러리를사용하거나unittest 같은표준라이브
러리를사용할수있음
간단한단위테스트예제
def sigma(until: int) -> int:
s = 0
count_ = 1
while count_ <= until:
s += count_
count_ += 1
return s
def test_sigma():
assert sigma(10) == 55
의도한동작을보장함
1부터10까지전부다더하면55가 나와야함
단위테스트가 작성되었으므로 sigma 는조금 더쉽게 고칠(혹은리팩토링) 수있음
과감하게 끊임없이고치기
def sigma(n):
return sum(range(1, n))
def test_sigma():
assert sigma(10) == 55
코드의의도는테스트가 보장하므로, 프로그래머는조금 더쉽게 코드를고칠수있음
지속적통합에도움이됨
지속적통합을통해서비스개선에도도움을줌
서비스지향설계(SOA)에서단위테스트짜기
단위테스트에서테스트해야하는함수가 다른서비스에의존할수있음
실제서버에단위테스트가 의존한다면, 제대로된단위테스트를할수없음
다른방법이필요
다른방법으로테스트구현하기
CI(Continuous Integration) 서버에서필요한다른서비스를직접실행하기
서비스를가짜로따라해서(mocking) 테스트하기
다른서비스실행해서테스트하기
def sigma(n):
r = get(URL, {‘number’: n})
resp = json.loads(r)
return resp[‘result’]
def test_sigma():
assert sigma(10) == 55
CI 서버(CircleCI, TravisCI 등)에다른서비스를직접띄우기가 힘들수있음
테스트도중다른서비스가 테스트외의조건 때문에오류를일으킬수있음
일관적인테스트결과를얻기가 힘듬
가짜로따라하기
def sigma(n, session):
…
return resp[‘result’]
def test_sigma():
session = Session()
adapter = requests_mock.Adapter()
session.mount(‘mock’, adapter)
adapter.register_uri(‘GET’, URL, text=55)
assert sigma(10) == 55
requests는requests‑mock을사용해서requests로만들어지는모든요청을가로채서흉내낼수있
음
httpretty, httmock 등다양한라이브러리가 있음
단위테스트에서의도한응답을내려줄수있도록코드를짜야함
가짜코드이기 때문에완전히같지않다
GET /sigma/?number=1 HTTP/1.1
Host: example.com
Accept: application/json
HTTP/1.1 400 Bad Request
Content-Type: application/json
"`n` is required."
다른서비스에서형태를바꾸더라도알아차릴수없음
다른서비스의형태를바꿀때마다가짜로짠코드도바꿔줘야함
가짜코드를구현하기
def mock(requst, context):
j = request.json()
if 'lat' not in j:
assert False
...
return {'name': 'hello'}
def test_store_location():
...
adapter.register_uri(‘GET’, URL, mock)
assert store_location(0.1, 0.1)
...
가짜코드가 다른서비스처럼동작하도록코드를채워넣어야함
형식검사코드가 절반이상
니름을단위테스트에사용해보기
필요한것은단위테스트안에서다른서비스가 원하는형식으로잘전달하고 있는지여부
니름을사용해서서비스의모양과 통신로직을쉽게 만들수있음
 sigma-service 구현하기
service sigma-service (
int64 sigma(int64 number),
);
class SigmaService(service_type):
...
class SigmaService_Client(client_type):
...
니름파일을컴파일한패키지를보면다른서비스의모양을알수있음
이모양을바로단위테스트에적용할수있음
 sigma-service 테스트에적용하기
class SigmaServiceTest(SigmaService):
def sigma(n: int) -> int:
return 55
def get_client(test: bool) -> SigmaService:
if test:
c = SigmaServiceTest()
else:
c = SigmaService_Client(HttpTransport(URL))
return c
def test_sigma():
client = get_client(test=True)
assert client.sigma(10)
서비스의모양을바로적용할수있음
테스트의설정을보고 가짜테스트구현체를사용하든지, 서비스에요청하든지할수있음
모양바뀐것 알아채기
service sigma-service (
int64 sigma ( int64 from
, int64 to
),
);
def test_sigma():
client = get_client(test=True)
# TypeError 일어남.
assert client.sigma(10)
모양이바뀌면, 컴파일된패키지의인자도바뀌므로쉽게 API의breaking change를알아차릴수있음
패키지버전은올려줘야함
형식검사가 필요없음
class SigmaServiceTest(SigmaService):
def sigma(n: int) -> int:
return 55
컴파일된니름패키지안에서형식검사는전부한후에서비스의메서드로값이들어옴
IDL/RPC를사용하면서얻는장점을테스트코드에서도얻을수있음
감사합니다
https://github.com/spoqa/nirum
14일, 15일스프린트진행
https://speakerdeck.com/admire93/nireum‑swiun‑soa‑danwi‑teseuteu
Spoqa https://www.spoqa.com/

More Related Content

What's hot

Kth개발자 세미나 1회
Kth개발자 세미나 1회Kth개발자 세미나 1회
Kth개발자 세미나 1회
Byeongsu Kang
 
[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11흥배 최
 
Let's Go (golang)
Let's Go (golang)Let's Go (golang)
Let's Go (golang)
상욱 송
 
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
흥배 최
 
Boost
BoostBoost
Writing Fast Code (KR)
Writing Fast Code (KR)Writing Fast Code (KR)
Writing Fast Code (KR)
Younggun Kim
 
Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택
JinTaek Seo
 
알파희 - PyPy/RPython으로 20배 빨라지는 아희 JIT 인터프리터
알파희 - PyPy/RPython으로 20배 빨라지는 아희 JIT 인터프리터알파희 - PyPy/RPython으로 20배 빨라지는 아희 JIT 인터프리터
알파희 - PyPy/RPython으로 20배 빨라지는 아희 JIT 인터프리터
YunWon Jeong
 
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013Esun Kim
 
파이썬 스터디 15장
파이썬 스터디 15장파이썬 스터디 15장
파이썬 스터디 15장SeongHyun Ahn
 
[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기
Sang Heon Lee
 
Boost 라이브리와 C++11
Boost 라이브리와 C++11Boost 라이브리와 C++11
Boost 라이브리와 C++11OnGameServer
 
병렬 프로그래밍2
병렬 프로그래밍2병렬 프로그래밍2
병렬 프로그래밍2
준혁 이
 
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
Jaeseung Ha
 
WTL 소개
WTL 소개WTL 소개
WTL 소개
Wonseok Song
 
20150306 파이썬기초 IPython을이용한프로그래밍_이태영
20150306 파이썬기초 IPython을이용한프로그래밍_이태영20150306 파이썬기초 IPython을이용한프로그래밍_이태영
20150306 파이썬기초 IPython을이용한프로그래밍_이태영
Tae Young Lee
 
[NDC 2016] 유니티, iOS에서 LINQ 사용하기
[NDC 2016] 유니티, iOS에서 LINQ 사용하기[NDC 2016] 유니티, iOS에서 LINQ 사용하기
[NDC 2016] 유니티, iOS에서 LINQ 사용하기
Daehee Kim
 
20150212 c++11 features used in crow
20150212 c++11 features used in crow20150212 c++11 features used in crow
20150212 c++11 features used in crow
Jaeseung Ha
 
코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011Esun Kim
 
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
Sang Don Kim
 

What's hot (20)

Kth개발자 세미나 1회
Kth개발자 세미나 1회Kth개발자 세미나 1회
Kth개발자 세미나 1회
 
[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11
 
Let's Go (golang)
Let's Go (golang)Let's Go (golang)
Let's Go (golang)
 
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
 
Boost
BoostBoost
Boost
 
Writing Fast Code (KR)
Writing Fast Code (KR)Writing Fast Code (KR)
Writing Fast Code (KR)
 
Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택
 
알파희 - PyPy/RPython으로 20배 빨라지는 아희 JIT 인터프리터
알파희 - PyPy/RPython으로 20배 빨라지는 아희 JIT 인터프리터알파희 - PyPy/RPython으로 20배 빨라지는 아희 JIT 인터프리터
알파희 - PyPy/RPython으로 20배 빨라지는 아희 JIT 인터프리터
 
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
사례를 통해 살펴보는 프로파일링과 최적화 NDC2013
 
파이썬 스터디 15장
파이썬 스터디 15장파이썬 스터디 15장
파이썬 스터디 15장
 
[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기
 
Boost 라이브리와 C++11
Boost 라이브리와 C++11Boost 라이브리와 C++11
Boost 라이브리와 C++11
 
병렬 프로그래밍2
병렬 프로그래밍2병렬 프로그래밍2
병렬 프로그래밍2
 
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
 
WTL 소개
WTL 소개WTL 소개
WTL 소개
 
20150306 파이썬기초 IPython을이용한프로그래밍_이태영
20150306 파이썬기초 IPython을이용한프로그래밍_이태영20150306 파이썬기초 IPython을이용한프로그래밍_이태영
20150306 파이썬기초 IPython을이용한프로그래밍_이태영
 
[NDC 2016] 유니티, iOS에서 LINQ 사용하기
[NDC 2016] 유니티, iOS에서 LINQ 사용하기[NDC 2016] 유니티, iOS에서 LINQ 사용하기
[NDC 2016] 유니티, iOS에서 LINQ 사용하기
 
20150212 c++11 features used in crow
20150212 c++11 features used in crow20150212 c++11 features used in crow
20150212 c++11 features used in crow
 
코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011
 
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
 

Similar to 니름: 쉬운 SOA 단위 테스트

About Visual C++ 10
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10
흥배 최
 
팀장 잔소리
팀장 잔소리팀장 잔소리
팀장 잔소리
Sungchul Park
 
Python과 Tensorflow를 활용한 AI Chatbot 개발 및 실무 적용
Python과 Tensorflow를 활용한  AI Chatbot 개발 및 실무 적용Python과 Tensorflow를 활용한  AI Chatbot 개발 및 실무 적용
Python과 Tensorflow를 활용한 AI Chatbot 개발 및 실무 적용
Susang Kim
 
파이썬 데이터 분석 (18년)
파이썬 데이터 분석 (18년)파이썬 데이터 분석 (18년)
파이썬 데이터 분석 (18년)
SK(주) C&C - 강병호
 
GraphQL in Action - REST와 이별할 때 생각해야 하는 것들
GraphQL in Action - REST와 이별할 때 생각해야 하는 것들GraphQL in Action - REST와 이별할 때 생각해야 하는 것들
GraphQL in Action - REST와 이별할 때 생각해야 하는 것들
Kivol
 
Oop design principle SOLID
Oop design principle SOLIDOop design principle SOLID
Oop design principle SOLID
Ryan Park
 
스마트폰 앱 백-엔드 솔루션 개발을 위한 Node.js 실전 가이드
스마트폰 앱 백-엔드 솔루션 개발을 위한 Node.js 실전 가이드스마트폰 앱 백-엔드 솔루션 개발을 위한 Node.js 실전 가이드
스마트폰 앱 백-엔드 솔루션 개발을 위한 Node.js 실전 가이드Jeongsang Baek
 
Java8 람다
Java8 람다Java8 람다
Java8 람다
Jong Woo Rhee
 
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
Jaeseung Ha
 
Node.js in Flitto
Node.js in FlittoNode.js in Flitto
Node.js in Flitto
SeungWoo Lee
 
[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규ChangKyu Song
 
200819 NAVER TECH CONCERT 04_NDK로 안드로이드에 C++ 끼얹기
200819 NAVER TECH CONCERT 04_NDK로 안드로이드에 C++ 끼얹기200819 NAVER TECH CONCERT 04_NDK로 안드로이드에 C++ 끼얹기
200819 NAVER TECH CONCERT 04_NDK로 안드로이드에 C++ 끼얹기
NAVER Engineering
 
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019min woog kim
 
Advanced nGrinder
Advanced nGrinderAdvanced nGrinder
Advanced nGrinder
JunHo Yoon
 
파이썬으로 익히는 딥러닝
파이썬으로 익히는 딥러닝파이썬으로 익히는 딥러닝
파이썬으로 익히는 딥러닝
SK(주) C&C - 강병호
 
2007년 제8회 JCO 컨퍼런스 POJO 프로그래밍 발표 자료
2007년 제8회 JCO 컨퍼런스 POJO 프로그래밍 발표 자료2007년 제8회 JCO 컨퍼런스 POJO 프로그래밍 발표 자료
2007년 제8회 JCO 컨퍼런스 POJO 프로그래밍 발표 자료
beom kyun choi
 
2016 C++스터디 1주차
2016 C++스터디 1주차2016 C++스터디 1주차
2016 C++스터디 1주차
Seungwee  Choi
 
Io t에서의 소프트웨어단위테스트_접근사례
Io t에서의 소프트웨어단위테스트_접근사례Io t에서의 소프트웨어단위테스트_접근사례
Io t에서의 소프트웨어단위테스트_접근사례
SangIn Choung
 

Similar to 니름: 쉬운 SOA 단위 테스트 (20)

About Visual C++ 10
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10
 
팀장 잔소리
팀장 잔소리팀장 잔소리
팀장 잔소리
 
Python과 Tensorflow를 활용한 AI Chatbot 개발 및 실무 적용
Python과 Tensorflow를 활용한  AI Chatbot 개발 및 실무 적용Python과 Tensorflow를 활용한  AI Chatbot 개발 및 실무 적용
Python과 Tensorflow를 활용한 AI Chatbot 개발 및 실무 적용
 
파이썬 데이터 분석 (18년)
파이썬 데이터 분석 (18년)파이썬 데이터 분석 (18년)
파이썬 데이터 분석 (18년)
 
GraphQL in Action - REST와 이별할 때 생각해야 하는 것들
GraphQL in Action - REST와 이별할 때 생각해야 하는 것들GraphQL in Action - REST와 이별할 때 생각해야 하는 것들
GraphQL in Action - REST와 이별할 때 생각해야 하는 것들
 
Oop design principle SOLID
Oop design principle SOLIDOop design principle SOLID
Oop design principle SOLID
 
스마트폰 앱 백-엔드 솔루션 개발을 위한 Node.js 실전 가이드
스마트폰 앱 백-엔드 솔루션 개발을 위한 Node.js 실전 가이드스마트폰 앱 백-엔드 솔루션 개발을 위한 Node.js 실전 가이드
스마트폰 앱 백-엔드 솔루션 개발을 위한 Node.js 실전 가이드
 
Nlp study1
Nlp study1Nlp study1
Nlp study1
 
Java8 람다
Java8 람다Java8 람다
Java8 람다
 
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
 
Node.js in Flitto
Node.js in FlittoNode.js in Flitto
Node.js in Flitto
 
[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규
 
200819 NAVER TECH CONCERT 04_NDK로 안드로이드에 C++ 끼얹기
200819 NAVER TECH CONCERT 04_NDK로 안드로이드에 C++ 끼얹기200819 NAVER TECH CONCERT 04_NDK로 안드로이드에 C++ 끼얹기
200819 NAVER TECH CONCERT 04_NDK로 안드로이드에 C++ 끼얹기
 
강의자료 2
강의자료 2강의자료 2
강의자료 2
 
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
 
Advanced nGrinder
Advanced nGrinderAdvanced nGrinder
Advanced nGrinder
 
파이썬으로 익히는 딥러닝
파이썬으로 익히는 딥러닝파이썬으로 익히는 딥러닝
파이썬으로 익히는 딥러닝
 
2007년 제8회 JCO 컨퍼런스 POJO 프로그래밍 발표 자료
2007년 제8회 JCO 컨퍼런스 POJO 프로그래밍 발표 자료2007년 제8회 JCO 컨퍼런스 POJO 프로그래밍 발표 자료
2007년 제8회 JCO 컨퍼런스 POJO 프로그래밍 발표 자료
 
2016 C++스터디 1주차
2016 C++스터디 1주차2016 C++스터디 1주차
2016 C++스터디 1주차
 
Io t에서의 소프트웨어단위테스트_접근사례
Io t에서의 소프트웨어단위테스트_접근사례Io t에서의 소프트웨어단위테스트_접근사례
Io t에서의 소프트웨어단위테스트_접근사례
 

니름: 쉬운 SOA 단위 테스트