• 테스트끼리는 서로 의존이 없어야한다

    • JUnit 도 테스트끼리 병렬로 실행됨
  • 테스트 양이 많다고 무조건 좋은것은 아니다

  • 메서드가 테스트하기 힘들다는 것은 테스트가 주는 피드백이다

    • e.g. 픽스쳐 세팅이 힘들다
    • e.g. 테스트에서 뭘 검증해야 할 지 모르곘다
    • 어떻게하면 테스트하기 편할까 생각해보고, 그에 맞춰 구조를 변경(개선)해보는 것이 좋다
  • 테스트를 위해 메서드나 생성자가 추가로 생기는 경우가 있다

    • 이럴 경우 해당 메서드가 정말 필요한지 체크해 볼 필요는 있는데, 대부분 필요없지는 않은 메서드나 생성자이다
    • 해당 메서드를 추가하지 않아 테스트가 힘들어지는 것 보단 해당 메서드를 추가하는 것이 더 낫다
  • assert 는 경계값에 대해서만 하면 된다

  • exception 테스트는 하나의 부분만 테스트해야한다

    • exception 이 발생하면 어쩌피 아래는 진행 안되기 떄문이다
  • 설계 -> 테스트작성 -> 리팩토링의 싸이클을 짧게 자주 거쳐야한다

    • 빠른 피드백!
  • 모든것을 테스트하려고 하기보단, 일단 의존성이 낮은 도메인 객체부터 테스트를 작성해보자

  • 어떤 인풋이 들어갔을 때 어떤 아웃풋이 나온다가 테스트 작성의 첫 스텝이다

  • 테스트 코드를 믿고 다양한 연습(리팩토링 등)을 계속해봐야 한다

  • 기능 변경 시 테스트도 같이 많이 변경되면 의심해봐야 한다

    • 테스트가 너무 구현 레벨까지 파고들어 가있는 것은 아닌지?
  • 요구사항도 명세하지 않고, 설계도 해보지 않고 TDD 를 하려니 힘든것이다

    • TDD 를 하더라도 이 부분은 당연히 해야한다
  • 테스트를 한번에 작성할 것이 아니라, 테스트를 계속해서 확장해나가는 것이 좋다

  • 테스트 메서드는 이 테스트가 뭘 의도하는지 잘 드러내는 것이 중요하다

    • 소통에 좋은 영향을 미쳐야한다
  • 테스트 코드에 없는 코드를 미리 구현하는 것은 TDD 의 원칙에 어긋난다

  • 어떻게 하면 테스트 할수 있을까? 어떻게 하면 TDD 로 할수 있을까? 를 계속 생각하다보면 많은 인사이트를 얻을 수 있다

  • 테스트가 가능하도록 계속 쪼개는 연습을 해야한다

  • 작은 단계로 나아가는 연습을 계속 해야한다

    • 처음부터 큰 단계로 나아간다면, 작은 단계로 나아가는 법을 결코 알지 못한다
  • mockito, powermock 같은 라이브러리들은 테스트하기 어려운 구조도 테스트 가능하게 만들어버려서, 테스트로 나쁜 구조를 발견하기 어려워진다

    • 행위검증은 지양하는 것이 좋다
  • 인터페이스보단 구현체를 테스트하는 것이 좋다

  • Random, LocalDate.now() 와 같이 제어할 수 없는 값을 반환하는 기능은 테스트하기 힘들다

    • 외부에서 주입할 수 있게 메서드를 바꾸면 테스트가 용이하다
  • 기존 객체를 상속해서 mock 객체를 만들고, 이를 테스트에 사용할 수 있다

  • private 메서드를 테스트해야 할 상황이 나온다면 설계를 의심해봐야 한다

  • 테스트 우선순위

    1. 도메인 레벨 유닛 테스트
    2. Acceptance Test
    3. 서비스
    4. 레파지토리(여기부터는 굳이…)
      • mybatis를 쓰는 경우 조금은 다를 수 있다(쿼리에 로직이 있는 경우)
    • 1,2 2개만 해도 사실상 충분하지만, Acceptance Test 는 학습 레벨이 높다
  • AcceptanceTest 는 비즈니스 레벨에서 체크되어야 하는 부분을 테스트하는 것이다

    • 도메인 전문가와 상의해서 TC 를 만들수있다
    • 이 테스트가 많을 필요는 없다
  • AcceptanceTest 검증은 어떻게 할까?

    • 다른 api 를 호출하는것은 또 조금 그렇지 않나? 괜찮나?
    • 어쩄든 검증만 되면 되니까? 근데 의존이 생기지 않나?
  • AcceptanceTest 시 데이터베이스 등이 롤백되지 않더라도 테스트는 성공되어야 한다

    • database 롤백과 상관없이 그 api 는 성공해야 하기 떄문이다
  • AcceptanceTest 시 초기 fixture 세팅 정도는 import.sql 같은것으로 넣어도 된다

    • base 가 되는 user 라든지…
    • 사실… 안넣어야 할 이유가 굳이 있나?
  • DataJpaTest 는 내부에서 @Transactional(RequiredNew) 사용 시 롤백이 안될 수 있다