> For the complete documentation index, see [llms.txt](https://ssosso.gitbook.io/study/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ssosso.gitbook.io/study/spring/toby1/2..md).

# 2. 테스트

## 테스트

값을 검증하고 확인하는 작업은 중요하다. 프로그램을 단단하게 만드는 방법으로 객체지향프로그래밍 방식을 통한 개발방식이 있고, 만들어진 내용을 검장히기 위한 테스트는 필수적 요소이다.

### 1 UserDaoTest 다시보기

#### 1.1 테스트의 유용성

**테스트를 통해 코드 및 설계의 결함을 해결**해나가야 소프트웨어 품질이 향상 -> `디버깅`을 통한 결함해소

#### 1.2 UserDaoTest의 특징

`main 메서드로 작성된 테스트` 코드이다.

* main 메서드는 쉽게 테스트 실행 가능
* UserDao를 직접 호출해서 사용

**웹을 통한 DAO 테스트 방법의 문제점**

어떤 서버로직을 테스트하기 위해서 앞단의 구현이 되어 있어야하며, 이는 많은 작업을 요구하기 때문에 배보다 배꼽이 큰 경우가 되어 버림.

**작은 단위의 테스트**

테스트는 작은 단위로 그 기능에 대해서 테스트해야한다.

**`단위 테스트`**

* 단위는 작을 수록 좋다.
* 이유 : 개발자가 설계하고 만든 코드를 원래의도한 대로 동작하는지를 개발자 스스로 빨리 확인하기 위함 &#x20;

**`자동수행 테스트 코드`**

* 테스트는 자동으로 수행되도록 코드를 만들어지는 것이 중요. `테스트에 대한 일련의 과정을 포함하게끔`
* 테스트용 클래스를 분리하여 작성하는 것이 낫다

**`지속적인 개선과 점진적인 개발을 위한 테스트`**

* 다 만든다음 장황한소스를 테스트를 하려고 할 때, 에러가 발생한다면.... 이것을 고치는데 아마 자포자기수준까지 나올 수 있다..
* 단위를 쪼개고 점진적으로 테스트를 해나가는 과정이 중요

#### 1.3 UserDaoTest의 문제점

* 수동확인 작업의 번거로움

  데이터 입력과 출력은 자동이지만, 그 **`결과의 검증은 사람이 수동작업으로 해야하는 단점`**
* 실행작업의 번거로움

  테스트해야할게 100개라면... main메서드도 100개 만들어야하고.... 파일도 많아질거고.. 일일히 100번 실행시키는건 번거롭다.. 이를 **`한 번에 실행 할 수 있는 것이 필요!`**

### 2 UserDaoTest 개선

#### 2.1 테스트 검증의 자동화

값 검증 로직까지 다 구현... 그랗쿤! 프레임워크 변화의 도입으로 인해 테스트를 해야할 경우 -> **이 테스트 코드 실행 한번이면 검증이 끝**\
자동화 시스템 만들어 두는 것이 중요. (결과 값 까지)

#### 2.2 테스트 의 효율적인 수행과 결과 관리

* JUnit 테스트로 전환
* 테스트 메소드 전환
  1. public으로 선언(**public만 허용함**)
  2. **@Test 어노테이션** 붇이기
* 검증 코드 전환

  if/else로 검정하던 코드 -> **`assertThat(테스트 대상값, is(예상 결과 값))`**
* 에러 및 예외 -> 실패 / 예상값이 다른 경우 -> 실패

### 3 개발자를 위한 테스팅 프레임워크 JUnit

Junit 프레임워크 찬양. 필수이다!

#### 3.1 JUnit 테스트 실행 방법

IDE에 내장된 JUnit 테스트를 사용하자

빌드 툴 !

* ant
* maven

#### 3.2 테스트 결과의 일관성

* 동일한 결과를 보장하는 테스트

  스프링에서 DB를 사용하는 코드를 테스트 하는 경우 편리한 테스트 방법

#### 3.3 포괄적인 테스트

다양하게 검증하는게 필요하다.

* `JUnit`은 **한 클래스에 여러 메서드를 정의하여 테스트**가 가능
* @Test : 1. public 메서드 2. void 반환형 3. 파라미터 x
* get 예외 조건에 대한 테스트

```java
@Test(expected=EmptyResultDataAccessException.class)
public void getUserFailure() throws SQLException {
    // 블라블라
}
```

**EmptyResultDataAccessException** 발생하면 성공, 아니면 실패

**`expected 속성`** 예외가 반드시 발생해야하는 경우를 테스트하고 싶을 때 유용

**포괄적인 테스트**

테스트를 작성할 때는 부정적인것부터 작성하자. 개발자는 긍정적인것 부터 작성하기 쉽상이기 때문이다.

#### 3.4 테스트가 이끄는 개발

**`TDD`**\
테스트 코드를 먼저 작성하여 실패하는 부분을 확인하여 개발하는 방식\
이렇게 하면 오류율을 극도로 줄일 수 있다

#### 3.5 테스트코드 개선

* **@Before**

  테스트 코드를 실행하기 전 실행하기 위함 -> 보통 공통메서드, 중복제거위해 사용
* **'@After'**

  테스트 코드 실행 후 실행되는 곳
* **테스트**

  클래스별로 `새로 생성된 인스턴스를 사용`

#### 4 스프링테스트 적용

**4.1 테스트를 위한 애플리케이션 컨텍스트 관리**

* **@BeforeClass / @AfterClass 스태틱 메소드**

  해당클래스에서 딱 한번만 실행 되도록 함

  ```java
      @BeforeClass
    public static void setUpBeforeClass() {
        // static method 이런식으로 
    }

    @AfterClass
    public static void tearDownAfterClass() {
        // static method 이런식으로
    }

    @Before
    public void setup() {
        // 매 테스트 코드가 실행될 때마다 실행됨 
        // @After도 마찬가지
    }
  ```

**4.2 DI와 테스트**

테스트 클래스에서도 DI는 가능 -> 기본싱글턴

* **`@DirtiesContext`**

  테스트 메소드에서 애플리케이션 컨텍스트의 구성이나 상태가 변경한다는 것을 테스트 컨텍스트 프레임워크에 알림 &#x20;

  애플리케이션 컨텍스트의 공유 허용x

**xml을 나눠서 사용하는 방법도 고려해볼 것** applicationContext.xml / test-applicationContext.xml -> 이 두개의 xml을 각각 사용하능 환경을 달리하여 구성.

```java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="/test-applicationContext.xml") // -> xml 설정을 바꾸면 설정 정보가 변경됨
public class AATest{
    // ...
}
```

#### 학습테스트로 배우는 스프링

**학습테스트**

내가 만든 코드가 아닌 `다른사람의 코드를 테스트`하면서 배우는 것.\
내가 짠 코드는 내가 생각한 방식대로만 생각하게 되므로.. 다른사람의 코드를 보고 테스트 함으로써\
참 테스트를 겪어보는 방식

**학습테스트의 장점 / 예제 / 버그테스트**

* 여러장점이 있다. 타소스를 보는.. 나보다 잘하는 사람코드를 볼 경우 도움이 됨
* 호환섬 검증
* 테스트 작성에 대한 좋은 훈련
* 새로운 기술을 공부하는 과정의 즐거움 (ex `스프링소스 테스트해보기 등`)
* 예제는 생략 책참고
