How to use client side JavaScript APIs for debugging Mashups and Widgets
Thingworx Mashup을 개발하다보면, 중간중간 바인딩 한 기능 묶음들을 테스트 할 일이 생긴다. 단위 테스트 한다고 생각하면 된다.
근데 이런 한 묶음의 기능들을 trigger 하기 위해서는 세션값이 변경되는 이벤트가 발생하거나 버튼 등의 위젯과 상호작용하는 작업들이 필요하다.
단순히 버튼을 누르면 실행되는 기능들이야 테스트 하기 편하겠지만, Session Change 이벤트 등을 발생시켜야 테스트 할 수 있다면?
현재 화면에서 세팅되어있는 Session 속성을 조회하고 싶다면?
테스트 단위가 너무 커서 중간의 특정 서비스 부터 실행시켜보고 싶다면?
테스트 하고 싶은 값을 리턴하는 테스트 서비스나 function을 만들어서~ Mashup에 추가해 주고~ 버튼 클릭 이벤트를 서비스에 바인딩해서~ 서비스 리턴 값을 세션에 바인딩 해주고~ Mashup 실행시켜서 버튼 클릭해서 테스트 하고 테스트가 완료되면 다시 테스트용 서비스와 테스트용 버튼을 삭제하는가?
Makshup에 Label을 추가해서~ Session 속성을 Label에 바인딩하고~ Mashup 실행시켜서 화면에서 확인하고 확인이 끝나면 다시 Label을 삭제하는가?
물론 Mashup에 테스트용 위젯을 임시로 추가해서 위에서 본 시나리오대로 얼마든지 테스트 할 수 있다. 나도 예전엔 위의 시나리오대로 많이 테스트 했고 지금도 필요에 따라 이 방식을 사용하고는 한다.
다만, 시간이 많이 걸리고 테스트용으로 추가한 위젯과 Label 삭제 또는 보이지 않게 하는 작업을 잊어서 종종 시스템에 디버깅용 UI가 살아있으면 아차 싶은 경우가 발생하기도 하기 때문에 작업시간 단축과 편의를 위해 API를 사용한 테스팅에 관심을 가지게 되었다.
본 글에서는 가장 사용 빈도가 높은 TW.Runtime.Session 객체의 사용과 특정 서비스를 trigger 할 수 있는 방법을 소개하고자 한다.
TW.Runtime.Session
개발되는 시스템에 따라 Session 값을 적극적으로 활용하기도, 또는 아얘 사용하지 않는 곳도 있긴 하지만 jsp 페이지를 별도로 개발해서 Mashup에 iframe으로 끼워넣어 상호작용 하는 등의 커스텀이 빵빵하게 된 시스템의 경우는 불가피하게 Session을 사용할 수 밖에 없다.
iframe으로 끼워넣어진 jsp 페이지 입장에서는 window.top을 통해 TW Mashup에 바로 접근할 수 있는데 이 때 TW Mashup과 jsp간에 가장 손쉽게 간단한 값을 주고받을 수 있는 방법은 Session을 사용하는 것이기 때문이다.
물론 TW Session을 너무 남발해 만들어진 시스템은 문제가 있을 수 있으니 적당한 수준을 맞추는게 좋다.
(Thingworx 8.3환경에서 개발 중에 Session 속성이 의도한 대로 초기화 되지 않는 버그성 문제들을 겪어 골치가 아팠던 경험이 있다..)
TW.Runtime.Session 객체는 브라우저 개발자 도구의 콘솔에서 아래 명령어를 입력해 살펴볼 수 있다.
TW.Runtime.Session
GlobalSessionProperties 설정
Thingworx에서는 기본적으로 Session 객체에 대한 설정을 할 수 있는 GlobalSessionProperties Entity(Thing Shape)가 있다.
사용자 지정 세션 속성을 만들고 싶다면 해당 Entity를 검색해서 Property를 Add 해주면 된다.
먼저 Composer에서 검색창에 GlobalSessionProperties를 검색한다.

해당 Thing Shape의 Properties and Alert 탭으로 들어간다.

+Add 버튼을 눌러 추가할 Session Property를 생성한다.

Thing Shape를 저장하면 이제 Mashup 에디터의 Session 탭에서 추가한 세션 속성을 확인할 수 있고, 이벤트와 값을 바인딩 할 수 있다.

SetSessionValue(name, value)
Session에 추가한 a_test_globalSession 속성에 ’testValue’라는 문자열 값을 저장하는 예제이다.
// TW.Runtime.Session.SetSessionValue(name, value);
TW.Runtime.Session.SetSessionValue('a_test_globalSession', 'testValue');참고로, 위의 코드로 값이 변경되는 경우에는 SessionChangeEvent까지 정상적으로 수행된다.
단, 이벤트 발생 조건은 이전에 설정되어있던 값과 새로 설정된 값이 다른 경우에만 해당되기 때문에 값 변경 없이 SessionChangeEvent만 발생시키려면 다른값으로 변경하여 실행시켜보거나, 다른 방법을 사용해야한다. 이 다른 방법에 대한건 뒤에서 다시 이야기 하겠다.
GetSessionValue(name)
Session에 추가한 a_test_globalSession 속성 값을 가져오는 예제이다.
// TW.Runtime.Session.GetSessionValue(name);
TW.Runtime.Session.GetSessionValue('a_test_globalSession');위의 SetSessionValue 예제 수행 후 GetSessionValue 예제를 수행하면, testValue가 세팅되어있는 것을 확인할 수 있다.

