728x90

복잡한 엔터프라이즈 애플리케이션을 효과적으로 개발하기 위해서는

객체지향과 테스트 기술을 유연하게 다룰 줄 알아야한다.

 

코드가 정확히 동작하는지를 확인하며 코드나 설계의 결함을 파악하여 제거해가는
디버깅을 통해 최종적으로 모든 결함을 제거하여 개발한 코드를 확신할 수 있게 해주는 작업

 

객체지향 기술을 통해 확장과 변화를 고려한 프로그래밍을 할 수 있다면

테스트를 통해 이러한 프로그래밍 결과를 검증할 수 있게 해준다.

기존 테스트 방식의 문제점

기존의 웹 프로그램에서 테스트를 하기 위해서는 해당 기능과 관련된 모든 기능들을

약식으로라도 구현해두고 웹 화면을 띄워 입출력을 실행한 후 관련 기능들이

모두 제대로 동작하는지 일일히 확인을 해야했다.

 

일부 기능만 테스트하기 위한 작업치고는 해야할 일이 너무 많을 뿐만 아니라

다수의 코드가 참여하는 테스트이기 때문에 어떤 기능에서 오류가 발생했는지,

어떤 요인들이 영향을 미치는지 식별하기가 쉽지 않다.

효율적으로 테스트 하기

작은 단위부터 시작하기 : 단위 테스트

위와 같은 문제들을 방지하기 위해서는 테스트하기 위한 대상에만 집중하는 것이 좋고

이를 위해서는 가능하면 작은 단위로, 관심사가 같은 것끼리 하는 것이 바람직하다.

 

이러한 작은 단위의 코드에 대해 수행하는 것은 단위 테스트라고 하며

여기서의 단위는 하나의 관심에 집중하여 효율적으로 테스트할 수 있는 범위이다.

 

단위 테스트는 주로 개발자가 만든 코드를 스스로 즉각적으로 확인하기 위해 사용되는데

이렇게 한 단위의 개발을 마칠 때마다 단위 테스트를 진행하면 해당 단위에 대해서는

완벽하게 알 수 있기 때문에 나중에 몰아서 긴 테스트를 하는 경우보다도

예외와 오류를 찾고 수정하기 훨씬 편해진다.

자동수행 테스트 코드

기존 웹 프로그램 테스트에서는 테스트를 수행하기 위해 웹 페이지를 실행한 후에

직접 값을 입력하고 전송하는 과정을 거쳐야 했지만

코드를 통해서 자동으로 테스트 데이터를 제공하면 이러한 번거로움이 줄어든다.

 

번거로운 작업이 없고 테스트를 빠르게 실행할 수 있기 때문에 자주 반복할 수 있다.

테스트는 지속적이고 점진적으로 하기

애플리케이션의 모든 로직을 다 작성한 후에 테스트를 시작하려하면

엄청난 양의 오류가 발생할 것이고 이를 그때 몰아서 찾으려하면 머리 아픈 작업이 될 것이다.

 

단위 테스트를 지속적으로 활용하여 점진적으로 코드의 완성도를 높여 나가는 것이 좋은데

속도가 느리다고 생각할 수도 있지만 이미 개발한 코드에 확신을 갖게 되고

나중에 몰아서 오류를 수정하는 것보다 훨씬 더 적은 시간으로 개발이 가능하다.

기존 테스트 코드의 문제점

public static void main(String[] args) throws ClassNotFoundException, SQLException {
    //user 추가하는 코드

    //user가 제대로 추가되었는지 확인하는 코드
    User user2 = dao.get(user.getId());
    System.out.println(user2.getName());
    System.out.println(user2.getPassword());

    System.out.println(user2.getId());
}

직접 눈으로 결과를 확인해야 함

콘솔창에 출력된 테스트 코드의 실행결과가 자신이 예상한 결과와 일치하는지

개발자가 직접 눈으로 콘솔창을 봐가며 잘못된 부분이 있는지 확인해야 한다.

일일히 테스트를 실행해야 함

테스트를 할 때마다 메인 메서드를 계속 추가한다면 상당히 번거롭고 난잡해진다.

