테스트 코드도 jar에 포함 시키기

배경 여러 컴포넌트의 테스트 코드에서 테스트 픽스처로 공통적으로 구성되어야 하는 로직이 있었다. 이를 core 컴포넌트의 테스트 코드(/src/test)에 구현하고 모든 컴포넌트에서 사용할 수 있도록 하고 싶었다. Apache Maven JAR Plugin maven에서 jar로 package할 때 사용되는 기본 플러그인 해당 플러그인의 execution을 추가해서 테스트 코드를 별도의 jar 파일로 패키징할 수 있다. <execution>: maven 라이프사이클 중에 플러그인이 실행하고자 하는 내용을 정의할 수 있다. 테스트 코드를 추가하고자 하는 컴포넌트의 maven 설정 아래와 같이 설정하면 프로덕션 코드는 {artifactId}-{version}....

2024-09-15 · 1 min · 101 words

테스트 종류

최근 수업 시간을 통해 단위 테스트나 통합 테스트 같은 코드 동작 테스트만 있는게 아니라 부하 테스트, 성능 테스트도 필요하다는 사실을 알게되었다. 이외에도 어떤 테스트가 있고 우리는 개발에 어떤 테스트가 필요한지 알아보도록한다. 테스트 접근법 테스트를 하기 위해서는 3가지의 접근법이 있다고한다. 화이트 박스 테스트 애플리케이션 내부의 코드를 기반으로 테스트를 진행한다. 모든 코드 라인을 거쳐 변수에 의도한 값이 저장되어 있는지, 의도한대로 분기문을 거치는지 등의 개발자가 이해할 수 있는 수준의 테스트 코드를 작성한다. 화이트 박스 테스트의 경우 불필요한 코드를 제거하는 등의 최적화를 할 수 있는 장점이 있다....

2024-09-15 · 2 min · 349 words

테스트 실행 시 로그 확인하기

gradle test -i 참고 자료 https://stackoverflow.com/questions/3963708/gradle-how-to-display-test-results-in-the-console-in-real-time

2024-09-15 · 1 min · 6 words

테스트 방법론

구현과 테스트 소프트웨어 생명 주기 (SDLC)와 테스트 V-Diagram Requirement Analysis: 의뢰자로부터 요구 사항을 받아 분석 System Design: 소프트웨어 명세 작성. 시스템 구성, 메뉴 구조, 데이터 구조 등. Architecture Design: 모듈 목록, 각 모듈의 기능, 인터페이스 관계, 의존 관계, 데이터베이스 테이블 등 설계. Module Design: 프로그래머가 직접 코딩을 할 수 있도록 유닛 또는 모듈 단위로 설계. 테스트 unit test 테스트가 가능한 최소 단위로 나누어진 모듈, 프로그램, 객체, 클래스 내에서 결함을 찾고 그 기능을 검증하는 것임 시스템의 다른 부분에서 격리하여 독립적으로 수행 됨 코드를 작성한 프로그래머가 주도함 코드를 중심으로 수행함 integration test 모듈간 인터페이스를 테스트 함 각기 다른 모듈과 상호 연동하는 동작을 테스트 함 기능적 특성과 특정한 비기능적 특성을 테스트 함 기능성: 조향 비기능성: 성능, 부하, 스트레스 등 system test 전체 시스템 또는 제품의 동작에 대해 테스트함 가능한 범위에서 실제 최종 사용 환경 또는 유사한 환경에서 수행함 환경 특성 장애 리스크를 최소화 하기 위해서 기능 및 비기능 요구 사항을 모두 검증함 독립적인 테스트 팀이 주도함(QA 팀 등) acceptance test 시스템이 실제 사용할만한 준비가 되어있는지에 대해 평가함 결함을 찾는 것이 주된 관심사가 아님 사용자가 불편함이 없는지 확인하는 것이 주 목적 시스템을 사용하는 사용자가 전담하여 수행함 알파/베타 테스트 알파 테스트: 사내 이해당사자들에게 테스트 베타 테스트: 사외 대상자들에게 테스트 FIRST: 좋은 단위 테스트는 무엇인가?...