SessionChange 이벤트만 triggering 하기
위에서 언급 했듯이, SessionChangeEvent는 Session 속성값이 이전에 설정되어있던 값과 새로 설정된 값이 다른 경우에만 발생한다. SetSessionValue를 통해 SessionChangeEvent를 발생시키려면 매번 다른 값을 Set 해주어야해서 조금 귀찮다.
그래서 찾게된 방법은 아래와 같다.
// TW.publishSessionChange(name);
TW.publishSessionChange('a_test_globalSession');이벤트 발생만 필요한 경우 위의 코드로 매번 다른 값을 Set 해줄 필요 없이 SessionChangeEvent를 trigger 할 수 있다.
Service & Event trigger
서비스 이벤트는 Mashup 자체에 할당되어있으며, Mashup이 로딩되면 해당 Mashup의 Data영역에 할당된 서비스들이 같이 올라오는 형태로 되어있다.
Console에서 Event 조회하는 방법
브라우저 개발자 도구의 콘솔에서 화면에 로드되어있는 Mashup 객체를 확인할 수 있다.
(콘솔에서의 조회는 단지 Event 정보만 확인하기 위한 것이고, 서비스를 triggering 하려면 후술할 Mashup Element를 찾아야 가능하다.)
TW.Runtime.Workspace.Mashups;Mashup 객체는 Session에 비해 꽤나 많은 정보들이 나오는데 그 중에서도 이벤트를 trigger 시키기 위한 정보를 테스트 Mashup에서 조회해 보겠다.
TW.Runtime.Workspace.Mashups.Current.Events;테스트를 위해 만든 이 Mashup에서는 Mashup Load 이벤트와 서비스 호출 완료 시점에서 trigger되는 ServiceInvokeCompleted 이벤트가 설정되어있는데, 위의 코드를 실행시킨 조회 결과로도 확인이 가능하다.

해당 Mashup에 바인딩된 이벤트가 총 4개가 조회되는데,
EventTriggerEvent를 살펴보면 Loaded 이벤트 1개, ServiceInvokeCompleted 이벤트 3개를 확인할 수 있다.
EventTriggerArea를 살펴보면
Loaded 이벤트는 Mashup에서 제공되는 이벤트 이기 때문에 Mashup이고, ServiceInvokeCompleted 이벤트는 서비스에서 제공되는 이벤트 이기 때문에 Data로 표시된다. (Mashup에서 Entity들과 Service를 추가할 때 Data 탭에 추가되기 때문에 Data로 구분됨)
Event Listener 조회
콘솔에서 조회하는 방법 이외에도 브라우저 개발자 도구에서 Mashup Element를 선택하여 이벤트 리스너 탭을 통해 이벤트를 조회할 수도 있다.
Mashup 이름이나 id가 다른 경우, Mashup 이 단일 Mashup 이 아니라 Master가 붙어있거나 MashupContainer를 통해 삽입되어 레이아웃이 복잡한 경우에는 테스트 하고자 하는 Mashup Element를 찾는것이 어려울 수 있다. 버전별로 MashupContainer에 들어가는 Mashup Element의 ID 명명 규칙이 다를 수도 있어서 Mashup Element 선택을 위한 ID 규칙같은걸 찾기는 힘든 것 같다.
다만 한번 ID를 찾아두면 그 페이지는 계속 쉽게 테스트 할 수 있으니 개발자 도구에서 잘 선택해서 이벤트 리스너 탭에 원하는 이벤트가 있는 Elemenet를 잘 찾아보자.

본 글의 예제에서는 Mashup Element의 id가 “actual-mashup”으로 되어있다.
“actual-mashup” Elemenet를 선택하면 위의 이미지와 같이 이벤트 리스너(이벤트 수신기) 탭에서 각 서비스와 각 서비스에 붙어있는 ServiceInvokeCompleted 이벤트를 확인할 수 있다.
서비스만 단독으로 실행 시킬 수도, 서비스에 연결되어있는 이벤트만 실행시킬 수도 있다.
Service triggering
다음 명령어로 A 서비스를 실행 시킬 수 있다.
$('div#actual-mashup').triggerHandler('Data_Things_slee_test_test_A');Event triggering
다음 명령어로는 A 서비스가 완료되면 trigger되는 구체적인 ServiceInvokeCompleted 이벤트를 triggering 할 수 있다.
$('div#actual-mashup').triggerHandler('Things_slee_test_test_A_ServiceInvokeCompleted');소개한 API 이외에도 TW.Runtime, TW.location, TW.log, ThingworxInvoker 등 다양한 API가 제공되니 API 문서를 확인해보는것도 좋을 것이다.
불필요한 노가다성 테스트 작업이 줄어드는 것만으로 개발 시간이 단축되고 피로도가 줄어드는 경험을 할 수 있을 것이다.😉