안녕하세요 깍돌이 입니다.
해당 포스팅은 사실 QA가 릴리즈 또는 배포 모니터링시에 사용하게되는 툴 중에 자동화 스크립트가 있을수 있습니다.
하지만 해당 포스팅 시리즈는 테스트 플랫폼 ( Test Platform ) 에 관련된 이야기기 때문에
이번에 작성되는 내용은 worker 에 대한 내용을 적으려고합니다. 저는 QA하면서 필요한 기술적인 부분들은
전부 Node.js 하나로 처리하고 있습니다. 이부분에 대해서 간략하게 적고 넘어가자면
Node.js 를 계속 써오고있어서 이기도 하지만 노드가 무조건 짱이다 이런 느낌도 아닙니다.
저연차 QA시절 (지금도 고연차는 아니지만) 에는 메인이 C++이였기 때문입니다. ( UI 자동화를 IE , Chrome C++ Object 로 하던 시절.. 크흠 )
Node.js 하나로 필요한 부분들을 다 커버할수 있기도 하고 에 Node 위주로 사용하고 있으며 효율적으로 사용해야 하기 때문입니다. ( 하지만 자바로 시작했어도 파이썬이나 노드로 넘어 왔을거 같긴합니다. )
그리고 궁극적인 목적은 높은 품질의 제품을 제공하기 위함입니다. 높은 품질의 S/W를 제공하기 위해서 자동화 테스트 를 넘어서 테스트 플랫폼이 필요하다면 만들면 됩니다. ( 자동화의 제일 중요한점은 이게 메인이 되선 안되고 QA활동에서 사용되는 Tool 로 써 작용되어야 하며 명확한 이유를 가지고 있어야 합니다. - 이건 대외비라 포스팅하지않습니다. )
JS Worker
JS Function 으로 작성된 함수에 대한 Worker 입니다.
해당 Worker.js의 경우 5초 25초 50초를 대기 후 정상 종료 합니다.
* 여기서부터 말하는 Worker는 실무에서는 작성될 독립된 자동화 테스트 코드 입니다.
=> 제가 사용할 자동화 테스트 코드는 폴링하는 경우가 많기 때문에 시나리오 사이사이에 폴링을 유사하게 기대하는 loop 함수를 사용합니다.
실행시
순차적으로 실행이 되었습니다. 좀 더 자세히 보기 위해서 로그를 추가 하였습니다.
일반적으로 JS 함수를 통해서 Worker 를 진행시
다같이 잘 돌아가는거 같지만 모든 함수들이 순차적으로 실행되고 있습니다.
모두 실행전에 결과를 주지않는 함수를 하나 만들어 놓겠습니다.
시나리오는 아래와 같습니다.
하나의 시나리오는 5초 15초 25초의 각각 의 폴링을 가지고 정상 종료 합니다.
2개의 시나리오를 실행시키며 1번째 시나리오에서는 5초 후 return 을 주지 않게됩니다.
이렇게만 보면 정상적으로 잘 동작하는 것 처럼 보입니다.
하지만 1에 suspend에서 어떠한 작업도 하지 않았기 때문입니다. 만약에 1에서 suspend 가 true일경우 에러가 발생했다면?
앞에 Worker 에서 발생한 서스펜드 에러로 인해서 뒤에서 실행되어야 모든 워커들이 실행되지 않는 현상이 발생합니다.
=> 해당 이유는 Node.js의 Event Loop 가 Single Thread 이기 때문인것 과 동시에 현재 실행되는 코드는 같은 Phase 에서 실행이 되고 있기 때문입니다. ( 이부분은 점차 수정하면서 설명 하도록 하겠습니다. )
이 뜻은 결국 각각의 Worker 들이 독립적으로 실행되지 않았다는 반증이 되기도 합니다.
Node.js의 기본적인 Event Loop 를 같이 사용하다보니 위와같은 이슈가 발생합니다.
테스트 플랫폼을 이용하는 QA가 자기자신의 코드가 아닌 다른곳에서의 에러도 신경 써야 한다?
=> 말이 안되는 이야기 입니다.
위의 경우로 인해서 일반적인 JS Function을 사용하는건 말이 안되는 상태입니다.
Event Loop (Timer Phase)
Node.js의 Event Loop 에는 Timer Phase가 있습니다.
* 출처(Node.js 공식 홈페이지) : https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/
필자의 자동화 시스템에서 Trigger 가 되는 주체는 Express.js로 구현된 서버가 되며 해당 Http 기반의 서버들은 기본적으로 Callback 이 등록되어있기 때문에 지속적으로 Event Loop 가 생성 하고 사라지지 않는 형태가 됩니다 .
그렇기 때문에 서버의 테스트 요청이 왔을 경우 ( 자동화 테스트 코드의 실행 요청 ) 해당 코드를 타이머로 묶어서 타이머 페이즈에 넣어 놓는 방법을 생각해 보았습니다.
그 결과 코드는 아래와같이 변경 됩니다. ( Express는 제외하고 샘플 코드를 작성하였습니다. - 실행할 자동화 테스트 코드를 타이머 페이즈로 밀어 넣습니다.)
위의 JS Worker 에서 오류가 났던 코드 그대로 사용시
뭔가 독립적으로 실행되는것처럼 보이게됩니다.
이상태에서 위의 JS Worker 를다시 보면 이거 try catch 를 잘써서 그런거 아닌가? 라는 의문이 다시 들수 있습니다.
setTimeout을 제거하고 Timer phase 로 들어가지않게 코드를 수정하게 되면
2개의 워커가 일단 실행은 되고 비동기 처럼? 돌아가는 것처럼 보이지만 같은 Stack 에서 돌아가고 있기 때문에
결국은 위와같은 현상이 발생하게 됩니다.
이렇게만 보이면 독립적으로 작성된 자동화 테스트 코드를 Timer Phase 에 넣어서 돌아 가고 있는 것 같고 실제로 10개의 worker 를 작성하였을 경우 아래와 같이 (시뮬레이션이지만) 뭔가 잘 돌아가는거 같습니다.
하지만 여기에서는 문제가 하나있습니다. 이건 다음 포스팅에 작성 하도록 하겠습니다.
다음 포스팅 - 현재의 Timer Phase 에 Worker를 등록해서 사용할 경우 문제점
마지막 포스팅 - 해당 문제를 해결하기 위한 Node.js Piscina