TIL - 22.12.02

0

TIL

목록 보기
25/126

Process & Thread

유튜브 영상 설명
얄코 : https://www.youtube.com/watch?v=iks_Xb9DtTM
테코톡 : https://www.youtube.com/watch?v=1grtWKqTn50



테스트 코드

  • 잘 작동하고 깔끔한 코드를 얻기 위해 테스트 코드를 작성한다.

  • 테스트 코드 작성의 장점
    개발 과정 중 예상치 못한 문제를 미리 발견할 수 있다.
    작성한 코드가 의도한 대로 작동하는지 검증할 수 있다.
    코드의 변경, 추가, 삭제 시 사이드 이펙트를 줄일 수 있다.

  • Annotation
    @Test : 테스트 메서드임을 나타냄. 실행 가능
    @BeforEach : 각 메서드 실행 전에 무조건 실행
    @BeforAll : 현재 클래스의 모든 메서드보다 먼저 실행되어야하는 메서드 표시
    @AfterAll : 현재 클래스의 모든 메서드보다 나중에 실행되어야하는 메서드 표시
    @RepeatedTest : 메서드 반복 호출을 함을 표시
    @DisplayName : 사용자 지정 표시 이름을 선언
    @AfterEach : 각 메서드 실행 후 무조건 실행


좋은 테스트 코드는 새로운 기능을 구현, 코드를 리팩터링 하는 데에 좋지만, 의미 없는 테스트 코드는 코드를 작성하는데 필요한 에너지 낭비와 수정, 유지 관리에 비용이 든다.


좋은 테스트 코드를 작성하는 방법

  1. 간단하게 만들기
    • 테스트 코드에 복잡한 논리를 피해야 한다.
  2. 엣지 케이스 테스트
    • 자주 발생하지 않는 항목을 테스트. 오류가 발생해야되는 부분이나 예외 처리가 필요한 부분(잘못된 입력, 누락된 인수, 빈 데이터, 호출된 함수의 예외) 등을 테스트한다.
  3. 버그를 수정하기 전에 테스트 작성
    • 버그가 발생했다면 재현하는 테스트를 작성해야 나중에 회귀 테스트로 기억에 남는다.
  4. 설명이 포함된 이름 사용
    • 테스트가 실패했을 때 가장 먼저 보게되는 것이 이름이고 찾아내기 쉽다.
  5. 한 번에 하나의 요구 사항 테스트
    • 요구사항에 맞는 구체적인 이름을 선택할 수 있고 테스트가 덜 부풀어 오르고 읽기 쉽고, 유지 관리가 쉬워진다.

테스트 코드 예제 - 1

테스트 하고자하는 구현 클래스

package lecture;

import java.util.List;

public class Practice {     // 구현 클래스
    public Integer sumInt(int a, int b) {
        return a + b;
    }
    public Double average(List<Integer> integers) {
        return integers.stream().mapToInt(Integer::intValue).average().getAsDouble();
    }
}

구현클래스에서 생성된 테스트 클래스

package lecture;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.Arrays;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

class PracticeTest {
    Practice practice = new Practice();

    @Test
    @DisplayName("sum 메소드 성공 테스트")
    void sumTest() {
        Integer sumInt = practice.sumInt(1, 2);

        assertNotNull(sumInt);
        assertEquals(sumInt, 3);
    }

    @Test
    @DisplayName("average 메소드 성공 테스트")
    void average() {
        Double average = practice.average(Arrays.asList(1, 2, 3, 5, 6));

        assertNotNull(average);
        assertEquals(average, 3.4);
    }
}

스레드

  • 프로세스 내에서 프로세스의 자원을 이용하는 여러 실행 흐름의 단위
  • 스레드를 일꾼 이라고 생각한다면 이해하기 편하다.
  • 스레드는 프로세스 내의 Code, Data, Heap 영역은 다른 스레드와 공유하고 Stack 영역을 각자 할당받는다.


실행 단계 살펴보기

  1. 프로그램이 실행되면, 가장 먼저 main() 함수가 호출되어 main() 함수의 스택 프레임이 스택에 저장.
  2. func1() 함수를 호출하면 해당 함수의 매개변수, 반환 주소값, 지역 변수 등의 스택 프레임이 스택에 저장.
  3. func2() 함수를 호출하면 해당 함수의 스택 프레임이 추가로 스택에 저장.
  4. func2() 함수의 모든 작업이 완료되어 반환되면, func2() 함수의 스택 프레임만이 스택에서 제거.
  5. func1() 함수의 호출이 종료되면, func1() 함수의 스택 프레임이 스택에서 제거.
  6. main() 함수의 모든 작업이 완료되면, main() 함수의 스택 프레임이 스택에서 제거되면서 프로그램이 종료.

→ Stack 자료구조! Last-In, First-Out

0개의 댓글