Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CHAPTER 1 효율적이고 체계적인 소프트웨어 테스트 #1

Open
moto6 opened this issue Aug 15, 2023 · 9 comments
Open

CHAPTER 1 효율적이고 체계적인 소프트웨어 테스트 #1

moto6 opened this issue Aug 15, 2023 · 9 comments

Comments

@moto6
Copy link
Owner

moto6 commented Aug 15, 2023

범위

  • CHAPTER 1 효율적이고 체계적인 소프트웨어 테스트 1 (~35p)

최소한 꼭 포함하면 좋을 주제

  • 효율적인 테스트란?
  • 테스트는 왜 이렇게 어려운가
  • 단위 테스트를 선호하는 이유

기간

  • ~ 23.08.26
@moto6 moto6 changed the title CHAPTER 1 효율적이고 체계적인 소프트웨어 테스트 1 CHAPTER 1 효율적이고 체계적인 소프트웨어 테스트 Aug 15, 2023
@moto6
Copy link
Owner Author

moto6 commented Aug 22, 2023

@70825
Copy link

70825 commented Aug 25, 2023

1. 테스트를 해야하는 이유

실력이 좋은 개발자라도 사람이기 때문에 실수를 하게 된다. 그래서 실수를 최대한 방지하기 위해 테스트 코드를 작성한다.
개발도 하면서 테스트를 작성하면 생산성이 느린 것처럼 보이지만, 운영 이후에 유지보수하는 시간까지 포함한다면 나중에 버그를 잡는 것보다 시간을 아낄 수 있다.

2. 효율적인 테스트란?

  • 테스트 주도 개발 (TDD)
  • 테스트 코드를 작성하는 것을 생각하면서 설계하기
  • 다양한 테스트 기법을 적용

이런 식으로 다양한 방법을 적용하며 개발할 때, 이상한 부분이 있으면 설계를 다시하거나, 버그를 발견해서 조기에 고치는게 제일 좋다.
특히 테스트 코드를 작성하지 않은 상태로 상용화를 하게 된다면 버그가 발생할 때마다 계속 코드를 고쳐야하므로 나중에는 스파게티 코드로 변하기 쉬울 것 같다. 그러면 유지보수하기 힘들어지고, 이미 유지보수하기 힘들어진 코드는 코드를 거리낌없이 작성하기 쉬우므로 악순환의 반복이 될 느낌? 그리고 그 유지보수의 고통은 내가 다른 곳으로 가지 않는 이상 고스란히 나에게로...

3. 소프트웨어 테스트 원칙

[완벽한 테스트는 불가능하다]
완벽을 고집하기 보다는 내가 생각할 수 있는 케이스에 대해서만 테스트를 하자
나중에 케이스가 생각나면 그때 추가해도 문제 없다

[버그는 다른 곳에 많이 발생하는 지점이 있으니 이 부분을 잘 테스트하기]
저 같은 경우엔 테스트 코드를 잘 작성해두어도 멀티스레드 환경에서만 발생하는 버그도 있어서 이걸 발견한 이후에야 해당 지점을 집중적으로 테스트 했던 기억이 납니다.

4. 단위 테스트를 선호하는 이유

  • 단위 테스트는 만들기도 쉽고, 피드백이 빨라서 선호

책에서는 단위테스트가 의존성이 필요한 서비스 로직은 Mock으로 단위 테스트하는 내용으로 보이는데, 저는 통합 테스트로 하는게 좋은 것 같다는 생각이 들었습니다.
세 달 전까지는 서비스 로직은 무조건 Mockito로 단위 테스트를 해왔는데, 그때 안드분들과 같이하는 협업 미션에서 안드분들에게 API를 제공하니 오류 투성이 코드라 슬랙에서 저를 많이 호출하시더라구요 😅 그때 테스트 커버리지를 위한 테스트였나라는 생각도 들었고, 그에 비해 통합테스트로 진행한 페어는 에러가 없었어서 이때 이후로 통합테스트로 해왔습니다.


저는 이번 챕터엔 적을 내용이 별로 없어서 블로그에 글을 안적고 여기에 적었는데, 생각보다 글이 길어진 것 같네요
테스트를 작성해보지 않은 사람들을 설득할 때 설명할만한 내용들이 1장에 있어서 좋은 것 같습니다!

@D0ri123
Copy link

D0ri123 commented Aug 26, 2023

https://baskinrobbins-seolhui-1.notion.site/1-1f0d538cca064e958ab19e4f9ede007d?pvs=4

