복붙노트

[SQL] 테스트 SQL 쿼리에 가장 좋은 방법은 [마감]

SQL

테스트 SQL 쿼리에 가장 좋은 방법은 [마감]

나는 우리가 복잡한 SQL 쿼리 오류와 데이트를 갖는 유지에있어서 문제로 실행했다. 그런 잘못된 고객과 다른 '문제'로 메일을 보내는 기본적으로이 결과.

같은 SQL 쿼리를 만드는 모든 사람의 경험은 무엇입니까? 우리는 다른 모든 주 데이터의 새로운 동료를 만들 수 있습니다.

그래서 여기 내 생각과 그들에게 몇 가지 제한 사항은 다음과 같습니다 :

덕분에 모든 입력을 위해 당신은 내 문제로 제공 할 수 있습니다.

해결법

  1. ==============================

    1.당신은 200 개 라인 긴 기능을 가진 응용 프로그램을 작성하지 않을 것입니다. 당신은 하나 명확하게 정의 된 책임, 작은 함수로 각각 그 긴 기능을 분해하는 것입니다.

    당신은 200 개 라인 긴 기능을 가진 응용 프로그램을 작성하지 않을 것입니다. 당신은 하나 명확하게 정의 된 책임, 작은 함수로 각각 그 긴 기능을 분해하는 것입니다.

    왜 그런 당신의 SQL을 작성?

    당신이 당신의 기능을 분해처럼 쿼리를 분해. 이것은 그들이 짧고, 간단하고 쉽게 리팩토링 쉽게 시험을 쉽게 이해 할 수 있습니다. 그리고 그것은 당신이 절차 적 코드에서와 마찬가지로, 그들 주위에 "심"그들 사이에, 그리고 "래퍼"를 추가 할 수 있습니다.

    당신이 어떻게해야합니까? 각각의 중요한 일을함으로써 쿼리는보기로한다. 그럼 당신은 당신이 더 원시적 인 기능에서 더 많은 복잡한 기능을 구성하는 것처럼,이 간단한 뷰에서 더 많은 복잡한 쿼리를 구성한다.

    그리고 좋은 점은, 뷰의 가장 조성을 위해, 당신은 당신의 RDBMS의 정확히 동일한 성능을 얻을 것입니다. (당신이하지 않습니다 일부;?.. 그래서 조기 최적화는 모든 악의 뿌리입니다 코드 올바르게 먼저 다음 최적화 당신이 필요로하는 경우)

    여기에 복잡한 쿼리를 분해하는 몇 가지보기를 사용하는 예입니다.

    각 뷰 하나만 변화를 추가하기 때문에 예에서, 각각 독립적으로 에러를 찾기 위해 검사 될 수 있고, 검사가 간단하다.

    다음 예에서 기본 테이블입니다 :

    create table month_value( 
        eid int not null, month int, year int,  value int );
    

    그것은 하나 개의 자료, 절대 달을 표현하기 위해, 두 개의 열, 월, 년을 사용하기 때문에이 표는 결함이있다. 여기에 새로운 계산 컬럼에 대한 우리의 사양입니다 :

    create view cm_absolute_month as 
    select *, year * 12 + month as absolute_month from month_value;
    

    이제 우리가 테스트해야하는 것은 어떤 튜플 (년, 월)를 위해, 거기에 오직 하나의 (absolute_month)이며, 그 (absolute_month)의 연속이다, 즉 것을, 우리의 사양에 내재이다. 하자 몇 가지 테스트를 작성.

    테스트 이름과 함께 catenated case 문 : 우리의 테스트는 다음과 같은 구조와 더불어, SQL 선택 쿼리 될 것입니다. 테스트 이름은 임의의 문자열입니다. 케이스 문은 시험 문이 다음 다른 '통과'끝 '실패'단지 사건이다.

    테스트 문은 테스트가 통과하는 참이어야 SQL의 선택 (서브 쿼리)입니다.

    여기에 우리의 첫 번째 테스트는 다음과 같습니다

    --a select statement that catenates the test name and the case statement
    select concat( 
    -- the test name
    'For every (year, month) there is one and only one (absolute_month): ', 
    -- the case statement
       case when 
    -- one or more subqueries
    -- in this case, an expected value and an actual value 
    -- that must be equal for the test to pass
      ( select count(distinct year, month) from month_value) 
      --expected value,
      = ( select count(distinct absolute_month) from cm_absolute_month)  
      -- actual value
      -- the then and else branches of the case statement
      then 'passed' else 'failed' end
      -- close the concat function and terminate the query 
      ); 
      -- test result.
    

    해당 쿼리를 실행하면이 결과를 생성합니다 오직 하나 (absolute_month)가 모든 (년, 월)의 경우 : 통과 된

    한 month_value에서 충분한 테스트 데이터,이 테스트의 작품이있다.

    우리는 너무 충분한 테스트 데이터에 대한 테스트를 추가 할 수 있습니다 :

    select concat( 'Sufficient and sufficiently varied month_value test data: ',
       case when 
          ( select count(distinct year, month) from month_value) > 10
      and ( select count(distinct year) from month_value) > 3
      and ... more tests 
      then 'passed' else 'failed' end );
    

    지금은 연속의의 테스트를하자 :

    select concat( '(absolute_month)s are consecutive: ',
    case when ( select count(*) from cm_absolute_month a join cm_absolute_month b 
    on (     (a.month + 1 = b.month and a.year = b.year) 
          or (a.month = 12 and b.month = 1 and a.year + 1 = b.year) )  
    where a.absolute_month + 1 <> b.absolute_month ) = 0 
    then 'passed' else 'failed' end );
    

    이제 파일에 바로 쿼리 우리의 테스트를 만들어 보자, 그리고 데이터베이스에 대해 해당 스크립트를 실행합니다. 우리가보기 스크립트에서 정의를 저장하는 경우 실제로, 우리는 같은 스크립트에 각 뷰에 대한 우리의 테스트를 추가 할 수 있습니다, 데이터베이스에 대해 실행 (또는 스크립트를, 나는 관련 뷰 당 하나 개의 파일을 권장합니다) 그래서 (재하는 행위 -) 우리의 뷰를 작성하면 뷰의 테스트를 실행합니다. 그런 식으로, 우리는 생산에 대한 뷰 생성이 실행 뷰는 생산 테스트 할 때 우리가보기를 다시 작성하고 모두 가져 오기 회귀 테스트.

  2. ==============================

    2.당신은 자주 당신이 원하는대로 다시로드 할 수있는 시험 시스템 데이터베이스를 만듭니다. 데이터를로드하거나 데이터를 생성하고를 저장합니다. 다시로드하는 쉬운 방법을 생성합니다. 해당 데이터베이스로 개발 시스템을 장착하고 생산에 가기 전에 코드를 확인합니다. 자신이 당신이 문제가 생산에 들어갈 수 있도록 관리 할 때마다 킥. 알려진 문제를 확인하고 시간이 지남에 따라 테스트 스위트를 성장 테스트 스위트를 생성합니다.

    당신은 자주 당신이 원하는대로 다시로드 할 수있는 시험 시스템 데이터베이스를 만듭니다. 데이터를로드하거나 데이터를 생성하고를 저장합니다. 다시로드하는 쉬운 방법을 생성합니다. 해당 데이터베이스로 개발 시스템을 장착하고 생산에 가기 전에 코드를 확인합니다. 자신이 당신이 문제가 생산에 들어갈 수 있도록 관리 할 때마다 킥. 알려진 문제를 확인하고 시간이 지남에 따라 테스트 스위트를 성장 테스트 스위트를 생성합니다.

  3. ==============================

    3.당신은 데이터의 고정 세트로 프로그램에 대한 단위 테스트를 작성하려고 할 수 있도록, DbUnit을을 확인 할 수 있습니다. 당신이 더 많거나 적은 예측 가능한 결과와 쿼리를 쓸 수 있어야 그런 식으로.

    당신은 데이터의 고정 세트로 프로그램에 대한 단위 테스트를 작성하려고 할 수 있도록, DbUnit을을 확인 할 수 있습니다. 당신이 더 많거나 적은 예측 가능한 결과와 쿼리를 쓸 수 있어야 그런 식으로.

    당신이 할 수 있습니다 다른 것은 당신이하고 명확하게 질의 존재를 모두 정확하고 잘못된 결과를 반환 한 쿼리를 사용하는 경우, 예를 들어, SQL 서버의 실행 스택을 프로파일 링하고 모든 쿼리가 참으로 올바른 사람이 있는지 확인하다 사용 질문에,하지만 응용 프로그램 코드에서 다른 지점에서 다른 쿼리를 보내는 경우는 어떻습니까?

    다음 쿼리를 해결하기 위해 모든 시도는 악성 쿼리는 여전히 어쨌든 잘못된 결과를 발사하는 사람이 될 수도 ... 쓸데없는 것입니다.

  4. ==============================

    4.재 : tpdi

    재 : tpdi

    case when ( select count(*) from cm_abs_month a join cm_abs_month b  
    on (( a.m + 1 = b.m and a.y = b.y) or (a.m = 12 and b.m = 1 and a.y + 1 = b.y) )   
    where a.am + 1 <> b.am ) = 0  
    

    개월 연속 값을 생각이 유일한 검사가 연속으로 발생하는 데이터를 (당신이 처음에 의도 아마 인) 존재하지 않는 것이, 연속되므로주의. 소스 데이터 중 어느 것도 (예를 들어, 당신은 단지 짝수했다 개월) 연속없는 경우에 항상 오전 계산이 완전히 떨어져있는 경우에도 전달합니다.

    또한 내가 뭔가를 놓친 거지, 또는 ON 절 하반기 잘못된 월 값 범프는 무엇입니까? (즉, 검사 2천11분의 12은 2천10분의 1 후에 오는)

    내 기억이 맞다 경우 옵티마이 그래서이 방법을 오버하지 않는, 공중에 가상의 손을 던져 모든 요청에 ​​풀 테이블 스캔을 수행 시작하기 전에 더 나쁜 것은,, SQL 서버는 적어도 당신에게 전망의 10 레벨을 할 수 있습니다.

    테스트 케이스에서 지옥을 테스트하는 것을 잊지 마십시오!

    그렇지 않으면 매우 넓은 대부분 또는 SqlUnit 또는 DbUnit을하거나 데이터에 대한 예상 결과를 확인하고, 검토, 유지하고 일반적으로 필요로 업데이트를 자동화하는 다른 * 단위를 사용하여 입력 가능한 모든 형태를 포함하는 데이터 집합을 만드는 것 같다 방법은 이동합니다.

  5. from https://stackoverflow.com/questions/754527/best-way-to-test-sql-queries by cc-by-sa and MIT license