뒤로가기

Experience

Spock Extension과 Elasticsearch + Kibana 조합으로 테스트 결과를 빠르게 피드

김다나 2020.01.03. 10

모든 테스트는 중요하고 가치가 높은 활동입니다. 특히 개발을 지원하기 위한 기술 중심의 테스트가 조금 더 중요하고 가능하다면 이런 테스트를 더 많이 해야 한다고 생각해 왔습니다. 왜냐하면, 버그가 나타나는 시점은 코드가 개발된 직후입니다. 이때 테스트가 수행되고 테스트 수행 결과를 피드백 받는 시간 간격이 짧을수록 버그의 원인을 쉽고 빠르게 찾을 수 있기 때문입니다.

하지만, 기술 중심의 자동화된 테스트 없이 수동으로 테스트를 하는 것은 테스트 수행 시간과 결과를 피드백 받는 시간이 더 오래 걸린다는 단점이 있습니다.

자동화된 회귀 테스트는 수행 속도가 빠르고 반복적인 테스트에 적합합니다. 사람의 인지 능력이 있어야 하는 영역에는 사용할 수 없고, 살충제 패러독스Pesticide paradox에 빠지기가 더 쉽습니다.

Effective Unit Testing이란 책에서도 “테스트의 실행 속도가 테스트의 피드백 주기를 감소시키고 생산성에 직접적인 영향을 준다”고 설명하고 있습니다.

http client

담당하고 있는 제품(또는 서비스)의 품질을 유지하면서 업무 생산성을 높이기 위해 API 리그레션 테스트를 자동화했습니다. 그리고, 테스트 결과를 Elasticsearch로 전송하고 Kibana를 통해서 피드백 받을 수 있도록 시스템을 구성한 과정을 공유하고자 합니다.

  • feign client 에서 method return type 을 feign 의 feign.Response 로 하고 있습니다.
                                            
                                            @Getter
    @NoArgsConstructor(access = AccessLevel.PROTECTED)
    @Entity
    public class Sales extends DateTimeEntity {
    
    	@Id
    	@GeneratedValue(strategy = GenerationType.IDENTITY)
    	private Long id;
    
    	@ManyToOne(fetch = FetchType.LAZY) // (2)
    	@JoinColumn(name = "owner_id", nullable = false)
    	private Owner owner;
    
    	@OneToMany(mappedBy = "sales", cascade = CascadeType.ALL, orphanRemoval = true)
    	private List<SalesDetail> salesDetailList = new ArrayList<>();
    
    	// (3)
    	@Column(name = "item", nullable = false)
    	private String item;
    
    	private long totalSales;
    
    	private long settlement;
    
    	// (1)
    	@Column(nullable = false)
    	private LocalDateTime occurDateTime;
    	
    	// (4)
    }
                                        
    • OkHttpClient 로 설정하기
      • 의존성 추가하기
                                            
                                            @Getter
    @NoArgsConstructor(access = AccessLevel.PROTECTED)
    @Entity
    public class Sales extends DateTimeEntity {
    
    	@Id
    	@GeneratedValue(strategy = GenerationType.IDENTITY)
    	private Long id;
    
    	@ManyToOne(fetch = FetchType.LAZY) // (2)
    	@JoinColumn(name = "owner_id", nullable = false)
    	private Owner owner;
    
    	@OneToMany(mappedBy = "sales", cascade = CascadeType.ALL, orphanRemoval = true)
    	private List<SalesDetail> salesDetailList = new ArrayList<>();
    
    	// (3)
    	@Column(name = "item", nullable = false)
    	private String item;
    
    	private long totalSales;
    
    	private long settlement;
    
    	// (1)
    	@Column(nullable = false)
    	private LocalDateTime occurDateTime;
    	
    	// (4)
    }