모든 단계에 대해 별도의 테스트 방법을 사용하는 것이 좋습니다?


10

REST API를 테스트하고 있습니다. JSON 구조를 반환한다고 가정 해 봅시다. 서버를 테스트하는 가장 좋은 방법은 무엇입니까? 각 테스트 단계는 이전의 모든 성공한 경우에만 성공할 수 있습니다.

구조 A : 모든 것을 한 번에 테스트

- Test method 1:
    - make server request
    - assert http response code was 200
    - assert returned file is not empty
    - assert returned file has valid JSON syntax
    - assert returned JSON contains key X

이것이 가장 좋은 해결책 인 것 같습니다.

장점 :

  • 하나의 서버 요청
  • "서버가 X 키로 JSON을 반환합니까?"

구조 B : 각 테스트에 점차적으로 어설 션 추가

 - Test method 1:
     - make server request
     - assert http response code was 200
 - Test method 2:
     - make server request
     - assert returned file is not empty
 - Test method 3:
     - make server request
     - assert returned file has valid JSON syntax
 - Test method 4:
     - make server request
     - assert returned JSON contains key X

이것이 내가 시작한 방법이며 모든 방법 이 가지만을 테스트하기 때문에 이것이 더 좋은 분리를 만들기 때문에 이것이 갈 길이되어야한다고 확신했습니다 . 그러나 지금은 이것들이 단위 테스트가 아니기 때문에 분리가 적절하지 않으며 행동을 전체적으로 테스트해야한다고 생각합니다.

구조 C : 요청을 한 번 만들고 캐시 된 응답에 대해 별도의 테스트 방법을 실행

- make server request and cache it (allow read-only access)

 - Test method 1:
     - assert http response code was 200 on cached server request
 - Test method 2:
     - assert returned file is not empty on cached server request
 - Test method 3:
     - assert returned file has valid JSON syntax on cached server request
 - Test method 4:
     - assert returned JSON contains key X on cached server request

장점 :

  • 반복되는 (비싼) 서버 요청이 없음
  • 여전히 단일 어설 션 테스트 방법이 있습니다

가장 합리적인 테스트 구조는 무엇입니까?


기존 답변을 무효화하는 방식으로 질문 변경을 중단하십시오! 감사.
Doc Brown

불편을 끼쳐 드려 죄송하지만 다른 방법으로 제안 하시겠습니까?
mrplow

먼저 그러한 방식으로 질문을 바꿔야한다면 두 번 생각하십시오. 실제로 일부 답변을 무효화하는 무언가를 추가해야한다고 생각하는 경우 답변 아래에 의견을 남겨 텍스트에 무언가를 변경하거나 추가 할 것인지 묻는 질문을 남기면 모든 작성자에게 알릴 수 있습니다.
Doc Brown

2
실제로 질문이 변경되면 답변 작성자에게 통보한다고 가정했습니다. 그렇기 때문에 주제를 벗어난 주석을 스팸으로 만들고 싶지 않습니다. 나는 나중에 저자에게 알릴 것입니다. 내 질문에 답변 해 주셔서 감사합니다.
mrplow

답변:


3

모범 사례에는 항상 목적과 그 이유가 있습니다. 디자인에서 이러한 이유를 고려하는 것이 좋습니다. 특히 이러한 모범 사례를 따르는 방법과 방법을 결정하려는 경우 특히 그렇습니다.

이 경우 모든 테스트 테스트를 단일 항목으로 만드는 주된 이유는 첫 번째 테스트가 실패하면 두 번째 테스트는 테스트되지 않는다는 것입니다. 너무 많은 의견 제출자들은 모든 것을 가능한 한 작은 비트로 나누고 가능한 한 많은 비트를 최대한 많이 감싸는 데 장점을 느끼는 것처럼 보이므로 모든 테스트에는 단일 어설 션이 포함되어야한다는 아이디어가 탄생했습니다.

이것을 맹목적으로 따르지 마십시오. 모든 테스트가 한 가지를 테스트해야하더라도 각 "사물"의 크기를 결정하는 데 약간의 생각을해야하며 그렇게하려면 모든 테스트가 한 가지를 테스트하기를 원하는 이유 를 명심해야합니다. 첫 번째 버그는 두 번째 것을 테스트하지 않은 채로 두지 않습니다.

그래서 당신은 스스로에게 물어볼 필요가 있습니다- "이 보증이 정말로 필요합니까?"

첫 번째 테스트 사례에 버그가 있다고 가정 해 봅시다. HTTP 응답 코드는 그렇지 않습니다 200. 따라서 코드에서 해킹을 시작하고 필요한 응답 코드를 얻지 못한 이유를 파악하고 문제를 해결하십시오. 그리고 지금 무엇?

  • 테스트를 수동으로 다시 실행하면 수정 프로그램으로 문제가 해결되었는지 확인하려면 첫 번째 오류로 인해 숨겨진 다른 문제가 발생해야합니다.
  • 수동으로 실행하지 않으면 (아마 시간이 오래 걸리기 때문에) 자동화 된 테스트 서버가 모든 것을 실행할 때까지 수정을 푸시하면 다른 테스트에 다른 어설 션을 추가 할 수 있습니다. 이 경우주기는 매우 길기 때문에 각주기마다 많은 버그를 발견하는 것이 좋습니다.

고려해야 할 사항이 몇 가지 더 있습니다.

어설 션 종속성

설명 한 테스트는 단지 예일 뿐이며 실제 테스트는 아마도 더 복잡 할 것입니다. 그래서 내가 말하려는 것은 실제 테스트에서 큰 힘으로 유효하지 않을 수도 있지만 여전히 다소 효과적 일 수 있습니다. 그것을 고려하고 싶을 수도 있습니다.

JSON 형식으로 응답을 리턴하는 REST 서비스 (또는 기타 HTTP 프로토콜)가있는 경우 일반적으로 일반 오브젝트를 리턴하는 일반 메소드와 같은 REST 메소드를 사용할 수있는 간단한 클라이언트 클래스를 작성합니다. 클라이언트가 작동하는지 확인하기 위해 별도의 테스트가 있다고 가정하면 처음 3 개의 어설 션을 버리고 4 개만 유지했을 것입니다!

왜?

  • 첫 번째 어설 션은 중복입니다. HTTP 응답 코드가 200이 아닌 경우 클라이언트 클래스에서 예외를 발생시켜야합니다.
  • 두 번째 어설 션은 중복됩니다. 응답이 비어 있으면 결과 개체가 null이거나 빈 개체를 다른 식으로 표시하므로 키 X를 넣을 위치가 없습니다.
  • 세 번째 어설 션은 중복입니다. JSON이 유효하지 않으면 구문 분석 할 때 예외가 발생합니다.

따라서 모든 테스트를 실행할 필요는 없습니다. 네 번째 테스트 만 실행하면됩니다. 버그 중 첫 번째 세 가지가 감지하려고하면 실제 예외를 얻기 전에 적절한 예외로 테스트가 실패합니다.

보고서를 어떻게 받으시겠습니까?

테스트 서버에서 이메일을받지 않고 QA 부서에서 테스트를 실행하고 실패한 테스트를 통지한다고 가정합니다.

QA의 잭이 문을 두드립니다. 그는 첫 번째 테스트 방법이 실패했으며 REST 메서드가 잘못된 응답 코드를 반환했다고 말합니다. 당신은 그에게 감사하고 근본 원인을 찾기 시작합니다.

그런 다음 QA에서 Jen에게 와서 세 번째 테스트 방법이 실패했다고 말하십시오. REST 메소드는 응답 본문에서 유효한 JSON을 리턴하지 않았습니다. 당신은 이미 그 방법을보고 있다고 말하고, 잘못된 종료 코드를 반환하게 한 것과 동일한 것으로 인해 유효한 JSON이 아닌 것을 반환하고 예외 스택 추적과 더 비슷하다고 생각합니다.

다시 작동하지만 QA의 Jim이 도착하여 네 번째 테스트 방법이 실패했으며 응답에 X 키가 없습니다.

컴퓨터 화면이 없을 때 코드를보기가 어렵 기 때문에 이유를 찾을 수도 없습니다. 짐이 충분히 빠르면 시간을 피할 수 있었을 것입니다 ...

테스트 서버에서 이메일은 여전히 해고하기 쉽게,하지만 - 할 수 없습니다 당신은 오히려 단지 통보에 ONCE 뭔가가 관련 테스트 로그 자신의 시험 방법 및 얼굴로 잘못?


3

동일한 매개 변수로 서버 요청을하는 것이 항상 동일하게 작동한다고 가정 할 수있는 경우, 방법 B는 거의 의미가 없습니다. 한 번의 호출로 충분할 때 동일한 응답 데이터를 네 번 얻기 위해 동일한 방법을 네 번 호출해야하는 이유는 무엇입니까?

안전하게 추측 할 수없고 테스트의 일부로 만들려면 테스트 A를 여러 번 실행하는 것이 좋습니다.

B가 이익을 얻을 수있는 유일한 가상 상황은 테스트 프레임 워크가 명시 적 테스트 방법 만 켜고 끌 수 있고 테스트의 개별 단계 에서이 작업을 수행해야 할 때입니다.

대안 C는 A와 B에 대해 위에서 언급 한 이점 중 하나를 결합한 것으로 보입니다. 테스트 프레임 워크에서 B보다 많은 오버 헤드없이 코드를 쉽게 구성 할 수 있다면 이것이 가능한 방법입니다. 그러나 이것은 A에 약간의 복잡성을 추가하므로 개별 테스트를 켜고 끄고 싶을 때만 사용하고 YAGNI 원칙을 적용하고 가장 간단한 솔루션 (A)을 고수합니다.

TLDR : 모든 어설 션을 항상 한 번의 테스트로 실행하려면 A로 시작하고 개별 어설트에 대해 외부에서보다 쉽게 ​​제어 할 수 있어야하는 경우 C로 리 팩터하십시오.


0

다른 코드와 마찬가지로 조기 최적화를 피하십시오. 먼저 테스트를 작성하여 읽기 쉽고 유지 관리하기 쉽습니다. 테스트가 너무 느리게 시작되면 최적화하십시오. 아주 간단한 예에서 A와 B는 읽기 쉽고 유지 관리가 쉬워서 너무 느리게 (구조 B) 또는 너무 복잡해질 때까지 (구조 A) 원하는 것을 선택하십시오.

서버가 상태 비 저장 인 경우 실제 응답과 예상 응답을 비교하여 전체 메시지를 한 번에 확인하여 최적화 할 수 있습니다. 분명히 그것은 가독성을 희생시킬 것입니다.

서버가 상태가 가득 차서 서버를 테스트 상태로 만들기 위해 느린 API 호출을 여러 번해야하는 경우 다른 방법을 사용하거나 테스트를 실행하는 데 몇 분이 걸릴 수 있습니다. 예를 들어 데이터베이스 업데이트를 실행하여 테스트 데이터베이스에 데이터를 주입하여 테스트하기에 적합한 상태의 객체를 신속하게 얻을 수 있습니다. 테스트는 빠르고 읽기 쉽지만 유지하기가 더 어렵습니다. 또는 API 앞에 파사드를 작성하여 여러 API 호출이 테스트중인 비즈니스 프로세스와 더 일치하는 단일 API 호출이 될 수 있습니다.


0

테스트는 처음부터 시작하여 다른 테스트에 대한 영향을 피합니다. 또한 무작위 순서로 테스트를 실행할 수 있습니다.
따라서 C 길은 받아 들여서는 안됩니다.


코드를 작성할 때 (또는 다른 것을 만들 때) 항상 "왜 그런 연습이 있습니까?"
왜 모든 것에 대해 다른 테스트가 필요하다고 말합니까?

필요한 경우 두 가지가 있습니다.

  1. "각 테스트 단계는 이전의 모든 성공한 경우에만 성공할 수 있습니다"에 의존 할 수없는 경우
  2. 테스트에 설명적인 주장 메시지가없는 경우

이러한 경우에 직면하는 데는 두 가지 이유가 있습니다.

  1. "이전 단계가 모두 성공한 경우에만 각 테스트 단계에서 성공할 수 있습니다"는 실제로 제품 기능에 적용 할 수 없습니다
  2. 경험이나 시간 부족 또는 압도적 인 제품 복잡성으로 인해 제품에 대한 지식이 충분하지 않습니다.

어떤 이유로 든이 이유 중 적어도 하나를 선언 할 수 없다면 맹목적으로 B 구조를 취하십시오 .


그렇지 않으면 (여기에 오기를 바랍니다) A 를 선택하십시오 .


또한 Software Quality Assurance & Testing Stackexchange 사이트 에서이 질문을 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.