@Lightieey
Copy link

1주차 스터디 정리 내용입니다!
이번 주에 일이 많아서 좀 늦어졌습니다 🥲
https://norgb.tistory.com/19

추가로, 읽으면서 다른 분들은 테스트 피라미드, 테스트 트로피, 테스트 허니콤 방식에 대해서 어떤 생각을 가지고 계시는지 궁금했습니다!
저는 아직 프로젝트를 하면서 제대로 테스트코드를 짜본 적이 없어서,
단위테스트나 통합테스트 중 뭐가 더 좋았다라고 말할 수 있을 만한 경험이 없어서요 😅

@brorica
Copy link

brorica commented Aug 27, 2023

TDD는 비용이 많이 든다?

  • 오히려 서비스 과정에서 발생하는 문제를 해결하는 비용이 더 크다.
    • 매출과 직결된 부분에서 장애가 발생했을 때의 손실된 매출(비용)과 개발 단계에서 해당 기능을 테스트하기 위해 사용된 비용을 생각하면 전자가 크다.
  • 테스트 작성도 결국은 많이 해봐야 한다.
    • 테스트 코드 작성하는 것을 숙달하면서 자신만의 방식을 만들어야 한다.

현직자 얘기를 들어보면 실제 프로젝트에선 기간 내에 완성해야 하기 때문에 테스트 코드 작성할 시간이 없고, 적용한다 해도 진짜 필요한 부분에서만 테스트를 가져간다고 한다.

또한, 비교적 자유롭다 여겨지는 스타트업도 초기엔 시장 선점을 빠르게 해야 해 테스트 코드가 더 빈약하단 얘기를 들었다.

정답은 TDD 개발 문화가 잘 정립된 회사로 가는 것이지만, 대부분은 이러지 않을 것이라 생각한다. 중요한 기능을 테스트할 자원이 부족한 경우, 팀을 설득하고 빠르게 테스트를 작성할 수 있는 능력이 요구될 것이다.

테스트는 버그가 없다는 걸 보여주는 게 아니다.

실제 서비스에선 우리가 알고리즘 문제 풀듯 입력과 상황들이 제한돼있지 않다.

따라서, 코너 케이스는 발생할 수 있다.

우리가 테스트 코드를 작성하는 것은 치명적인 버그가 발생할 경우의 수를 최대한 줄이는 것이다.

물론, 버그가 발생한다는 것 자체가 추가 비용이 발생하는 일이지만 대부분은 적은 비용으로도 해결할 문제가 될 것이다.

단위 테스트는 만능이 아니다.

단위 테스트에선 통과를 해도, 여러 의존성이 엮이는 통합 테스트에서 발생하는 문제도 있다.

실제로도 비즈니스 단에선 통과가 잘 되지만, 컨트롤러를 통해 입력을 거치는 부분에서 인증/인가 부분에서 기대하지 않은 결과가 나왔던 적이 있다.

결국에는 여러 단위 테스트를 묶어 하나의 통합 테스트를 만들 수 있는 능력도 필요하다.

@parkcoldroad
Copy link

1주차 정리 내용입니다!
https://velog.io/@coldstreet/%EC%9D%B4%ED%8E%99%ED%8B%B0%EB%B8%8C-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%ED%85%8C%EC%8A%A4%ED%8C%85chapter-1

@70825
Copy link

70825 commented Aug 27, 2023

추가로, 읽으면서 다른 분들은 테스트 피라미드, 테스트 트로피, 테스트 허니콤 방식에 대해서 어떤 생각을 가지고 계시는지 궁금했습니다!
저는 아직 프로젝트를 하면서 제대로 테스트코드를 짜본 적이 없어서,
단위테스트나 통합테스트 중 뭐가 더 좋았다라고 말할 수 있을 만한 경험이 없어서요 😅

@Lightieey
테스트 트로피는 아예 처음 들어서 논외로 치고, 테스트 피라미드, 테스트 허니콤중에 저는 테스트 피라미드가 아무리 노가다라도 프로젝트 규모가 커질수록 유리하고, 회사에 새롭게 오는 사람들에게 자세한 문서화 역할을 할 수 있으니까 더 좋다고 생각해요
그리고 단위 테스트, 통합 테스트 둘 다 중요하다고 생각하는데요. 대신 짧은 시간 안에 프로젝트를 진행하는데, 테스트 코드를 만들고 싶다면 허니콤 방식을 적용해서 통합테스트 위주로 만들고, 길게 가져가야하는 프로젝트라면 테스트 피라미드로 만드는게 더 효율적일 것 같아요

