2016-12-05 1 views
4

내 조직은 약 1 년 전에 Java로 작성된 REST 서비스/마이크로 서비스 간의 계약 생성/검증을 위해 Pact를 사용하기 시작했습니다. 우리는 공급자 테스트의 적절한 범위 또는 파악이 무엇인지 결정하고 다른 협약 사용자의 경험으로부터 얻은 의견을 사랑하기를 힘들어합니다.Pact Provider 테스트의 범위는 어떻게되어야합니까?

기본적으로이 토론은 공급자 테스트를 모의하거나 스텁하는 위치를 중심으로 진행됩니다. 서비스에서는 최소한 다른 서비스에 대한 외부 호출을 조롱해야하지만 REST 리소스 클래스에 더 가깝게 조롱하는 옵션이 있습니다.

우리는 두 가지 옵션에 내려 삶은 :

1 첫 번째 옵션은 공급자 테스트는 엄격한 계약 테스트 할 만 서비스를 스텁/조롱 공급자 서비스의 REST 리소스 클래스를 행사해야한다는 것입니다 수업/관현악단 등에서 사용되었습니다. 이 계약 테스트는 공급자 테스트에 의해 스텁/조롱 된 부품을 테스트하는 구성 요소 테스트로 보강됩니다.

2. 두 번째 옵션은 공급자 테스트를 각 요청에 대해 전체 서비스 구성 요소를 실행하는 구성 요소 테스트로 사용하는 것입니다. 다른 구성 요소에 대한 일시적 외부 호출 만 조롱되거나 스텁됩니다.

  • 테스트 구현하기 간단하고 작은 풋 프린트를의
    => 더 높은 학위를 얻을 것이다 :

    다음은 각 옵션에 대한 옵션 1

    프로의 프로의의 생각입니다 격리.

  • 일반적으로 소비자의 expectancy (오류 흐름 등)에서 다루지 않은 사용 사례를 다루기 위해 다른 구성 요소 테스트가 필요할 수 있습니다. 이 방법으로 우리는 하나의 가방에 다른 종류의 컴포넌트 테스트 (Pact 및 기타)를 섞어서 테스트 스위트를 이해하기 쉽게 만들지 않을 것입니다. 옵션 2

프로의는 :

  • 시험은 시험에 나쁜 조롱/스터 빙에 의한 버그를 "진짜"코드 => 적은 위험을 더 많이 운동한다.

나는 정말로 당신의 공급자 테스트가 일반적으로이 점을 어떻게 들었는지에 관심이 있습니다. 모범 사례가 있습니까?

"구성 요소"의 의미를 분명히 함 구성 요소는 대형 서비스 응용 프로그램의 마이크로 서비스 또는 모듈입니다. 우리는 'Martin Fowlers http://martinfowler.com/articles/microservice-testing/'의 구성 요소를 정의했습니다.

일반적으로 공급자 서비스/구성 요소에는 Jersey 리소스 클래스에 REST 끝점이 있습니다. 이 끝점은 Pact 공급자 테스트의 공급자 끝점입니다. 예제 : 위의 예 공급자 테스트를 실행하거나 진짜 "IMPL"클래스를 주입 할 수있을 때 CustomerOrchestrator 조롱 할 수 중 하나를 @Autowired (우리가 스프링을 사용)에서

@Path("/customer") 
public class CustomerResource { 

    @Autowired private CustomerOrchestrator customerOrchestrator; 

    @GET 
    @Path("/{customerId}") 
    @Produces(MediaType.APPLICATION_JSON) 
    public Response get(@PathParam("customerId") String id) { 
     CustomerId customerId = CustomerIdValidator.validate(id); 
     return Response.ok(toJson(customerOrchestrator.getCustomer(customerId))).build(); 
    } 

.실제 "CustomerOrchestratorImpl.class"를 삽입하기로 결정하면 다른 @Autowired Bean 의존성이 생기고, 다른 Bean 종속성은 다른 것을 가질 수 있습니다 ... 등등. 마지막으로 종속성은 데이터베이스 호출을 만들 DAO 객체 또는 다른 다운 스트림 서비스/구성 요소에 대한 HTTP 호출을 수행하는 REST 클라이언트.

위의 예제에서 "옵션 1"솔루션을 채택한다면 CustomerResource의 customerOrchestrator 필드를 조롱하고 "옵션 2"를 채택한다면 각 클래스에 대해 Impl-class (실제 클래스)를 주입합니다 ClientResource 의존성 그래프에 종속성을 부여하고 조롱 된 데이터베이스 항목을 만들고 대신 mocked 다운 스트림 서비스를 만듭니다.

필자는 공급자 테스트에서 실제로 실제 데이터베이스를 거의 사용하지 않는다는 것을 언급해야합니다. "옵션 2"를 채택한 경우 실제 데이터베이스 데이터를 조롱하는 대신 DAO 클래스 계층을 조롱하여 테스트에서 움직이는 부분의 수를 줄였습니다.

우리는 스프링 컨텍스트에서 명시 적으로 선언되지 않은 Autowired 종속성을 자동으로 모의하는 "테스트 프레임 워크"를 만들었으므로 스텁/조롱은 우리에게는 경량 프로세스입니다. 이것은 CustomerResource을 행사하고 스텁 CustomerOrchestrator 빈을 시작 공급자 테스트의 발췌 한 것입니다 :이 자주 오는 질문은

@RunWith(PactRunner.class) 
@Provider("customer-rest-api") 
@PactCachedLoader(CustomerProviderContractTest.class) 
public class CustomerProviderContractTest { 

