Arquillian을 사용한 테스트 소개

1. 개요

Arquillian은 Jakarta EE를위한 컨테이너에 구애받지 않는 통합 테스트 프레임 워크입니다. Arquillian을 사용하면 컨테이너, 배포, 프레임 워크 초기화 등의 관리 부담이 최소화됩니다.

테스트 환경을 부트 스트랩하는 것이 아니라 실제 테스트 작성에 집중할 수 있습니다.

2. 핵심 개념

2.1. 배포 아카이브

컨테이너 내부에서 실행할 때 애플리케이션을 쉽게 테스트 할 수있는 방법이 있습니다.

첫째, ShrinkWrap 클래스는 배포 가능한 * .jar, * .war* .ear 파일 을 생성하는 API를 제공 합니다.

그런 다음 Arquillian을 사용 하면 ShrinkWrap 객체 를 반환하는 메서드 에서 @Deployment 주석을 사용하여 테스트 배포를 구성 할 수 있습니다 .

2.2. 컨테이너

Arquillian은 세 가지 유형의 컨테이너를 구분합니다.

  • 원격 – JMX와 같은 원격 프로토콜을 사용하여 테스트
  • 관리 형 – 원격 컨테이너이지만 수명주기는 Arquillian에서 관리합니다.
  • 임베디드 – 로컬 프로토콜을 사용하여 테스트가 수행되는 로컬 컨테이너

또한 기능별로 컨테이너를 분류 할 수 있습니다.

  • Glassfish 또는 JBoss와 같은 애플리케이션 서버에 배포 된 Jakarta EE 애플리케이션
  • Tomcat 또는 Jetty에 배포 된 서블릿 컨테이너
  • 독립형 컨테이너
  • OSGI 컨테이너

런타임 클래스 경로를 검사하고 사용 가능한 컨테이너를 자동으로 선택합니다.

2.3. 강화 테스트

Arquillian은 테스트를 쉽게 작성할 수 있도록 종속성 주입 등을 제공하여 테스트를 강화합니다.

@Inject를 사용하여 종속성을 주입하고, @Resource를 사용하여 리소스를 주입하고 , @EJB를 사용하여 EJB 세션 빈을 사용할 수 있습니다 .

2.4. 여러 테스트 러너

주석을 사용하여 여러 배포를 만들 수 있습니다.

@Deployment(name="myname" order = 1)

여기서 name은 배포 파일의 이름이고 order 매개 변수는 배포의 실행 순서이므로 이제 주석을 사용하여 여러 배포에서 동시에 테스트를 실행할 수 있습니다.

@Test @OperateOnDeployment("myname")

이전 테스트는 @Deployment 주석에 정의 된 순서를 사용하여 myname 배포 컨테이너 에서 실행됩니다 .

2.5. Arquillian 확장

Arquillian은 테스트 요구 사항이 핵심 런타임에 포함되지 않는 경우 여러 확장을 제공합니다. 지속성, 트랜잭션, 클라이언트 / 서버, REST 확장 등이 있습니다.

Maven 또는 Gradle 구성 파일에 적절한 종속성을 추가하여 이러한 확장을 활성화 할 수 있습니다.

일반적으로 사용되는 확장은 Drone, Graphene 및 Selenium입니다.

3. Maven 종속성 및 설정

pom.xml 파일에 다음 종속성을 추가해 보겠습니다 .

 org.jboss.arquillian arquillian-bom 1.1.13.Final import pom   org.glassfish.main.extras glassfish-embedded-all 4.1.2 test   org.jboss.arquillian.container arquillian-glassfish-embedded-3.1 1.0.0.Final test 

최신 버전의 종속성은 여기에서 찾을 수 있습니다 : arquillian-bom, org.glassfish.main.extras, org.jboss.arquillian.container.

4. 간단한 테스트

4.1. 구성 요소 만들기

간단한 구성 요소부터 시작하겠습니다. 테스트에 집중할 수 있도록 여기에 고급 로직을 포함하지 않습니다.

public class Component { public void sendMessage(PrintStream to, String msg) { to.println(message(msg)); } public String message(String msg) { return "Message, " + msg; } }

Arquillian을 사용하여이 클래스가 CDI 빈으로 호출 될 때 올바르게 작동하는지 테스트하려고합니다.

4.2. 첫 번째 Arquillian 테스트 작성

먼저 프레임 워크 별 실행기를 사용하여 테스트 클래스를 실행하도록 지정해야합니다.

@RunWith(Arquillian.class) 

컨테이너 내에서 테스트를 실행하려면 @Deployment 주석 을 사용해야합니다 .

