최초 프로젝트 셋팅
코드 테스트환경 구축
코드 테스트를 하기위해서 다음과 같은 방법이 있습니다.
- 간단하게 사용자 정의 클래스 생성하여 학습 코드 집합
- VisualStudio에 유닛테스트 프로젝트활용
- 분산환경 메시지 Test를 위해 AKKA Test Toolkit사용
Actor 개념을 익히기까지는 사용자 정의 테스트 클래스를 통해 실습을 하고
이후 Remote 테스트때 기본유닛테스트+Akka Test ToolKit을 이용예정입니다.
AKKA가 분산환경에서의 메시지 처리기술을 다루고 있기때문에, 실제 서비스 코드작성할때
꼼꼼한 유닛 테스트 작성이 요구됩니다.
사용자 정의 테스트 클래스 작성
using Akka.Actor;
namespace ServiceA.STUDY
{
public class ActorTest //Actor 기본 테스트를 위해서~~
{
protected ActorSystem actorSystem;
public ActorTest(ActorSystem system) //메인 APP에서 생성한 AKKA System만 참조하면 됩니다.
{
actorSystem = system;
}
protected void SomeTest1()
{
}
public void RunAll()
{
SomeTest1(); //SubTest
}
}
}
이렇게 하는 이유는 단지, 기존 어플리케이션 코드에서 학습 진행한 코드를 섹션별로 분리목적으로 큰 의도는 없습니다.
위와 같은 템플릿은 ActorTest외에 , RemoteActorTest , ClusterActorTest 등 학습 목적에따라 Class로 분리예정이며
생성패턴이 유사하니 추가로 언급하지 않겠습니다.
using Akka.Actor;
using ServiceA.STUDY;
namespace ServiceA
{
class Program
{
static void Main(string[] args)
{
ConsoleKeyInfo cki;
Console.CancelKeyPress += new ConsoleCancelEventHandler(myHandler);
using (ActorSystem system = ActorSystem.Create("ServiceA"))
{
//Actor의 시스템 준비 완료
//ActorTest -ActorTest코드는 아래 두줄외에 더이상 추가가 안됩니다.
ActorTest actorTest = new ActorTest(system);
actorTest.RunAll();
while (true)
{
// 메인 어플리케이션 종료방지를 위한코드 ( ctrl+x 종료 )
cki = Console.ReadKey(true);
if (cki.Key == ConsoleKey.X) break;
}
}
}
protected static void myHandler(object sender, ConsoleCancelEventArgs args)
{
args.Cancel = true;
}
}
}
Visual Studio에서 제공하는 UnitTest 사용하기
간단한 단위 테스트를 이용할때는, 직접 테스트 클랙스를 작성하여 콘솔환경에서 수행하는것보다
IDE에서 제공하는 유닛 테스트프로젝트를 이용하는것이 더 편리하고 강력합니다.
AKKA의 기본기능을 배우기위해서는, 유닛테스트 템플릿 프로젝트로 충분합니다.
테스트 코드를 서비스 코드와 완전하게 분리할수 있습니다.
서비스코드는 서비스에 필요한 각종 액터,메시지정의가 포함될수 있습니다.
Test프로젝트는 서비스프로젝트를 참조하여, 서비스내에서 정의한 객체들을 참조를통해
테스트 수행 가능합니다.
테스트를 단위혹은 그룹별실행 가능하며, 출력및 유효검사가 편리합니다.
AKKA 유닛테스트 샘플
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Akka.Actor;
using Akka.Event;
using ServiceA.STUDY;
namespace AkkaTest
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
using (ActorSystem actorSystem = ActorSystem.Create("ServiceA"))
{
IActorRef myActor = actorSystem.ActorOf<BasicActor>("myactor");
Props watchProps = WatchActor.Props(myActor);
IActorRef watcher = actorSystem.ActorOf(watchProps, "watcher");
var result = myActor.Ask("나는 살아있다.").Result;
actorSystem.Stop(myActor); //myActor를 임의로 Stop하여, watcher가 종료를감시한는지 체크
myActor.GracefulStop(TimeSpan.FromSeconds(10)).Wait(); //생성한 Actor를 안전하게 종료시킨다.
}
}
}
}
출력:
테스트 이름: TestMethod1 테스트 결과: 성공 Result StandardOutput: [DEBUG][2017-09-12 오전 1:29:23][Thread 0022][EventStream(ServiceA)] Logger log1-DefaultLogger [DefaultLogger] started [DEBUG][2017-09-12 오전 1:29:23][Thread 0022][EventStream(ServiceA)] StandardOutLogger being removed [DEBUG][2017-09-12 오전 1:29:23][Thread 0022][EventStream(ServiceA)] Default Loggers started [INFO][2017-09-12 오전 1:29:23][Thread 0022][remoting] Starting remoting [DEBUG][2017-09-12 오전 1:29:23][Thread 0029][remoting] Starting prune timer for endpoint manager... [INFO][2017-09-12 오전 1:29:23][Thread 0022][remoting] Remoting started; listening on addresses : [akka.tcp://ServiceA@127.0.0.1:8001] [INFO][2017-09-12 오전 1:29:23][Thread 0022][remoting] Remoting now listens on addresses: [akka.tcp://ServiceA@127.0.0.1:8001] [INFO][2017-09-12 오전 1:29:23][Thread 0004][[akka://ServiceA/user/myactor#1560625506]] BasicActor:GetSomeMessage 나는 살아있다. [INFO][2017-09-12 오전 1:29:23][Thread 0008][[akka://ServiceA/user/watcher#2126936690]] WatchActor:GetSomeMessage <Terminated>: [akka://ServiceA/user/myactor#1560625506] - ExistenceConfirmed=True [INFO][2017-09-12 오전 1:29:23][Thread 0008][[akka://ServiceA/user/watcher#2126936690]] 감시대상이 사라짐 [DEBUG][2017-09-12 오전 1:29:23][Thread 0022][ActorSystem(ServiceA)] Disposing system [DEBUG][2017-09-12 오전 1:29:23][Thread 0022][ActorSystem(ServiceA)] System shutdown initiated
AKKA Test Toolkit 사용하기
각종 리모트,클러스터환경에서의 메시지 검증을 위해서 AKKA TestTookit을 제공합니다. ( JAVA에서 제공하는 AKKA TestToolkit과 컨셉이 동일합니다.)
기존 VS 유닛 테스트기와 연동되어 사용이 가능해집니다.
-실제 메시지 처리에 대한 유효검사가 용이해집니다. -여러가지 가상의 환경을 셋팅하여 AKKA의 기능에관련된 메시징 기능 체크가 가능합니다. -이것이 가능한 이유는 기본 유닛테스트 클래스가 액터기반으로 작동이 되기때문입니다. |
|---|
설치(기존 유닛 테스트에 추가 설치)
사용예
using ServiceA.STUDY;
using Akka.TestKit.VsTest;
namespace AkkaTest
{
[TestClass]
public class UnitTest1 : TestKit //TestKit을 상속받습니다.
{
[TestMethod]
public void TestMethod1() //기본 유닛 테스트기
{
using (ActorSystem actorSystem = ActorSystem.Create("ServiceA"))
{
IActorRef myActor = actorSystem.ActorOf<BasicActor>("myactor");
Props watchProps = WatchActor.Props(myActor);
IActorRef watcher = actorSystem.ActorOf(watchProps, "watcher");
var result = myActor.Ask("나는 살아있다.").Result;
actorSystem.Stop(myActor); //myActor를 임의로 Stop하여, watcher가 종료를감시한는지 체크
myActor.GracefulStop(TimeSpan.FromSeconds(10)).Wait(); //생성한 Actor를 안전하게 종료시킨다.
}
}
[TestMethod]
public void TestMethod2() //Akka Tookit을 이용한 유닛테스트, 테스트기에 테스트를 할수 있는 액터가 추가됨
{
var myActor = this.Sys.ActorOf<MyActor>("myActor");
var probe = this.CreateTestProbe();
myActor.Tell("Hello", this.TestActor);
ExpectMsg("Re:Hello", TimeSpan.FromSeconds(1));
}
}
}