    @ClassRule 
    public static PactJerseyWebbAppDescriptorRule webAppRule = buildWebAppDescriptorRule(); 

    @Rule 
    public PactJerseyTestRule jersyTestRule = new PactJerseyTestRule(webAppRule.appDescriptor); 

    @TestTarget public final Target target = new HttpTarget(jersyTestRule.port); 

    private static PactJerseyWebbAppDescriptorRule buildWebAppDescriptorRule() { 
     return PactJerseyWebbAppDescriptorRule.Builder.getBuilder() 
      .withContextConfigLocation("classpath:applicationContext-test.xml") 
      .withRestResourceClazzes(CustomerResource.class) 
      .withPackages("api.rest.customer") 
      .build(); 
    } 

    @State("that customer with id 1111111 exists") 
    public void state1() throws Exception { 
     CustomerOrchestrator customerOrchestratorStub = SpringApplicationContext.getBean(CustomerOrchestrator.class) 
     when(customerOrchestratorStub.getCustomer(eq("1111111"))).thenReturn(createMockedCustomer("1111111)); 

    } 
    ... 
+0

안녕하세요 조엘입니다. 협조를 사용하고 계시 다니 기쁩니다. Pact에 사용되는 용어가 아니므로 '구성 요소'가 의미하는 바를 상세하게 설명해 주실 수 있습니까? 또한 두 옵션의 코드 예제를 제공 할 수 있다면 쉽게 의미를 알 수 있습니다. 건배. –

+0

안녕하세요, 구성 요소는 마이크로 서비스 또는 큰 서비스 응용 프로그램의 모듈입니다. 우리는 'Martin Fowler http://martinfowler.com/articles/microservice-testing/'의 구성 요소를 정의했습니다. –

답변

2

, 내 대답은 "각 서비스에 대한 의미가 무엇"이다. 조약이 사용 된 첫 번째 마이크로 서비스는 작고 단순하여 모의 또는 스터브없이 전체 서비스를 테스트하는 것이 가장 쉽습니다. 실제 서비스 호출과 검증 테스트의 유일한 차이점은 테스트에 sqlite를 사용했다는 것입니다. 물론 우리는 다운 스트림 서비스에 대한 호출을 스텁했습니다.

실제 데이터를 설정하는 것이 스텁보다 복잡한 경우 스텁을 사용합니다. 그러나! 이 작업을 수행하려는 경우 협상과 동일한 방식으로 스텁 통화를 확인해야합니다. 일종의 공유 치구를 사용하고 pact 제공자 테스트에서 스텁하는 모든 호출에 대해 예상 한대로 동작이 일치하는지 테스트해야합니다. 당신이 협력/계약 테스트를 체인있는 것처럼 그것은 다음과 같이 함께입니다 : 내가 옵션으로 이동 말할 enter image description here

+0

고마워 베스, 스터 빙 할 때 연쇄 측면에 좋은 점. 필자는 모든 개발자가 공통된 "테스트 전략/우수 사례"를 만들 수 있도록 테스트 범위를 지정하는 방법에 대한 "규칙"이라고 생각합니다. 우리는 모든 사람들이 각 상황에서 가장 적절하다고 생각하는 것을하도록 허용한다면 조만간 공급자 테스트의 다양한 맛을 갖게 될 것이라는 점에 조금은 두려워합니다. 연쇄 측면을 강조하는 것은 스텁 영역의 유연성을 허용하더라도 테스트 웹에 구멍이 생기지 않도록하는 한 가지 방법 일 수 있습니다. –

0

2.

협정에 대한 전체 존재 이유이 자신감을 가지고 있기 때문에 그 이유는 귀하의 코드 변경 - 그것은 소비자를 해치지 않을 것입니다. 그렇지 않으면 상호 작용을 그대로 유지하면서 변경 (버전 관리)을 관리하는 방법을 찾습니다.

완전히 자신감을 가지려면 가능한 한 '실제'코드를 사용해야하며 데이터는 조롱되거나 실제 일 수 있지만 실제로는 그다지 중요하지 않습니다. 프로덕션 코드를 배포하기 전에 많은 양의 프로덕션 코드를 테스트 할 수 있기를 원합니다.

내가 사용하는 방식에는 2 가지 유형의 테스트, 유닛 테스트 및 Pact 테스트가 있습니다. 단위 테스트는 Pact 테스트가 소비자와 공급자 간의 상호 작용을 테스트하는 데 사용되는 반면 내 코드 변경은 종속성을 조롱하는 데 유용한 바보 같은 실수 나 잘못된 입력에 대해 내 코드가 손상되지 않도록합니다. 요청 또는 데이터 형식에 영향을줍니다. 잠재적으로 여기에서 종속성을 조롱 할 수는 있지만 종속성이 요청 또는 데이터에 영향을 줄 수 있으므로 프로덕션 환경에서 손상 될 수 있습니다.

그러나 소비자와 공급자 간의 계약을 테스트하는 데 사용하는 한 Pact를 사용하는 방법은 모두 기본 설정입니다.

0

우리는 옵션 2를 결정했습니다. 공급자 테스트에서 최대한 많은 실제 코드를 포함하도록 노력해야합니다. 가장 큰 이유는 보완적인 구성 요소 테스트에서 조롱 된 스프링 빈에서 테스트 대칭을 얻는 것이 옵션 2를 사용하여 결과적으로 약간 더 복잡한 공급자 테스트를하는 것보다 복잡 할 수 있다는 것입니다.

입력 해 주셔서 감사합니다!

관련 문제