Arquillian은 테스트 아카이브를 격리하기 위해 전체 클래스 경로를 사용하지 않습니다. 대신 아카이브 생성을위한 Java API 인 ShrinkWrap 클래스를 사용합니다 . 테스트 할 아카이브를 만들 때 테스트를 사용하기 위해 클래스 경로에 포함 할 파일을 지정합니다. 배포 중에 ShrinkWrap 은 테스트에 필요한 클래스 만 격리합니다.

addclass () 메서드를 사용하여 필요한 모든 클래스를 지정하고 빈 매니페스트 리소스를 추가 할 수도 있습니다.

The JavaArchive.class creates a mockup web archive called test.war, this file is deployed into the container and then is used by Arquillian to perform tests:

@Deployment public static JavaArchive createDeployment() { return ShrinkWrap.create(JavaArchive.class) .addClass(Component.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); }

Then we inject our component in the test:

@Inject private Component component;

Finally, we perform our test:

assertEquals("Message, MESSAGE",component.message(("MESSAGE"))); component.sendMessage(System.out, "MESSAGE");

5. Testing Enterprise Java Beans

5.1. Enterprise Java Bean

With Arquillian we can test dependency injection of an Enterprise Java Bean, to do that we create a class that has a method for converting any word to lowercase:

public class ConvertToLowerCase { public String convert(String word){ return word.toLowerCase(); } }

Using this class, we create a stateless class for calling the method created before:

@Stateless public class CapsConvertor { public ConvertToLowerCase getLowerCase(){ return new ConvertToLowerCase(); } }

The CapsConvertor class gets injected into a service bean:

@Stateless public class CapsService { @Inject private CapsConvertor capsConvertor; public String getConvertedCaps(final String word){ return capsConvertor.getLowerCase().convert(word); } }

5.2. Test the Enterprise Java Bean

Now we can use Arquillian to test our enterprise Java Bean, injecting the CapsService:

@Inject private CapsService capsService; @Test public void givenWord_WhenUppercase_ThenLowercase(){ assertTrue("capitalize".equals(capsService.getConvertedCaps("CAPITALIZE"))); assertEquals("capitalize", capsService.getConvertedCaps("CAPITALIZE")); }

Using ShrinkWrap, we ensure that all classes are wired correctly:

@Deployment public static JavaArchive createDeployment() { return ShrinkWrap.create(JavaArchive.class) .addClasses(CapsService.class, CapsConvertor.class, ConvertToLowerCase.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); }

6. Testing JPA

6.1. Persistence

We can also use Arquillian to test persistence. First, we are going to create our entity:

@Entity public class Car { @Id @GeneratedValue private Long id; @NotNull private String name; // getters and setters }

We have a table that holds names of cars.

Then we are going to create our EJB to perform basic operations on our data:

@Stateless public class CarEJB { @PersistenceContext(unitName = "defaultPersistenceUnit") private EntityManager em; public Car saveCar(Car car) { em.persist(car); return car; } public List findAllCars() { Query query = em.createQuery("SELECT b FROM Car b ORDER BY b.name ASC"); List entries = query.getResultList(); return entries == null ? new ArrayList() : entries; public void deleteCar(Car car) { car = em.merge(car); em.remove(car); } }

With saveCar we can save the car names into the database, we can get all cars stored with findAllCars, and also we can delete a car from the database with deleteCar.

6.2. Test Persistence With Arquillian

Now we can perform some basic tests using Arquillian.

First, we add our classes to our ShrinkWrap:

.addClasses(Car.class, CarEJB.class) .addAsResource("META-INF/persistence.xml")

Then we create our test:

@Test public void testCars() { assertTrue(carEJB.findAllCars().isEmpty()); Car c1 = new Car(); c1.setName("Impala"); Car c2 = new Car(); c2.setName("Lincoln"); carEJB.saveCar(c1); carEJB.saveCar(c2); assertEquals(2, carEJB.findAllCars().size()); carEJB.deleteCar(c1); assertEquals(1, carEJB.findAllCars().size()); }

이 테스트에서는 먼저 4 개의 자동차 인스턴스를 만들고 데이터베이스의 행 수가 우리가 만든 것과 동일한 지 확인합니다.

8. 결론

이 튜토리얼에서 우리는 :

  • Arquillian 핵심 개념 도입
  • Arquillian 테스트에 부품 주입
  • EJB 테스트
  • 테스트 된 지속성
  • Maven을 사용하여 Arquillian 테스트를 수행했습니다.

Github의 기사에서 코드를 찾을 수 있습니다.