2024-09-15 · 4 min · 750 words

타입 소거

목표 타입 소거의 의미를 이해한다. 타입 소거가 필요한 이유를 이해한다. 타입 소거의 의미 타입 파라미터에 대해서 컴파일 타임에만 타입 검사를 하고 런타임에는 타입에 대한 정보를 삭제하는 방식 아래와 같은 코드가 있다고 가정하면 public static <E> boolean containsElement(E [] elements, E element){ for (E e : elements){ if(e.equals(element)){ return true; } } return false; } 런타임에는 아래와 같이 동작한다. unbound 타입인 E가 Object 타입으로 치환되었다. public static boolean containsElement(Object [] elements, Object element){ for (Object e : elements){ if(e....

2024-09-15 · 2 min · 244 words

클래스의 모든 필드를 getter 없이도 직렬화

코드 리뷰를 하다가 새로운 사실을 알게 되었다. Jackson은 기본적으로 getter 메소드로 직렬화를 한다. 아래처럼 지정하면 클래스의 필드들을 기반으로 접근제어자 상관 없이 직렬화가 가능하다. OBJECT_MAPPER.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

2024-09-15 · 1 min · 25 words

클라이언트가 서버에 갱신된 정보를 빠르게 가져오는 방법

이런 고민을 한 이유: HTTP의 한계 무상태성: 클라이언트의 상태를 기억하지 않기 때문에 클라이언트에게 갱신된 정보를 알려줄 수 없다. 비연결성: 1개의 리퀘스트로 부터 응답을 하면 연결이 끊어진다. Polling: 주기적으로 클라이언트가 request를 보내 새로운 정보를 갱신하는 방법 장점 구현이 단순하다. 단점 주기적으로 HTTP 연결을 맺고 끊는게 상당한 클라이언트와 서버 측에서 모두 큰 부담이 된다. 이를 어느 정도 해결하기 위해 전송하는 데이터 양을 줄이기 위해 ajax를 사용한다. Long Polling(HTTP/1.1): 클라이언트와 서버가 계속 연결을 맺고 끊는 것을 줄이기 위해서 만든 방법....

2024-09-15 · 2 min · 401 words

쿼리 파라미터가 여러 개인 경우 어떻게 처리할까

일반적으로 두 가지 방법을 사용한다. http://localhost:8080/api/foos?id=1,2,3 http://localhost:8080/api/foos?id=1&id=2 위의 두 예시모두 Spring MVC에서 자동으로 매핑시켜주기 때문에 걱정없이 사용할 수 있다. @GetMapping("/api/foos") @ResponseBody public String getFoos(@RequestParam List<String> id) { return "IDs are " + id; } 참고 자료 https://stackoverflow.com/questions/2602043/rest-api-best-practice-how-to-accept-list-of-parameter-values-as-input

2024-09-15 · 1 min · 37 words

쿠버네티스로 클러스터 구성하기

쿠버네티스 구성 방법 퍼블릭 클라우드 업체에서 제공하는 관리형 쿠버네티스 EKS(Amazon Elastic Kubernetes), AKS(Azure Kubernetes Services), GKE(Google Kubernetes Engine) 등이 있다. 구성이 이미 다 갖춰져 있고 마스터 노드를 클라우드 업체에서 관리하기 떄문에 학습용으로는 적합하지 않다. 설치형 쿠버네티스 Rancher, OpenShift 등이 있다. 하지만 유료라는 단점이 있다. 구성형 쿠버네티스 kubeadm, kops(Kubernetes Operations), KRIB(Kubernetes Rebar Integrated Bootstrap), kubespray 등이 있다. 사용하는 시스템에 쿠버네티스 클러스터를 자동으로 구성해준다. kubeadm이 가장 널리 알려져 있다. kubeadm은 사용자가 변경하기도 쉽고, 온프레미스와 클라우드를 모두 지원하며, 배우기도 쉽다....

2024-09-15 · 3 min · 441 words

코딩을 지탱하는 기술

프로그래밍 언어의 목적 프로그래밍 언어는 인간을 편하게 하기 위해 만들어졌다. 예전에는 케이블의 연결을 바꾸고(ENIAC), 테이프에 구멍을 뚫어서 데이터를 표현하는(EDSAC) 것을 통해 프로그램을 변경할 수 있었다. 이것은 사람이 프로그램을 읽거나 쓰기에는 어려웠다. 그 이후에 현재 우리가 사용하고 있는 것과 비슷한 프로그래밍 언어 FORTRAN이 고안되었다. 이렇게 프로그래밍 언어의 목적은 프로그래밍을 편리하게 하는 것이다. 하지만 이 편리함의 의미는 사람에 따라 다르기 때문에 현재에 수많은 언어가 존재하고 있는 것이다. 예를 들어, C++는 빠른 실행 속도를 중시하고 있지만, 결과적으로 언어 사양이 복잡해졌다....

2024-09-15 · 10 min · 2026 words

컬럼명 수정 SQL

ALTER TABLE user CHANGE name nickname VARCHAR(30) NULL; 바꿀 컬럼명 뒤에 타입도 함께 명시하지 않으면 에러가 난다는 점을 유의해야된다.

2024-09-15 · 1 min · 19 words

컨테이터 IP 확인하기

docker위에서 돌아가고 있는 WAS가 docker 위에 올라가 있는 DB에게 연결을 계속 실패하는 문제가 있었다. 분명 docker inspect 명령어로 확인한 IP 주소 값인데 왜 연결에 실패하는지 이해가 되지 않았다. docker를 사용하면 docker0라는 네트워크 인터페이스가 생긴다. docker에서는 이 네트워크 인터페이스에 bridge라는 네트워크 드라이버를 제공하고있다. 그래서 docker를 설치한 직후에 docker network ls 명렁어를 입력하면 아래와 같이 bridge 드라이버를 사용중인 네트워크를 볼 수 있다. 또한 아무 설정없이 컨테이너를 만들면 이 기본 bridge 네트워크에 연결하게 된다....

2024-09-15 · 1 min · 134 words

컨테이너로 이미지 만들기 및 Docker hub에 업로드

컨테이너로 이미지 만들기 docker commit [ContainerID] 이미지에 태그 붙이기 docker tag SOURCE_IMAGE[:TAG] TARcoGET_IMAGE[:TAG] 이미지 docker hub에 업로드 및 다운로드 docker push [OPTIONS] NAME[:TAG] docker pull [OPTIONS] NAME[:TAG] 참고 자료 https://galid1.tistory.com/324

2024-09-15 · 1 min · 30 words

최대 샤드 개수

배경 테스트 코드 실행 중에 ES에서 최대 샤드 개수를 초과해서 인덱스를 만들 수 없다는 오류가 발생했다. cluster.max_shards_per_node ES 클러스터 설정 값 중에 한 노드 당 만들 수 있는 최대 샤드 수가 있다. 클러스터 내에 있을 수 있는 (프라이머리 샤드 수) + (레플리카 샤드 수)의 최대는 cluster.max_shards_per_node * number of non-frozen data nodes 참고 자료 https://www.elastic.co/guide/en/elasticsearch/reference/current/misc-cluster-settings.html

2024-09-15 · 1 min · 55 words

지연 로딩

즉시 로딩과 지연 로딩 @Entity public class Member { @ManyToOne @JoinColumn(name = "TEAM_ID") private Team teams; // ... } 즉시 로딩(@ManyToOne(fetch = FetchType.EAGER)): Member라는 엔티티를 조회할 때 연관된 엔티티인 Team 도 같이 조회된다. 지연 로딩(@ManyToOne(fetch = FetchType.LAZY)): Member라는 엔티티를 조회할 때 Team을 조회하지 않다가, 실제로 사용할 떄 조회한다. ex) member.getTeam() 지연 로딩의 동작 방법 만약, 위 예시에서 team이 지연로딩()을 사용 중이라면 member.getTeam() 을 호출했을 때의 Team은 프록시 객체다. 그리고 이 프록시 객체는 실제 사용될 때 까지 로딩을 미룬다....

2024-09-15 · 3 min · 572 words

중위 함수

목표 중위 함수 구현 방법을 알아본다. infix 중위 함수로 만들고자 하는 함수 앞에 infix 키워드를 붙이면 된다. 단, 3가지 조건이 있다. 함수가 클리스에 구현되어 있거나, 특정 클래스의 확장 함수이다. 함수는 정확히 하나의 파라미터를 가진다. 함수 앞에 infix 키워드가 붙어있다. data class Point(val x: Int, val y: Int) { infix fun isEqualTo(other: Point): Boolean { return x == other.x && y == other.y } } Point(1, 2) isEqualTo Point(1, 2) 참고 자료 https://www....

2024-09-15 · 1 min · 72 words

주기적으로 특정 함수 실행시키기

아래의 함수로 구현할 수 있다. var intervalID = setInterval(func, [delay, arg1, arg2, ...]); 실행 주기는 ms 단위다. var intervalID = setInterval(myCallback, 500, 'Parameter 1', 'Parameter 2'); function myCallback(a, b) { // Your code here // Parameters are purely optional. console.log(a); console.log(b); } 주기 실행을 멈추려면 아래 함수를 사용하면 된다. clearInterval(intervalID)

2024-09-15 · 1 min · 50 words

정적 페이지 배포시 Cloudfront 캐시 지우기

새로 배포할 때마다 cloudfront에 캐싱 되어 있는 파일을 지워야된다면 invalidation을 생성하면된다. 하지만 여기서 주의할 점이 invalidation은 설정 값이 아니다. 배포할 때마다 매번 invalidation을 생성해서 무효화 해줘야된다. 우리는 이 또한 자동화 해주고싶어서 aws cli를 사용했다. aws cloudfront create-invalidation --distribution-id ${{ secrets.DISTRIBUTION_ID }} --paths "/index.html" "/bundle.js" 위의 명령어를 사용하려면 IAM에 CreateInvalidation 접근 권한이 필요하다. 우리의 경우 CU 코치님에게 요청을 해서 받을 수 있었다. 참고 자료 https://docs.aws.amazon.com/cli/latest/reference/cloudfront/create-invalidation.html

2024-09-15 · 1 min · 64 words

전역 에러 처리하기

목표 Vue 앱에서 처리하지 않은 에러를 전역적으로 처리하는 방법을 이해한다. app.config.errorHandler app.config.errorHandler에 catch하지 않은 에러의 global handler를 할당할 수 있다. app.config.errorHandler = (err, instance, info) => { // handle error, e.g. report to a service } 핸들링해줄 수 있는 함수들은 다음과 같다. Component renders Event handler Lifecycle hooks setUp() 함수 Watchers Coustom directive hooks Transition hooks 참고 자료 https://vuejs.org/api/application.html#app-config-errorhandler

2024-09-15 · 1 min · 59 words

자식 컴포넌트의 함수 호출하기

Ref를 사용하면 특정 DOM노드나 React 요소에 접근하는 방법을 제공해준다. Ref 생성하기 아래와 같이 React.createRef() 함수로 Ref를 생성한뒤, 원하는 DOM 노드의 프로퍼티로 Ref를 지정해주면된다. class MyComponent extends React.Component { constructor(props) { super(props); this.myRef = React.createRef(); } render() { return <div ref={this.myRef} />; } } Ref에 접근하기 ref에 엘리먼트가 전달되었을 때, ref의 current라는 어트리뷰트에 담기게된다. const node = this.myRef.current; 그 뒤에는 해당 컴포넌트에 있는 함수를 호출 할 수 있다. class AutoFocusTextInput extends React....

2024-09-15 · 1 min · 96 words