그리고 저는 팀프로젝트를 테스트 피라미드로 하고 있어요. 저도 너무 지칠 떄 테스트 코드 작성하면 거의 인간 톱니바퀴가 생각날 정도로 노가다라고 느끼는데, 이런 노가다 작업 때문에 과감하게 리팩터링도 가능하고, 사이드 이펙트도 최소화 시킨게 아닐까라고 행복회로 돌리면서 만드는 중입니다 ㅋㅋㅋ... 🫠

@brorica
Copy link

brorica commented Sep 4, 2023

2주차 정리 내용입니다!

2장의 내용은 우리가 당연히 알고는 있지만, 막상 하기엔 번거로운 내용인 명세 테스트를 어떻게 풀어갈지에 대해 설명돼있습니다.

명세 테스트를 만드는 법

  1. 요구사항 이해
    • 프로그램 or 메소드가 무엇을 수행해야 하는지 -> 비즈니스 규칙
    • 데이터 입력 추론
    • 데이터 출력 추론
  2. 테스트 코드 작성
    • 느낌에 따라 자유롭게 작성
  3. 입출력 테스트 구획 탐색 (문자열 기준)
    • NULL
    • 빈 문자열
    • 길이 1
    • 길이 1 초과
  4. 경계 분석하기
    • 내점: 조건이 참인 부분
    • 외점: 조건이 거짓인 부분
  5. 테스트 고도화

주의할 점

명세 테스트를 만드는 과정에서 우리는 실패에 대한 위험성을 이해해야 합니다.

실패가 발생할 때 가장 위험한 곳을 위주로 테스트 자원을 투자하고, 이 과정에서 필요없는 경우의 수를 제외 해야합니다.

하지만, 처음부터 최적화된 경우의 수를 생각할 수 없다고 생각합니다.

우리가 알고리즘 문제를 풀 때, 완전탐색을 통한 풀이부터 시작해 천천히 최적화 하는 것을 연습해야 하는 것처럼 명세 테스트를 작성할 때 전체 테스트의 경우의 수를 생각하고 이를 줄여보는 노력을 해야 합니다.

@parkmuhyeun
Copy link

1장은 블로그에 적을 정도까지의 깊이는 아닌 것 같아 여기다 적겠습니다!

개발자를 위한 효율적이 소프트웨어 테스트

어떻게 하면 개발 활동과 함께 효율적인 테스트를 수행할 수 있을까?

반복 프로세스의 효율적 테스트

  • TDD를 수행하다가 요구사항이 불명확하다고 생각하고 다시 요구사항 분석으로 되돌아가서 기댓값을 더 가다듬을 수도 있고
  • 기능의 반만 구현하고는 나머지를 구현하기 전에 테스트를 엄격하게 해보는게 더 생산적이라고 느낄 수도 있다
  • 자유롭게 앞뒤로 왔다 갔다 하며 적용하려는 기법의 순서를 바꾸어보고 자신에게 가장 적합하고 생산적인 방법을 찾자

테스트 비용

개발자에게 엄격한 테스트를 하도록 강요하는 것은 비용이 많이 든다고 생각할 수 있다.

  • 하지만, 상용 버전에서 발생하는 버그의 비용은 종종 예방하는 비용보다 훨씬 더 크다.
  • 버그를 많이 만들어내는 팀은 개발자가 버그를 만들고 나서 고객(또는 QA)이 버그를 발견하고 버그를 고치고 고객이 다시 다른 버그를 찾는 무한 루프에 시간을 많이 소모한다.
  • 테스트 케이스를 작성하는 데 익숙해지면 더 빨리 작성할 수 있다.

소프트웨어 테스트 원칙(테스트는 왜 이렇게 어려운가)

완벽한 테스트는 불가능

우리에게 프로그램을 완벽히 테스트 할 수 있는 자원은 없다. 자원이 무한정 있어도 불가능 할 수 있음.
-> 개발자는 무엇을 테스트할지 선택해야 한다. 우리의 목표는 항상 비용을 최소화하면서 최대한 많이 버그를 찾는 것이다.

가변성이 중요

소프트웨어 테스트에 은 탄환은 없다. 즉 가능한 버그를 모두 찾기 위해 항상 사용할 수 있는 기법은 존재하지 않는다. 다른 종류의 버그를 찾는 데는 다른 테스트 기법이 도움이 된다.

