[Test] TDD(Test Driven Development)
·
Software Engineering/Test
TDD: 테스트가 개발을 이끈다?우리는 지금까지 테스트의 필요성과 단위 테스트 작성법에 대해 알아봤다. 이번에는 한 걸음 더 나아가, 아예 개발 프로세스 자체를 뒤집어보는 '테스트 주도 개발(TDD)'에 대해 이야기해보려 한다.TDD(Test Driven Development)란?TDD는 말 그대로 프로덕션 코드보다 테스트 코드를 먼저 작성해서, 테스트가 전체 구현 과정을 이끌어가는 개발 방법론이다."코드를 짜기도 전에 테스트를 어떻게 만들어?" 싶겠지만, TDD는 아주 구체적이고 체계적인 단계를 따른다.TDD의 심장: RED-GREEN-REFACTOR 사이클TDD는 아래 3단계를 끊임없이 반복하며 진행된다.실패하는 테스트부터 작성한다 (RED)우선 "이 기능은 이렇게 동작해야 해"라는 기대를 담아 테스..
[Test] 단위 테스트(Unit Test)
·
Software Engineering/Test
단위 테스트 파헤치기지난 글에서는 테스트가 귀찮지만 왜 필요한지에 대해 알아봤다. 이번에는 '단위 테스트'에 대해 좀 더 깊게 들어가 보자.단위 테스트(Unit Test)란?말 그대로 작은 코드 단위를 독립적으로 검증하는 테스트다. 보통 클래스나 메서드 하나가 그 대상이 된다. 다른 테스트에 비해 검증 속도가 매우 빠르고 안정적이라는 장점이 있다.Java에서는 보통 JUnit5라는 테스트 프레임워크를 사용한다. 여기에 AssertJ라는 라이브러리를 곁들이면, 풍부한 API와 메서드 체이닝을 통해 테스트 코드를 훨씬 깔끔하고 읽기 쉽게 작성할 수 있다.// JUnit5의 @Test 어노테이션과 AssertJ의 assertThat을 사용한 예시class CafeKioskTest { @Test vo..
[Test] 테스트를 해야 하는 이유
·
Software Engineering/Test
테스트는 귀찮다. 그럼에도 왜 해야 할까?솔직히 말해보자. 테스트는 귀찮다. 그럼에도 우리는 왜 테스트 코드를 작성해야만 할까?수동 테스트의 굴레Production Code가 있다고 해보자. 제품 출시를 위해 당연히 테스트가 필요하다.나, 또는 다른 개발자, 혹은 기획자나 QA 같은 동료가 직접 테스트를 시작한다. 웹사이트의 버튼을 하나하나 누르고, 앱에서 특정 기능을 실행해보고, 여러 값을 입력해본다. 예외적인 값도 넣어보며 꼼꼼히 검증한다.좋다. 이렇게 해서 첫 기능이 무사히 검증되었다. 곧이어 새로운 기능이 추가된다. 그럼 또 누군가가 처음부터 끝까지 테스트를 반복해야 한다.시간이 흘러 또 다른 기능이 추가되었는데, 이번엔 기존 프로덕션 코드의 일부가 변경되었다. 이제 문제는 더 복잡해진다. 새로 ..
[JVM] 자바 유저 스레드와 커널 스레드
·
Java/JVM
자바 유저 스레드와 커널 스레드#Java/JVM스레드에는 사용자 수준 스레드(User Level Threads)와 커널 수준 스레드(Kernel Level Threads) 두 가지 유형이 있다. 두 가지의 장점을 합친 Hybrid 모델도 존재한다. Java에서는 Kernel thread와 User thread를 모두 사용하는 Hybrid 모델이다.사용자 수준 스레드는 사용자 라이브러리를 통해 사용자가 만든 스레드로, 스레드가 생성 된 프로세스의 주소 공간에서 해당 프로세스에 의해 실행되고 관리된다.커널 수준 스레드는 커널에 의해 생성되고 운영체제에 의해 직접 관리된다. 사용자 수준 스레드보다 생성 및 관리 속도가 느리다.두 유형의 차이는 누가 스레드를 제어하느냐에 있다.사용자 수준 스레드는 스레드가 생성..
[JVM] 자바 코드부터 JVM의 동작까지 구체적으로 살펴보기
·
Java/JVM
JVM#Java/JVM/자바의 등장 배경/JVM/자바 컴파일러/자바 클래스 로더/자바 실행 엔진(Execution Engine)/자바 인터프리터/자바 JIT 컴파일러/GraalVM/Garbage Collection/자바 런타임 시스템/정리: JVM이란?자바의 등장 배경1990년대 초반 당시 주로 사용되던 C/C++이 갖는 어려 문제점들을 극복하기 위해 개발하게 되었다.문제점들메모리를 개발자가 직접 제어해야 한다는 점복잡성이 높아 개발자가 오류를 만들어내기 쉽다는 점플랫폼에 따라 다른 결과를 출력할 수 있다는 점등등직접 위 문제의 해결 방법들을 찾아보자.메모리를 개발자가 직접 제어해야 한다는 점: 알고리즘을 통해 자동으로 제어하게 설계해보자.복잡성이 높아 개발자가 오류를 만들어내기 쉽다는 점: 선택의 폭을..
[Docker] About 도커(Docker)
·
Infra/Docker
About 도커(Docker)#Docker우테코 테코톡의 영상의 내용을, 글로 편하게 볼 수 있도록 정리한 게시글입니다!참고)https://youtu.be/IiNI6XAYtrs?si=LQPkjVUi-Ac02etT도커란?컨테이너 기반 가상화 도구가상화?가상화의 등장 배경6000만원짜리 좋은 서버가 있다. 여기에 쇼핑몰 사이트를 띄운다.그런데 쇼핑몰 사이트가 좋은 서버의 성능 10%도 못 쓴다.그래서 이 서버에 반려동물 사료 플랫폼이라는 새로운 프로젝트를 같이 올리려고 한다.그런데 그냥 올리면 쇼핑몰 사이트에서 쓰고 있는 기술들이랑 충돌이 발생한다. 서버의 성능을 나눠서 사용할 수 없을까? : 가상화하나의 서버 자원을 나눠 가지고 성능을 분산 시키고, 분산된 서버들은 각기 다른 서비스를 수행할 수 있게 되..
[Java] 68. 병렬 스트림
·
Java/Modern Java(8~)
병렬 스트림#Java/adv3단일 스트림HeavyJob 클래스는 오래 걸리는 작업을 시뮬레이션하는데, 각 작업은 1초 정도 소요된다고 가정하겠다. 입력값에 10을 곱한 결과를 반환하며, 작업이 실행될 때마다 로그를 출력한다.예제1 - 단일 스트림단일 스트림(sequential stream)으로 IntStream.rangeClosed(1, 8)에서 나온 1부터 8까지의 숫자 각각에 대해 heavyTask()를 수행long startTime = System.currentTimeMillis();int sum = IntStream.rangeClosed(1, 8) .map(HeavyJob::heavyTask) .reduce(0, (a, b) -> a + b); // sum()long en..
[Java] 67. 디폴트 메서드
·
Java/Modern Java(8~)
디폴트 메서드#Java/adv3디폴트 메서드가 등장한 이유자바 8에서 디폴트 메서드(default method) 가 등장하기 전에는 인터페이스에 메서드를 새로 추가하는 순간, 이미 배포된 기존 구현 클래스들이 해당 메서드를 구현하지 않았기 때문에 전부 컴파일 에러를 일으키게 되는 문제가 있었다.디폴트 메서드는 이러한 문제를 해결하기 위해 등장했다.자바 8부터는 인터페이스에서 메서드 본문을 가질 수 있도록 허용해 주어, 기존 코드를 깨뜨리지 않고 새 기능을 추가할 수 있게 되었다.디폴트 메서드로 문제 해결자바 8부터 이러한 하위 호환성 문제를 해결하기 위해 디폴트 메서드가 추가되었다. 인터페이스에 메서드를 새로 추가하면서, 기본 구현을 제공할 수 있는 기능이다.예를 들어, Notifier 인터페이스에 sc..
[Java] 66. Optional
·
Java/Modern Java(8~)
Optional#Java/adv3옵셔널이 필요한 이유NPE자바에서 null은 값이 없음을 표현하는 기본적인 방법이다.하지만, null을 잘못 사용하거나 null 참조에 대해 메서드를 호출하면 NullPointerException (NPE)이 발생하여 프로그램이 예기치 않게 종료될 수 있다.메서드 뎁스가 깊고, null 체크를 누락하면 추척하기 어렵고, 디버깅 비용이 증가한다.가독성 저하null을 반환하거나 사용하는 경우, 조건문을 통해 객체가 null인지 계속 확인해야 한다. 이러한 null 체크 로직이 누적되면 코드가 복잡해지고 가독성이 저하된다.의도가 드러나지 않음메서드 시그니처(String findNameById(Long id))만 보고서는 이 메서드가 null을 반환할 수도 있다는 사실을 명확히 ..
[Java] 65. 스트림 API3 - 컬렉터
·
Java/Modern Java(8~)
스트림 API3 - 컬렉터#Java/adv3컬렉터1스트림이 중간 연산을 거쳐 최종 연산으로써 데이터를 처리할 때, 그 결과물이 필요한 경우가 많다. 대표적으로 "리스트 나 맵 같은 자료 구조에 담고 싶다"거나 "통계 데이터를 내고 싶다"는 식의 요구가 있을 때, 이 최종 연산에 Collectors를 활용한다.collect 연산(예: stream.collect(...))은 반환값을 만들어내는 최종 연산이다. collect(Collector collector) 형태를 주로 사용하고, Collectors 클래스 안에 준비된 여러 메서드를 통해서 다양한 수집 방식을 적용할 수 있다.기능메서드 예시설명반환 타입List로 수집toList() toUnmodifiableList()스트림 요소를 List로 모은다. to..