Skip to content

Latest commit

 

History

History
83 lines (52 loc) · 10.2 KB

심규창.md

File metadata and controls

83 lines (52 loc) · 10.2 KB

4주차 학습 PR

이번 주의 메인 테마는 테스트입니다. 단위 테스트와 테스트 툴인 JUnit5, AssertJ를 공부하고, 로또 미션에 충분한 테스트를 작성해주세요! 많은 예시 코드를 보시면 금방 감이 오실 겁니다!

  • 테스트 코드란? 테스트 코드는 왜 작성하는지? : 테스트 코드란 소프트웨어의 기능, 동작을 테스트할 때 사용하는 코드이다. 기본적으로 우리가 작성한 코드에서 예외 상황(결함, 작동하지 않는 경우 등등)을 확인하고 수정하는 과정에서 사용되기 때문에 매우 중요하다. 테스트 코드를 사용해 우리가 작성한 코드가 정상적인 결과를 도출하는 지를 확인하게 된다.

: 테스트 코드를 사용하는 이유는 코드의 품질 향상, 문서화, 리팩토링 등이 있다. 테스트 코드를 작성해 우리가 개발한 기능에 대해 발생할 수 있는 오류를 사전에 방지할 수 있고 신뢰할 수 있는 코드를 작성하도록 도와준다. 또한 테스트 코드를 통해 코드의 동작을 더 명확하게 할 수 있어 개발자 간의 커뮤니케이션에도 도움이 된다. 서비스를 지속하게 되면 기능의 확장이나 코드의 품질을 더 높이기 위해 리팩토링 작업이 필요하고 이전에 작성한 테스트 코드를 활용해 기능에 대해 안정적으로 확장 및 리팩토링이 가능하다.

: 하지만 이러한 테스트 코드를 작성하게 되면서 기존의 개발 시간보다 더 많은 시간이 소요될 수 있다. 기능의 추가, 변경, 확장 등이 많아질 수록 그에 해당하는 테스트 코드 또한 많아지기 때문에 유지보수 비용이 발생할 수 있다. 그리고 실제 요구사항보다 더 복잡하고 정교한 코드를 작성하는 오버 엔지니어링으로 이어질 수도 있다. 따라서 소프트웨어의 중요한 기능을 미리 파악하고 테스트해 최소한의 필요한 테스트 코드를 작성하는 것이 효율적이다.

: 테스트 코드는 단위 테스트, 통합 테스트, E2E(End to Edn Testing) 등 여러 종류의 코드가 있고 상황에 따라 유동적으로 테스트 코드를 작성하는 데 활용된다. 테스트 코드의 종류가 다양한 것은 테스트를 해야 하는 대상의 범위에 따라 달라지기 때문이다. <<<<<<<< HEAD:week04/심규창.md

테스트 종류

c4771aeca9f018128c276191fc97c6b2ae456cf8:심규창.md

  • 단위 테스트란?

: 우리가 코드를 작성할 때 일반적으로 사용되는 대표적인 테스트이다. 하나의 기능을 하는 코드(메서드, 클래스 등)가 우리가 예상한 결과를 도출하는 지 확인하는 과정이다. 단위 테스트의 대상은 정해져 있지 않지만 가장 작은 소프트웨어 단위의 동작을 확인하는 테스트이기 때문에 보통 메서드나 클래스 단위로 설정한다. 단위 테스트를 효율적으로 하기 위해서는 테스트하고자 하는 대상의 크기를 작게 설정해 최대한 간단하고 확인하기 쉽게 작성해야 한다. 개발 과정에서 테스트는 실제 소프트웨어의 구조와 구현이 어떤 방식인지 알기 때문에 개발자 관점에서 진행된다. 따라서 테스트를 명확하게 진행하기 위해서는 내부 코드에 대한 이해가 필수적이다.


통합 테스트(Integration Testing)

: 단위 테스트에서 결과를 확인한 각각의 기능을 결합해 상호작용이 정상적으로 이루어지는지 확인하는 테스트이다. 단위 테스트는 개발자 본인이 만든 코드에 대해 검증하기 때문에 외부에서 적용되는 부분에 대해서는 테스트가 어렵다. 통합 테스트는 이러한 외부적 요인(외부 라이브러리: 특정 기능을 구현하기 위해 사용하는 라이브러리 - 개발자가 직접 개발하지 않고 이미 개발된 기능을 가져와서 사용하는 용도)까지 묶어서 검증할 때 사용한다.

: 프론트엔드 웹에서 사용하는 데이터를 가져오기 위해 데이터베이스와 상호작용한다. 이 과정에서 통합 테스트는 데이터베이스와 프론트엔드 웹의 상호작용이 정상적으로 이루어 지는가 에 대한 확인을 한다.

E2E 테스트

: 실제 사용자의 시나리오를 테스트하면서 소프트웨어가 우리가 예상한 동작을 수행하는지 확인한다. 예를 들어 도서관 서비스를 개발한다면 고객이 회원을 등록하고 책을 고르고 대여 및 반납하는 과정을 처음부터 끝까지 테스트한다. 해당 테스트로 고객이 책을 대여하고 반납하는 과정이 정상적으로 동작하는 지를 확인할 수 있다.

Q. E2E 테스트 vs 인수 테스트(Acceptance Test)