문제점 개선하기

if (!user.getName().equals(user2.getName())) {
	//이름 테스트 실패 출력
} else if (!user.getName().equals(user2.getName())) {
	//비밀번호 테스트 실패 출력
} else {
	//테스트 성공 출력
}

코드로 검증하기

기존 테스트 코드에서 직접 눈으로 결과를 확인하교 비교해야하는 단점은

테스트 수행뿐만 아니라 결과를 검증하는 코드까지 작성하여 검증을 자동화하면 해결된다.

 

테스트의 실패는 테스트 중에 발생하는 런타임 에러결과값이 다른 에러가 있고

런타임 에러는 콘솔창에 에러 메시지가 출력되기 때문에 확인이 쉽지만

예상과 결과값이 다른 경우는 별도의 확인 작업이 필요하다.

 

분기별로 테스트의 결과를 처리해주는 등의 방법으로 결과를 직접 확인하지 않고

코드를 통해서 테스트의 성공 여부만 확인하면 된다.

테스트를 더 편하게 사용하기

메인 메서드로 만드는 테스트는 테스트 코드로서의 기능은 수행하지만

개발자들은 항상 더욱 편리한 것을 필요로 한다.

 

이를 위해서 일정한 패턴의 테스트를 생성하고, 많은 테스트를 간단히 실행하고,

종합적인 결과를 보거나 실패 원인을 빠르게 찾을 수 있는 테스트 지원 도구가 존재한다.

JUnit 프레임워크

이름에서 부터 알 수 있듯이 자바의 단위 테스트 지원 프레임워크다.

 

프레임워크의 기본 동작 원리는 IoC이기 때문에 

오브젝트를 생성하고 실행하는 일은 모두 프레임워크가 처리할 것이고

개발자는 테스트를 위해 main 메서드나 오브젝트 같은 것을 직접

만들어서 실행시키는 수고를 할 필요가 없다.

테스트 메서드로 전환하기

테스트를 메인 메서드를 통해 실행한다는 것은 제어권을 직접 가진다는 의미

이러한 제어권을 프레임워크로 넘겨줘야 한다.

@Test 
public void andAndGet() throws SQLException {
    ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml");
    UserDao dao = context.getBean("userDao", UserDao.class);

    //유저 정보 추가를 위한 정보 작성 코드

    dao.add(user);
}

@Test 어노테이션을 통해 테스트 메서드임을 알려주고 테스트 내용을 작성하면 되는데

테스트 메서드는 접근제어자를 반드시 public으로 선언해야 한다.

 

기존에는 조건문으로 테스트 데이터들을 비교하여 결과를 만들었다면

JUnit이 제공하는 assertThat 메서드를 사용하여 대체할 수 있다.

@Test 
public void andAndGet() throws SQLException {
    //유저 정보 추가 코드 생략
    User user2 = dao.get(user.getId());

    assertThat(user2.getName(), is(user.getName()));
    assertThat(user2.getPassword(), is(user.getPassword()));
}

 

assertThat 메서드는 첫 번째 파라미터 값이 두 번째 파라미터 값과 일치하는지 비교하여

일치하면 계속 진행(continue)하고 일치하지 않으면 테스트를 실패하게 한다.

테스트 실행하기

JUnit 프레임워크로 만든 테스트 코드도 마찬가지로 자바 프로그램이기 때문에

따로 메인 메서드를 통해 실행을 시켜줘야 실행이 된다.

public static void main(String[] args) {
	JUnit.main("@Test 메서드를 가진 클래스");
}

@Test 어노테이션이 적용된 메서드를 가진 클래스를 사용하여 실행시킨다.

'Back-End > Spring' 카테고리의 다른 글

스프링에 테스트 적용하기  (0) 2023.06.08
JUnit 자세히 알아보기  (0) 2023.06.08
XML 설정  (0) 2023.06.07
DI(Dependency Injection)  (0) 2023.06.07
싱글톤 레지스트리 / 오브젝트 스코프  (0) 2023.06.07

+ Recent posts