버그는 다른 곳에 비해 많이 발생하는 지점이 있다.

완벽한 테스트는 불가능하기 때문에 소프트웨어 테스터는 수행할 테스트에 우선순위를 매겨야한다. 몇몇 구성요소에는 다른 구성요소보다 더 많은 버그가 있기 때문에 훨씬 엄격한 테스트를 할 필요가 있다.

어떤 테스트를 하든지 결코 완벽하거나 충분하지 않다.

테스트가 얼마나 대량으로 진행되든지 간에 소프트웨어 시스템에 버그가 100% 존재하지 않는 다는 것을 보장할 수 없다.

테스트 피라미드와 집중해야 할 부분

실용적 테스트에 관해 이야기할 때 가장 먼저 결정해야 할 사항은 어느 수준으로 코드를 테스트하는가이다.

  • 단위 테스트
  • 통합 테스트
  • 시스템 테스트

단위 테스트

단위를 격리해서 테스트하는 것을 단위 테스트라고 한다. 단위 테스트는 시스템에서 작업 단위를 호출하는 자동화된 코드 조각이다. 작업 단위는 한 메서드, 한 클래스 또는 함께 동작하는 여러 클래스에 이를 수 있고, 검증 가능한 단 하나의 논리적 목표를 달성한다.

*단위 테스트는 외부 시스템(데이터베이스, 웹 서비스)에 의존하지 않는 작은 클래스 세트 또는 완전히 제어하지 않는 무언가를 테스트하는 것을 뜻한다.

장점

  • 빠르다.
  • 다루기 쉽다.
  • 작성하기 쉽다.

단점

  • 현실성이 떨어진다.
  • 잡을 수 없는 종류의 버그가 존재한다.

통합 테스트

통합 테스트는 우리의 코드와 외부 요소 간의 통합을 테스트해야 할 때 사용하는 테스트 수준이다. 시스템 전체를 테스트하는 대신 구성요소들의 상호작용에 초점을 맞춘다. A 구성요소가 X 메시지를 B 구성요소로 보내면 어떻게 되는지, 그것들이 여전히 올바로 동작하는지 테스트

시스템 테스트

소프트웨어를 더 실질적인 관점에서 바라보고 더 현실적인 테스트를 수행하려면 시스템이 가진 모든 데이터베이스, 프런트 엔드 앱 및 기타 구성요소를 포함한 소프트웨어 시스템을 실행해야 한다. 시스템 테스트의 명백한 이점은 테스트가 현실적이라는 것. 하지만 단위 테스트에 느리며, 작성하기 힘들다는 단점이 있다. 또는, 어떨 때는 통과하고 어떨 때는 실패하기도 하는 불안정한 경향을 가지고 있다.

각 테스트 수준을 언제 사용해야 할까?

우선 결론부터 말하자면 '상황에 따라 다르다'

image

저자는 일반적으로 단위 테스트를 사용하는 걸 좋아한다고 한다. 단위 테스트는 작성하기 쉽고, 빠르며, 제품 코드와 엮어서 만들 수 있다. 또한, 단위 테스트는 소프트웨어 개발자가 작업하는 방식(새로운 기능을 구현할 때 여러 개별 단위를 작성)과 잘 들어맞는다고 한다.
그리고 정말 중요한 부분에 대해서는 통합 테스트와 시스템 테스트를 사용한다.

각 수준에서 무엇을 테스트해야 할까?

소프트웨어 시스템의 알고리즘이나 단일 비즈니스 로직곽 관련된 단위에 대해서는 단위 테스트를 사용한다. 단위 테스트를 이용하면 입력 데이터를 완전히 통제할 수 있을 뿐 아니라 기대한 대로 동작했는지에 대한 완벽한 관찰 가능성을 확보할 수 있따.

통합 테스트는 대상 구성요소가 외부 구성요소(데이터베이스 또는 웹 서비스)와 상호작용 할 때마다 통합 테스트를 사용한다

시스템 테스트는 매우 비용이 많이 드는데(작성하기 어렵고 실행 속도가 느리다) 그래서 피라미드의 맨 위에 있다. 버그가 발생하면 시스템의 어느 부분에 가장 큰 영향을 끼칠까? 이러한 지점들이 몇 가지 시스템 테스트를 수행해야 하는 부분이다.

한 줄 요약: 상황에 맞는 테스트 전략을 선택하여 알잘딱깔센한 테스트 코드를 작성하자!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants