외부 API를 쿼리하는 것이 유일한 목적이지만 API가 복잡한 쿼리 구문을 사용하는 함수를 어떻게 테스트합니까?


16

유일한 실제 논리는 외부 API의 쿼리 구문에 있습니다. API를 쿼리하는지 여부를 테스트하고 싶지 않고 올바른 데이터가 반환되는 방식으로 쿼리하는지 테스트하고 싶습니다. 예를 들어 일부 의사 코드는 다음과 같습니다.

function retrieve_related_data(id)
{
  query = "[potentially long, syntactically complex query that
            uses param id to get some data]";
  results = api_wrapper.query(query);
  return results;
}

API를 구성한보다 구체적인 예 :

function retrieveLifeSupportingObjectsWithinRegion(id)
{
  query = "
    within region(" + id + ") as r
    find objects matching hydration>0 and temp_range has 75
    send name, id, relative(position, r)        
  ";
  results = astronomicalObjectApiWrapper.query(query);
  return results;
}

쿼리는 API에 대한 구문 사용자 정의이며 복잡하며 동일하거나 유사한 결과를 얻는 여러 가지 방법이 있습니다. 이 기능의 목적은 식별 된 데이터를 얻는 것이 아니라 식별 된 id데이터와의 퍼지 관계를 기반으로 다른 데이터의 하위 집합을 찾는 것 id입니다. 다른 요구 사항은 id시스템에 관계없이 항상 동일 하지만 시스템이 수정되면 시간이 지남에 따라 변경 될 수 있습니다. 예를 들어, 예제 api가 중력 정보에 대한 지원을 추가 한 경우 결과를 구체화하기 위해 중력을 사용하도록 쿼리를 변경하려고 할 수 있습니다. 또는 온도 범위를 확인하는 더 효율적인 방법을 제안했지만 결과는 변경되지 않습니다.

테스트하려는 것은 주어진 입력에 id대해 올바른 데이터 세트가 반환 된다는 것입니다 . 누군가가 쿼리를 엉망으로 만들면 더 이상 올바른 데이터를 반환하지 않으므로 쿼리를 엉망으로 id만들지 만 사람들이 쿼리를 수정하지 않고도 수정 할 수 있기를 원합니다. 시험.

내가 고려한 옵션 :

  1. API를 스텁 할 수는 있지만 너무 간단합니다 ( id질의가 쿼리에 있는지 확인한 다음 예상 데이터 세트가있는 경우 또는 예기치 않은 세트가 아닌 경우)를 반환하고 너무 취약합니다 (쿼리 문자열이 함수에있는 내용) 또는 너무 복잡한 (사용 된 쿼리가 구문 상 올바른지 확인 하고 올바른 데이터가 리턴 되는지 확인 )

  2. 실제 API에 쿼리를 제출할 수는 있지만 테스트 시스템의 제어 범위를 벗어나 외부 시스템의 데이터가 변경되면 시간이 지남에 따라 예상 결과가 변경 될 수 있습니다.

  3. 나는 가지고있는 데이터를 제어하기 위해 실제 API의 테스트 설치를 설정할 수 있지만 많은 노력이 필요합니다.

나는 2 번에 기대어 자주 실행되지 않는 통합 테스트를 더 만들고 외부 시스템의 데이터 변경이 테스트를 중단하는 빈도를 확인합니다. 지금은 이것이 가장 간단하다고 생각하지만, 내가 생각하지 않는 대안이 있거나이 문제를 해결할 더 좋은 방법이 있는지 궁금합니다. 모든 조언을 부탁드립니다.


나는 이것을 단위 테스트라고 생각했지만 실제로 통합 테스트 또는 저수준 수용 테스트입니까?
Joshua Coady

2
읽기 전용 API입니까? 또는, 당신은 할 수 있습니다 쓰기 당신이 안정적으로 확인할 수있는 데이터 읽기 에를?
svidgen

이 질문은 "내 SQL (= 복잡한 구문)이 올바른 데이터를 반환하는지 테스트하는 방법"과 다른가? 데이터베이스를 사용하면 일반적으로 crud-sql-syntax를 테스트하는 몇 가지 통합 테스트와 비즈니스 로직을 검증하기위한 모의 저장소 fasade
k3b

답변:


7

외부 API 응답의 유효성을 검사하면 함수를 테스트하는 것처럼 보이지만 실제로는 그렇지 않습니다. 어쨌든 외부 API와 API가 실행되는 환경을 테스트하고 있습니다.

테스트는 제 3자가 작성한 코드가 아니라 우리가 작성한 코드의 예상 된 동작을 보장하기 위해 해결되어야합니다.

어느 정도까지는 우리가 의존하는 API와 라이브러리의 적절한 기능을 신뢰해야합니다. 예를 들어, 일반적으로 구현하는 프레임 워크 구성 요소는 테스트하지 않습니다.

내가 왜 그렇게 말합니까?

테스트하려는 것은 주어진 입력 ID에 대해 올바른 데이터 세트가 반환된다는 것입니다

여기서 무엇을 테스트할까요? 말씀 드린 바와 같이, 데이터와 정확성은 우리가 통제 할 수 없으므로 테스트 단계의 성공을 통제 할 수없는 외부 에이전트로 제한합니다. 이러한 테스트는 비결정적이고 확실 하게 될 수있는 후보 입니다. 빌딩 파이프 라인에서 이러한 종류의 테스트를 원하지 않습니다 .

다른 관심사는 계약을 확인하는 것입니다. 릴리스 또는 배포 전에 통합이 여전히 예상대로 작동하는지 확인하기 위해 계약 테스트 1 이 매우 유용하다는 것을 알았습니다 .

누군가가 쿼리를 엉망으로 만들면 더 이상 ID를 기반으로 올바른 데이터를 반환하지 않도록 실패하고 있습니다.

쿼리가 정상이지만 API의 버그로 인해 데이터가 잘못된 경우 어떻게됩니까? 데이터 만 통제 할 수있는 것은 아닙니다. 논리도 마찬가지입니다.

기능 테스트 또는 엔드 투 엔드 테스트를 구현하면 도움이 될 수 있습니다. API가 잘못된 데이터를 반환하면 예기치 않은 동작 및 출력이 발생할 수 있도록 특정 실행 경로의 유효성을 검사하기 위해 이러한 테스트를 처리 할 수 ​​있습니다. 반면에 쿼리의 형식이 잘못된 경우 API에서 오류가 발생할 것으로 예상합니다.

그러나 사람들이 테스트를 수정하지 않고도 쿼리를 수정하기 위해 쿼리를 수정할 수 있기를 바랍니다.

그런 목적으로 도구를 구현하는 것이 좋습니다. 다음과 같이 간단 할 수 있습니다.

  • 테스트로 실행되지만 테스트 계획에 속하지 않는 클래스
  • 쉘 스크립트 + 컬

아니면 더 정교한 것. 예를 들어 독립형 클라이언트입니다.

어쨌든 문제의 함수는 두 가지 종류의 테스트에 가치가 있습니다.

  • 단위 테스트. 말했듯이 외부 API를 스텁해야하지만 단위 테스트의 전체 목적입니다. 의존성을 분리하는 코드 테스트.

  • 통합 테스트. 코드가 올바른 요청을 보낼뿐만 아니라 응답 내용, 오류, 리디렉션 등을 올바르게 처리하는지 확인하십시오. 이러한 모든 경우에 대해 테스트를 수행하고 데이터를 테스트하지 마십시오 .

참고 사항 : 귀하의 질문은 응용 프로그램의 SQL 문을 어떻게 테스트합니까?

관련 질문 :


1 :이 주제 에 관한 @DocBrown의 답변에 관심이있을 것입니다


"문제 (IMO)는 외부 API 테스트에 너무 집중하고 있다는 것입니다." -asker가 외부 API 테스트에 관심이 있음을 나타내는 내용이 없습니다. 또한, "외부 API 스텁"이라고 말하지만, 어 커가 "너무 단순"옵션, "너틀 취성"옵션, "너무 복잡한"옵션 또는 네 번째 옵션 중 어느 것을 사용해야하는지에 대한 제안이 있습니까?
Tanner Swett

OP 질문은 외부 API를 호출하는 함수를 테스트하는 방법을 묻습니다. 그러나 그의 의심을 읽으면 쿼리와 결과 테스트에 너무 중점을 둔 것으로 보입니다. 나는 4 가지 제안을했다 : (1) API를 테스트하지 마십시오. (2) 통합 테스트를 쿼리를 시작하기위한 워크 벤치로 사용하지 마십시오. 대신 도구를 만드십시오. (3) 주요 질문으로 돌아가서 단일 및 통합 테스트를 수행하십시오. 그러나 API 응답의 내용을 확인하지는 않습니다. (4) 프로젝트 관리자에게 프로젝트의 테스트 계획의 일부로 외부 API의 테스트 스위트를 만들어야하는지 물어보십시오.
Laiv

1
쿼리 자체는 "우리가 작성한 코드"로 간주합니다. 최종 목표는 자동화 된 테스트로 코드에 버그가 있으면 알려줍니다. SQL 문에 대해 말한 내용으로 가져 가면 비슷한 것으로 생각합니다. 제 질문은 API가 의도 한대로 응답하는 방식으로 코드가 외부 API를 쿼리하는지 테스트하는 것과 같습니다 ( 공칭 응답). 나는 당신이 말하는 것을 단위 및 통합 테스트에서 제외하는 것이라고 생각하지만 쿼리가 미션 크리티컬 한 경우 라이브 외부 API를 테스트하기 위해 다른 자동 테스트를 별도로 설정할 수 있습니다.
Joshua Coady

1
IMO, 가장 좋은 방법은 기능 테스트를 수행하는 것이며, 절대 적용되지 않을 where 절의 변경은 하나 이상의 기능 테스트에서 다른 행동을 유발할 것입니다. UT는 테스트 계획에서 약간의 부분 일뿐입니다.
Laiv

2
공명판이되어 주셔서 감사합니다. 궁극적으로 쿼리에 사용자 지정 논리가 있지만 쿼리는 테스트중인 시스템 외부에서 "실행"되는 코드이기 때문에 단위 테스트 도메인 외부에 있습니다. 나는 그것을보기 전에 다른 방법으로 여러 번 말해 줄 누군가가 필요했습니다.)
Joshua Coady

2

생성 된 쿼리 문자열이 예상 값과 일치하는지 확인하는 단위 검사를 보았습니다.

하나. 제한된 사용이라면 이것은 내 의견이었다. 쿼리 구문은 복잡하고 버그가 많을 수 있으므로 A는 문자열이 '정확하게'생성 된 경우에도 확인하고 B를 끝낼 가능성이 있었으며 예기치 않은 결과가 실제 환경에서 반환 될 수 있습니다.

나는 당신이 당신의 옵션을 선택하는 것이 옳다고 생각합니다. 2. 라이브 인스턴스에 대해 통합 테스트를 실행하십시오.

비파괴적인 한, 오류의 원인을 파악할 수는 없지만 파악해야 할 첫 번째 테스트입니다.

옵션 3 '더미 데이터로 테스트 인스턴스 배포'를 선택하는 것이 좋습니다. 그러나 테스트 서버를 배포하는 데 시간이 많이 걸리는 경우 테스트 서버에서 동일한 테스트를 가리킬 수 있으므로 테스트 작성에는 영향을 미치지 않습니다.


0

API에 따라 다르지만 가능하면 옵션 # 3 (개인 테스트 인스턴스)으로 이동하십시오.

언급 한 이유 때문에 API (옵션 # 1) 스터 빙은 최악의 옵션 이며이 경로를 사용하면 좋은 것보다 많은 해를 끼칠 것입니다 (많은 낭비 시간).

실제 API (옵션 # 2)에 대해 실행하면 테스트가 불안정하고 신뢰할 수 없으며 몇 가지 오 탐지 후에는 사용을 중단합니다. 데이터가 변경 될뿐만 아니라 서비스도 다운 될 수 있습니다. 내 생각에 이것은 쿼리에 대한 테스트가 없으며 문제를 찾기 위해 통합 / 시스템 테스트에 의존하는 것과 유사합니다. 즉, API 데이터가 거의 변경되지 않고 API 자체가 거의 항상 작동하는 경우 이는 실행 가능한 옵션 일 수 있습니다. 대부분의 API는이 설명에 맞지 않습니다.

결국 이러한 쿼리가 얼마나 중요하고 복잡한 지에 따라 결정됩니다. 소수 이상이 있고 일부는 테스트해야 할 정도로 복잡 할 경우 테스트를 위해 프라이빗 인스턴스를 설정하는 데 투자합니다. . 다른 단위 테스트와 마찬가지로 비용을 지불합니다.


기본적으로 단위 테스트 (# 1)와 통합 테스트 (# 2)가 해롭다는 것을 알고 있습니까? # 3이 가장 좋을 수도 있지만 가장 비쌀 수도 있습니다. API가 변경 될 때마다 유지되어야합니다. # 2가 없으면 앱이 프로덕션 상태가 될 때까지 실제 조치에서 발생할 수있는 버그 변경에 대해 알지 못합니다 (조치가 너무 늦습니다). 테스트 ... 오늘 ... 내일에 코드 라인, 알고 어떻게 ... 거기이기 때문에 좋아, # 1 uneeded 보인다
LAIV

나는 나쁜 테스트가 해롭다는 것을 분명히 말하고 있습니다. 색다른 테스트는 많은 시간과 노력을 낭비하며 사람들이 전체적으로 단위 테스트에 대한 믿음을 잃게합니다. 구현 변경 사항 (# 1) 또는 데이터 변경 사항 (# 2)이 임의로 테스트되는 테스트는 좋은 테스트가 아닙니다.
Michal Tenenberg

통합 테스트는 데이터를 테스트하지 않습니다. 그게 다야. 테스트를 중단 할 수 없으며 통합을 검증하기 만하면됩니다. 테스트는 믿음의 문제가 아니라 응용 프로그램에 가치를 더하는 좋은 습관을 갖는 문제입니다
Laiv
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.