: 인수 테스트는 소프트웨어의 내부 코드에 관심을 가지지 않는 블랙 박스 테스트이다. E2E 테스트는 실제 사용자 관점에서 테스트할 때 주로 사용하는 형식이다.

  • JUnit5, AssertJ란?

: JUnit은 자바를 위한 단위 테스트 프레임 워크이다. 테스트를 작성하고 실행하는 데 사용되는 오픈 소스 프레임 워크로 annotation(JUnit 4부터)을 제공해 보다 편리한 테스트를 가능하게 한다. 또한 테스트 결과를 확인하고 최적화된 코드를 유추하는 기능도 제공한다. Test 클래스를 작성하는 것으로 개발자에게 테스트에 대한 정보를 제공한다. 문자나 GUI 기반으로 실행되며 단정 메서드(Assert Method)로 테스트 케이스의 실행 결과(성공 - 녹색 / 실패 - 붉은색)를 판별한다.

: AssertJ는 JUnit 테스트 코드에 사용되는 라이브러리이다. 메서드 체이닝(메서드를 줄줄이 엮어 계속해서 사용하는 방법)을 지원해 더 가독성이 좋은 테스트 코드를 작성하게 도와준다. 그리고 테스트에 필요한 메서드(assert 메서드)를 지원해 편의성을 높여준다.

<<<<<<<< HEAD:week04/심규창.md

AssertMethod

c4771aeca9f018128c276191fc97c6b2ae456cf8:심규창.md

  • BDD란?

: 일반적으로 테스트 코드를 작성하기 위해서는 테스트를 진행할 코드가 있어야 한다고 생각하지만 TDD(Test Driven Development) 방식은 기능에 대한 테스트 코드를 먼저 작성하고 예외 상황에 대해 방지한 후에 실제 코드를 작성하는 과정이다. 작은 단위의 테스트 케이스를 작성하고 정상적으로 동작하는 코드를 추가하는 단계를 반복해 구현하는 방식이다. TDD 방식은 실패하는 테스트 코드 작성 → 테스트 코드를 성공시키기 위한 실제 코드 작성 → 중복 코드 제거 및 일반화 등의 리팩토링의 과정이 반복되는 구조이다. 설계 과정에서 프로그래밍의 목적과 어떤 것을 테스트할지 미리 정의하고 테스트 코드를 작성하는 과정에서 발생하는 예외 사항에 대해 테스트 케이스를 추가하고 개선한다.

: TDD를 활용한 개발은 확실한 모듈화를 얻을 수 있다. 이를 통해 코드를 작성하는 과정으로 유지보수와 확장이 쉽고 각 기능의 역할이 단순해지고 명확해지는 장점을 얻을 수 있다. 하지만 초기에 테스트 코드와 케이스를 작성하기 때문에 생산성이 저하된다는 단점 또한 존재한다. 그리고 기존에 사용하던 방식과 다른 구조로 진행되기 때문에 적응의 시간이 필요하기도 하다.

<<<<<<<< HEAD:week04/심규창.md

TDD

c4771aeca9f018128c276191fc97c6b2ae456cf8:심규창.md

: BDD(Behavior Driven Development)는 TDD를 근간으로 파생된 개발 방법이다. TDD에서는 테스트 과정에서 발생한 예외 사항 등을 테스트 케이스로 두고 진행하지만 BDD는 테스트 케이스 자체가 요구사항이 되도록 한다. 이미 작성된 요구사항이나 기획서가 있고 이에 맞춰 테스트 케이스를 작성해 유지보수 비용을 줄인다. BDD는 시나리오 기반으로 테스트 케이스를 작성하기 때문에 단위 테스트를 권장하지 않고 비 전문가가 보더라도 이해할 수 있을 정도로 쉽게 만들어야 한다. BDD에서 하나의 시나리오는 Given(시나리오 진행에 필요한 값 설정), When(시나리오를 진행하는 데 필요한 조건 명시), Then(시나리오를 완료했을 때 보장해야 하는 결과 명시) 구조를 기본 패턴으로 권장한다.

: TDD는 개발 코드를 완성하기 위한 목적이라면 BDD는 개발 결과에 대한 검증이 목적이다.

  • private method test

: private method는 따로 테스트를 진행하지 않는다. 보통 public 메서드에서 내부 로직을 따로 진행할 때 private method를 구현하기 때문에 public method에 대한 테스트가 이루어지기 때문이다. private method는 기본적으로 외부에서 접근이 불가능하기 때문에 private 메서드와 변수에 대한 접근 방법이 추가로 필요하다. 따라서 private method를 꼭 테스트해야 되는 상황이라면 Reflection을 사용해 접근한다. Java Reflection을 활용해 클래스, 필드, 메서드를 찾아 임시적으로 접근 가능하게 할 수 있다.

  • @ParameterizedTest

: 같은 기능을 하는 테스트 코드의 파라미터만 다른 경우 Parameterized Test annotation을 통해 중복 코드를 줄일 수 있다. 해당 annotation을 추가하는 것을 제외하면 다른 테스트 코드와 동일하게 구성된다. 각 테스트 코드마다 하나의 파라미터(private type, null and enpty value, enum) 만을 전달해 사용한다. 기본적인 파라미터를 제외하고 복잡한 object를 전달할 때는 @MethodSource annotation을 활용한다.

<<<<<<<< HEAD:week04/심규창.md

@Parameterized

c4771aeca9f018128c276191fc97c6b2ae456cf8:심규창.md