단위 테스트에서 내 방법을 사용해야합니까?


83

오늘 나는 " JUnit basics"비디오를 보고 있었고 저자는 프로그램에서 주어진 메소드를 테스트 할 때 프로세스에서 다른 메소드를 사용해서는 안된다고 말했다.

보다 구체적으로 말하면 인수의 이름과 성을 사용하는 레코드 작성 방법을 테스트하고 주어진 테이블에서 레코드를 작성하는 데 사용했습니다. 그러나 그는이 방법을 테스트하는 과정에서 다른 DAO 방법을 사용하여 데이터베이스를 쿼리하여 최종 결과를 확인 해서는 안된다고 주장했습니다 (실제로 올바른 데이터로 레코드가 작성되었는지 확인). 그는 데이터베이스를 쿼리하고 결과를 확인하기 위해 추가 JDBC 코드를 작성해야한다고 주장했다 .

나는 그의 주장의 정신을 이해한다고 생각합니다. 한 방법의 테스트 사례가 다른 방법 (이 경우 DAO 방법)의 정확성에 의존하지 않기를 원하며 이것은 자신의 유효성 검사를 (다시) 작성하여 달성됩니다 / supporting 코드 (보다 구체적이고 집중되어야하므로 더 간단한 코드).

그럼에도 불구하고 내 머리 속의 목소리는 코드 복제, 불필요한 추가 노력 등과 같은 논쟁으로 항의하기 시작했습니다. 우리가 전체 테스트 배터리를 실행하고 모든 공개 방법을 철저히 테스트한다면 (이 경우 DAO 방법 포함) 다른 방법을 테스트하는 동안 해당 방법 중 일부를 사용하는 것이 좋지 않습니까? 그중 하나가 예상대로 작동하지 않으면 자체 테스트 사례가 실패하고 문제를 해결하고 테스트 배터리를 다시 실행할 수 있습니다. 중복 코드가 다소 단순하더라도 코드 중복이 필요하지 않거나 노력이 낭비되지 않습니다.

필자가 작성한 최근의 Excel - VBA 응용 프로그램 ( VBA 용 Rubberduck 덕분에 단위 테스트를 거쳤습니다)으로 인해이 권장 사항을 적용하면 추가적인 추가 작업이 많이 발생하고 아무런 이익이 없음을 알 수 있습니다.

이에 대한 통찰력을 공유 할 수 있습니까?


79
그것은 모든 데이터베이스를 포함하는 단위 테스트 볼이 약간 이상하다
리처드 설렘

4
IMO 다른 클래스를 IFF라고 부르는 것이 좋습니다. 디스크 나 네트워크를 통해 이동해야하는 모든 것을 조롱하십시오. 일반 ol 클래스 IMO를 조롱하는 것은 의미가 없습니다.
RubberDuck

2
이 비디오에 대한 링크가 있습니까?
candied_orange

17
" VBA를위한 Rubberduck 덕분에 단위 테스트를 거쳤 습니다." 오타를 수정하고 "RubberDuck"에서 "Rubberduck"으로 편집했지만 스패머가 그렇게하고 rubberduckvba.com에 대한 링크를 추가하고 싶습니다 (도메인 이름과 프로젝트를 공동 소유 함) @RubberDuck)-대신 여기에 의견을 드리겠습니다. 어쨌든 사람들이 실제로 지난 2 년 동안 더 나은 부분을 위해 잠 못 이루는 밤의 대부분을 담당했던 도구를 실제로 사용하는 것을 보는 것이 좋습니다! =)
Mathieu Guindon

4
@ Mat'sMug와 RubberDuck 나는 당신이 Rubberduck로하고있는 일을 좋아합니다. 보관하십시오. 분명히 내 인생이 더 쉬워졌습니다 (Excel VBA에서 많은 작은 프로그램과 프로토 타입을 수행합니다). BTW, 내 게시물에 Rubberduck의 언급은 나를 다시 나에게 좋은되었습니다 RubberDuck 그 자신에게 친절하려고 노력했다 여기 PE에. :)
carlossierra

답변:


186

그의 주장의 정신은 실제로 정확합니다. 단위 테스트의 요점은 코드를 분리하고 종속성이없는 코드를 테스트하여 발생하는 모든 오류를 빠르게 인식 할 수 있도록하는 것입니다.

그렇게 말하면, 단위 테스트는 도구이며, 그것은 당신의 목적을 수행하기위한 것이며,기도하는 제단이 아닙니다. 때로는 의존성이 충분하게 작동하기 때문에 의존성을 남기는 것을 의미하며, 조롱하고 싶지는 않습니다. 때로는 통합 테스트가 아니라면 단위 테스트 중 일부가 실제로 매우 가깝습니다.

궁극적으로 평가를받지 않고 중요한 것은 테스트중인 소프트웨어의 최종 제품입니다. 그러나 규칙을 구부릴 때와 트레이드 오프가 가치가있는 시점을 결정할 때주의를 기울여야합니다.


117
실용주의를위한 만세.
Robert Harvey

6
나는 의존성을 없애는 문제가되는 속도만큼의 신뢰성은 아니라고 덧붙였다. 격리 만트라에서의 테스트는 너무나 강력하지만이 주장은 종종 누락됩니다.
Michael Durrant

4
"... 단위 테스팅은 도구이며, 그것은 당신의 목적을 수행하기위한 것이며,기도 할 제단이 아닙니다."-이것!
Wayne Conrad

15
"기도 할 제단이 아님"-화난 TDD 코치들!
Den

5
@ jpmc26 : 더 나쁜 것은 웹 서비스가 다운되는 것을 올바르게 처리했기 때문에 모든 단위 테스트가 통과되는 것을 원하지 않습니다 . 이는 유효하고 올바른 동작이지만 실제로는 코드가 작동하지 않습니다! 일단 스터브하면 "위"또는 "아래"중 하나를 선택하고 둘 다 테스트 할 수 있습니다.
Steve Jessop

36

나는 이것이 용어로 귀결된다고 생각한다. 많은 사람들에게 "단위 테스트"는 매우 구체적인 것이며, 정의 에 따라 테스트중인 장치 외부의 코드 (방법, 기능 등)에 따라 통과 / 실패 조건을 가질 수 없습니다 . 여기에는 데이터베이스와의 상호 작용이 포함됩니다.

다른 사람들에게 "단위 테스트"라는 용어는 훨씬 느슨하며 응용 프로그램의 통합 부분을 테스트하는 테스트 코드를 포함하여 모든 종류의 자동 테스트를 포함합니다.

테스트 전문가 (해당 용어를 사용할 수있는 경우) 는 테스트가 둘 이상의 순수 코드 단위 에 의존한다는 점에서 단위 테스트 와 구별 되는 통합 테스트 라고 할 수 있습니다 .

나는 당신이 "단위 테스트"라는 용어의 느슨한 버전을 사용하고 실제로 "통합 테스트"를 언급하고 있다고 생각합니다.

이러한 정의를 사용하면 "단위 테스트"에서 테스트중인 단위 외부의 코드에 의존해서는 안됩니다. 그러나 "통합 테스트"에서는 특정 코드 조각을 연습 한 다음 통과 기준에 대해 데이터베이스를 검사하는 테스트를 작성하는 것이 매우 합리적입니다.

통합 테스트에 의존해야하는지 아니면 단위 테스트에 의존해야하는지 또는 둘 다에 대해 더 큰 논의 주제입니다.


당신은 당신의 의심에 옳습니다. 용어를 잘못 사용하고 있으며 각 유형의 테스트를보다 적절하게 처리 할 수있는 방법을 확인할 수 있습니다. 감사!
carlossierra

11
"다른 사람들에게는"단위 테스트 "라는 용어가 훨씬 느슨합니다. 소위"단위 테스트 프레임 워크 "는 더 높은 수준의 테스트를 구성하고 실행하는 정말 편리한 방법입니다. ;-)
Steve Jessop

1
"순수한"대 "느슨한"구별이 아니라 의미로로드되는 대신 도메인 관점에서 "단위", "종속성"등을 보는 사람들 간의 구별이 좋습니다 (예 : "인증"은 단위로 "데이터베이스"는 의존성 등으로 계산됩니다) 대 프로그래밍 언어 관점에서 보는 사람들 (예 : 메소드는 단위, 클래스는 종속성) "테스트중인 단위"와 같은 문구가 의미하는 바를 정의하면 논증 ( "You 's wrong!")이 토론으로 바뀔 수 있습니다 ( "이것이 올바른 수준의 세분화입니까?").
Warbo

1
@EricKing 물론, 첫 번째 카테고리의 사람들 대부분 에게 DAO를 사용하든 데이터베이스를 직접 쳤든 관계없이 단위 테스트에 데이터베이스 포함시키는 아이디어 는 혐오입니다.
Periata Breatta

1
@AmaniKilumanga 문제는 기본적으로 "누군가는 단위 테스트 에서이 작업을 수행해서는 안되지만 단위 테스트 에서이 작업을 수행하면 안된다고 말합니다. 괜찮습니다. 괜찮습니까?" 제 대답은 "그렇습니다. 그러나 대부분의 사람들은 단위 테스트 대신 통합 테스트라고 부릅니다." 귀하의 질문으로, "통합 테스트에서 생산 코드 방법을 사용할 수 있습니까?"라는 것이 무슨 의미인지 잘 모르겠습니다.
Eric King

7

대답은 '예'입니다.

저수준 코드가 적절하게 기능하고있는 기초 작업을 수행 할 수 있도록하기 위해 독립적으로 수행되는 고유 한 테스트는 절대적으로 필요합니다. 그러나 더 큰 라이브러리를 코딩 할 때는 단위를 교차하는 테스트가 필요한 코드 영역도 있습니다.

이러한 교차 단위 테스트는 코드 범위 및 엔드 투 엔드 기능을 테스트 할 때 유용하지만 다음과 같은 몇 가지 단점이 있습니다.

  • 단절된 문제를 확인하기위한 격리 된 테스트가 없으면 실패한 "교차"테스트는 코드의 문제점을 판별하기 위해 추가 문제 해결이 필요합니다.
  • 교차 단위 테스트에 너무 많이 의존하면 SOLID 객체 지향 코드를 작성할 때 항상 있어야하는 계약 사고 방식에서 벗어날 수 있습니다. 격리 된 테스트는 일반적으로 장치가 하나의 기본 작업 만 수행해야하므로 의미가 있습니다.
  • 엔드 투 엔드 테스트는 바람직하지만 테스트에서 데이터베이스에 쓰거나 프로덕션 환경에서 원하지 않는 작업을 수행해야하는 경우 위험 할 수 있습니다. Mockito 와 같은 mocking 프레임 워크 가 인기있는 많은 이유 중 하나 는 객체를 가짜로 만들고 실제로는 원하지 않는 것을 변경하지 않고 엔드 투 엔드 테스트를 모방 할 수 있기 때문입니다.

하루가 끝나면 저수준 기능을 포괄하는 많은 테스트와 엔드 투 엔드 기능을 테스트하는 많은 테스트가 필요합니다. 시험을 작성하는 이유에 초점을 맞추십시오. 코드가 예상 한대로 작동하고 있음을 확신 할 수 있습니다. 그렇게하려면 무엇이든해야합니다.

슬프지만 진정한 사실은 자동화 된 테스트를 전혀 사용하지 않는다면 이미 많은 개발자에게 도움이 될 것입니다. 좋은 테스트 관행은 개발 팀이 마감 기한에 직면했을 때 가장 먼저 미끄러 져야합니다. 따라서 코드를 어떻게 수행해야하는지에 대한 의미있는 반영을하는 총을 고수하고 단위 테스트를 작성하는 한 테스트가 얼마나 "순결"하는지에 대해서는 집착하지 않을 것입니다.


4

다른 개체 메서드를 사용하여 조건을 테스트 할 때 발생하는 한 가지 문제는 서로 상쇄되는 오류가 누락된다는 것입니다. 더 중요한 것은 어려운 테스트 구현의 어려움을 놓치고 있다는 것입니다. 그 고통은 기본 코드에 대해 무언가를 가르치고 있습니다. 고통스러운 테스트는 이제 나중에 고통스러운 유지 보수를 의미합니다.

나머지 개체를 다시 구현 하지 않고도 테스트하기가 더 쉬울 때까지 유닛을 더 작게 만들고 클래스를 분할하고 리팩터링하고 다시 디자인 하십시오. 코드 나 테스트를 더 이상 단순화 할 수 없다고 생각되면 도움을 받으십시오. 항상 운이 좋으며 깨끗하게 테스트하기 쉬운 과제를 얻는 동료를 생각하십시오. 운이 없기 때문에 도움을 요청하십시오.


1
여기서 열쇠는 단위입니다. 다른 절차와 프로세스를 호출해야하는 경우, 그것은 하나의 장치가 아닙니다. 여러 번 호출하고 여러 단계를 검증해야하는 경우 단위보다 큰 코드 조각 인 경우 단일 논리 조각을 포함하는 작은 조각으로 나눕니다. 일반적으로 DB 호출도 조롱하거나 실제 DB에 액세스하고 테스트 후 데이터를 실행 취소해야하는 단위 테스트에서 메모리 내 DB를 사용합니다.
dlb

1

테스트되는 기능 단위가 '영구적으로 저장되고 검색 가능한 데이터입니까?'인 경우 실제 데이터베이스에 저장하고 데이터베이스에 대한 참조를 보유하는 모든 객체를 파괴 한 다음 코드를 호출하여 단위 테스트 테스트를 수행합니다. 다시 개체.

데이터베이스에서 레코드가 작성되는지 테스트하는 것은 나머지 시스템에 노출 된 기능 단위를 테스트하는 것이 아니라 스토리지 메커니즘의 구현 세부 사항과 관련이있는 것 같습니다.

모의 데이터베이스를 사용하여 성능을 향상시키기 위해 테스트를 단축하고 싶을 수도 있지만 계약을 체결하고 계약을 마친 시스템과 계약을 맺은 계약자가 있지만 실제로 데이터베이스에는 아무것도 저장하지 않았습니다. 시스템 재부팅 사이.

단위 테스트에서 '단위'가 '코드 단위'또는 '기능 단위'를 나타내는 지 여부는 많은 코드 단위가 함께 생성 한 기능 일 수 있습니다. 나는 이것이 유용한 차이점을 발견하지 못한다. 내가 염두에 두어야 할 질문은 '테스트가 시스템이 비즈니스 가치를 제공하는지 여부에 대해 무언가를 알려주 는가?'와 '구현이 변경되면 테스트가 취약한가?'이다. 설명 된 것과 같은 테스트는 시스템을 TDD 할 때 유용합니다. '데이터베이스 레코드에서 객체 가져 오기'를 아직 작성하지 않았으므로 전체 기능 단위를 테스트 할 수는 없지만 구현 변경 사항에 취약하므로 구현 변경 사항에 취약합니다. 전체 작업을 테스트 할 수 있으면 제거하십시오.


1

정신은 정확합니다.

이상적으로는 단위 테스트 에서 단위 (개별 방법 또는 소규모 클래스)를 테스트합니다 .

이상적으로는 전체 데이터베이스 시스템을 제거합니다. 즉, 가짜 환경에서 메소드를 실행하고 올바른 순서로 올바른 DB API를 호출하는지 확인하십시오. 자신의 방법 중 하나를 테스트 할 때 DB를 테스트하고 싶지 는 않습니다 .

많은 장점이 있습니다. 무엇보다도 올바른 DB 환경을 설정하고 나중에 롤백 할 필요가 없기 때문에 테스트가 빨리 눈을 멀게됩니다.

물론, 이것은 시작부터 올바르게 수행하지 않는 모든 소프트웨어 프로젝트에서 높은 목표입니다. 그러나 단위 테스트 의 정신입니다 .

이 방법과 다른 기능 테스트, 동작 테스트 등과 같은 다른 테스트가 있습니다. "테스트"와 "단위 테스트"를 혼동하지 마십시오.


"정확한 순서로 올바른 DB API를 호출해야합니다"– 예. 그것이 문서를 잘못 읽은 것으로 판명 될 때까지 실제로 사용해야했던 정확한 순서는 완전히 다릅니다. 통제 밖의 시스템을 조롱하지 마십시오.
Joker_vD

4
@Joker_vD 이것이 바로 통합 테스트입니다. 단위 테스트에서는 외부 시스템을 절대적으로 조롱해야합니다.
Ben Aaronson

1

데이터베이스와 상호 작용하는 비즈니스 코드에 대한 단위 테스트에서 직접 데이터베이스 액세스를 사용 하지 않아야 하는 매우 중요한 이유가 하나 이상 있습니다. 데이터베이스 구현을 변경하는 경우 모든 단위 테스트를 다시 작성해야합니다. 열의 이름을 바꾸십시오. 코드의 경우 데이터 매퍼 정의에서 한 줄만 변경하면됩니다. 그러나 테스트 중에 데이터 매퍼를 사용하지 않으면 이 열을 참조하는 모든 단일 단위 테스트도 변경해야합니다 . 이는 특히 검색 및 교체가 쉽지 않은보다 복잡한 변경의 경우 엄청난 양의 작업으로 바뀔 수 있습니다.

또한 데이터베이스와 직접 대화하는 대신 데이터 매퍼를 추상 메커니즘으로 사용하면 데이터베이스에 대한 종속성을 완전히 제거하는 것이 더 쉬워집니다. 지금은 관련이 없지만 수천 개의 단위 테스트와 모든 테스트를 수행 할 때 테스트 스위트가 몇 분에서 실행까지 몇 초가 걸리고 생산성에 큰 이점을 줄 수 있기 때문에 데이터베이스를 리팩토링하여 종속성을 제거 할 수 있다는 점에 감사하게 생각합니다.

귀하의 질문은 당신이 올바른 행을 따라 생각하고 있음을 나타냅니다. 의심 스러우면 단위 테스트도 코드입니다. 나머지 코드베이스와 마찬가지로 유지 관리 가능하고 향후 변경 사항에 쉽게 적용 할 수 있도록하는 것도 중요합니다. 읽을 수있게하고 중복을 제거하기 위해 노력하면 훨씬 더 나은 테스트 스위트를 갖게됩니다. 그리고 좋은 테스트 스위트는 사용되는 것입니다. 또한 사용되는 테스트 스위트는 오류를 찾는 데 도움이되지만 사용되지 않는 테스트 스위트는 가치가 없습니다.


1

단위 테스트 및 통합 테스트에 대해 배울 때 배운 가장 좋은 교훈은 방법을 테스트하는 것이 아니라 동작을 테스트하는 것입니다. 다시 말해,이 객체는 무엇을 하는가?

그런 식으로 볼 때 데이터를 유지하는 방법과 다시 읽는 다른 방법은 테스트가 가능합니다. 물론 방법을 구체적으로 테스트하는 경우 다음과 같이 각 방법에 대한 테스트가 끝납니다.

@Test
public void canSaveData() {
    writeDataToDatabase();
    // what can you assert - the only expectation you can have here is that an exception was not thrown.
}

@Test
public void canReadData() {
    // how do I even get data in there to read if I cannot call the method which writes it?
}

이 문제는 테스트 방법의 관점 때문에 발생합니다. 방법을 테스트하지 마십시오. 행동 테스트. WidgetDao 클래스의 동작은 무엇입니까? 위젯을 유지합니다. 자, 위젯이 지속되는지 어떻게 확인합니까? 지속성의 정의는 무엇입니까? 그것은 당신이 그것을 쓸 때 다시 읽을 수 있음을 의미합니다. 따라서 읽기 + 쓰기가 함께 테스트가되고 제 생각에는보다 의미있는 테스트가됩니다.

@Test
public void widgetsCanBeStored() {
    Widget widget = new Widget();
    widget.setXXX.....
    // blah

    widgetDao.storeWidget(widget);
    Widget stored = widgetDao.getWidget(widget.getWidgetId());
    assertEquals(widget, stored);
}

그것은 논리적이고, 응집력 있고, 신뢰할 수 있으며, 제 생각에는 의미있는 테스트입니다.

다른 답변은 격리의 중요성, 실용적 토론과 현실적인 토론, 단위 테스트가 데이터베이스를 쿼리 할 수 ​​있는지 여부에 중점을 둡니다. 그들은 실제로 질문에 대답하지 않습니다.

무언가를 저장할 수 있는지 테스트하려면 그것을 저장 한 다음 다시 읽어야합니다. 읽을 수없는 것이 저장되어 있는지 테스트 할 수 없습니다. 데이터 검색과 별도로 데이터 저장을 테스트하지 마십시오. 아무 말도하지 않는 테스트가 끝납니다.


매우 통찰력있는 접근 방식, 그리고 당신이 말했듯이, 당신이 정말로 내가 가진 핵심 의문 중 하나를 쳤다고 생각합니다. 감사!
carlossierra

0

잡으려고하는 실패 사례의 한 예는 테스트중인 개체가 캐싱 계층을 사용하지만 필요에 따라 데이터를 유지하지 못한다는 것입니다. 그런 다음 개체를 쿼리하면 "예, 새 이름과 주소가 있습니다"라고 표시되지만 실제로 예상했던 작업을 수행하지 않았기 때문에 테스트가 실패하기를 원합니다.

또는 단일 책임 위반을 간과하면 UTF-8 인코딩 버전의 문자열을 바이트 지향 필드로 유지해야하지만 실제로 Shift JIS는 유지한다고 가정합니다. 다른 구성 요소는 데이터베이스를 읽을 예정이므로 UTF-8이 필요하므로 요구 사항입니다. 그런 다음이 객체를 왕복하면 올바른 이름과 주소가 Shift JIS에서 다시 변환되기 때문에 올바른 이름과 주소를보고하지만 테스트에서 오류가 감지되지 않습니다. 나중에 통합 테스트에 의해 감지되기를 바랍니다. 그러나 단위 테스트의 요점은 문제를 조기에 발견하고 정확히 어떤 구성 요소가 책임이 있는지 파악하는 것입니다.

그중 하나가 예상대로 작동하지 않으면 자체 테스트 사례가 실패하고 문제를 해결하고 테스트 배터리를 다시 실행할 수 있습니다.

주의하지 않으면 상호 의존적 인 테스트 세트를 작성하기 때문에이를 가정 할 수 없습니다. "저장합니까?" test는 테스트중인 save 메소드를 호출 한 다음 load 메소드를 통해 저장되었는지 확인합니다. "로드합니까?" test는 save 메소드를 호출하여 테스트 픽스처를 설정 한 다음 테스트중인로드 메소드를 호출하여 결과를 확인합니다. 두 테스트는 모두 테스트하지 않는 방법의 정확성에 의존합니다. 즉, 테스트중인 방법의 정확성을 실제로 테스트하는 것은 없습니다.

여기에 문제가 있다는 단서는 다른 유닛을 테스트하는 두 가지 테스트가 실제로 동일한 것을 수행한다는 것 입니다. 둘 다 setter를 호출하고 getter를 호출 한 다음 결과가 원래 값인지 확인합니다. 그러나 세터 / 게터 쌍이 함께 작동하는 것이 아니라 세터가 데이터를 유지하는지 테스트하고 싶었습니다. 그래서 당신은 뭔가 잘못된 것을 알고, 당신은 무엇을 알아 내고 테스트를 수정해야합니다.

코드가 단위 테스트를 위해 잘 설계된 경우 테스트중인 방법으로 데이터가 실제로 올바르게 유지되는지 여부를 테스트 할 수있는 방법은 적어도 두 가지입니다.

  • 데이터베이스 인터페이스를 조롱하고 예상 값으로 적절한 함수가 호출되었다는 사실을 조롱 기록하십시오. 이것은 메소드가 예상대로 작동하는지 테스트하고 클래식 단위 테스트입니다.

  • 데이터가 올바르게 유지되는지 여부를 기록 하려면 정확히 동일한 의도 로 실제 데이터베이스를 전달하십시오 . 그러나 "예, 올바른 데이터를 얻었습니다"라는 조롱 함수가 아닌 테스트에서 데이터베이스를 직접 읽고 올바른지 확인합니다. 전체 데이터베이스 엔진이 영광스러운 모의 글을 작성하는 데 사용하기에 상당히 큰 것이기 때문에 이것이 가장 순수한 테스트 가 아닐 수도 있습니다. 커밋되지 않은 트랜잭션이 표시 될 수 있으므로 쓰기에 사용 된 것과 동일한 데이터베이스 연결을 사용하여 읽지 않아야합니다. 그러나 그것은 옳은 것을 테스트하고 적어도 당신은 그것을 정확하게 알고 있습니다 모의 코드를 작성하지 않고도 전체 데이터베이스 인터페이스를 구현합니다!

따라서 JDBC로 테스트 데이터베이스에서 데이터를 읽거나 데이터베이스를 조롱하는지 여부는 테스트 구현의 세부 사항입니다. 어느 쪽이든 요점은 내가 잘못한 경우에도 동일한 클래스의 다른 잘못된 메소드와 공모하여 허용되도록하는 경우보다 분리하여 장치를 더 잘 테스트 할 수 있다는 것입니다. 따라서 테스트하는 방법의 구성 요소를 신뢰하는 것 외에 편리한 방법을 사용하여 올바른 데이터가 유지되는지 확인하고 싶습니다.

코드가 단위 테스트를 위해 제대로 설계 되지 않은 경우 테스트하려는 메소드의 오브젝트가 데이터베이스를 삽입 된 종속성으로 허용하지 않을 수 있으므로 선택의 여지가 없습니다. 어떤 경우 테스트 대상 장치를 분리하는 가장 좋은 방법에 대한 설명은 테스트 대상 장치를 얼마나 가깝게 분리 할 수 ​​있는지에 대한 설명으로 변경됩니다. 그러나 결론은 같습니다. 결함이있는 유닛들 사이에서 음모를 피할 수 있다면 가능한 시간과 코드에서 결함을 찾는 데 더 효과적이라고 생각하는 다른 것에 의존하십시오.


0

이것이 내가 좋아하는 방법입니다. 이것은 제품의 결과에 영향을 미치지 않고 제품을 생산하는 방식에만 영향을 미치기 때문에 개인의 선택입니다.

이는 테스트중인 애플리케이션없이 데이터베이스에 모의 값을 추가 할 수있는 가능성에 달려 있습니다.

두 가지 테스트가 있다고 가정 해 보겠습니다. A-데이터베이스 읽기 B-데이터베이스에 삽입 (A에 따라 다름)

A가 합격하면 B의 결과가 B가 아닌 테스트 된 부품에 의존한다는 것이 확실합니다. A가 실패하면 B에 대해 잘못된 부정을 가질 수 있습니다. 오류는 B 또는 A에있을 수 있습니다. A가 성공할 때까지 확실하지 않습니다.

응용 프로그램 뒤의 DB 구조를 알 수 없어야하거나 변경 될 수 있으므로 단위 테스트에서 일부 쿼리를 쓰려고하지 않습니다. 코드 자체로 인해 테스트 사례가 실패 할 수 있음을 의미합니다. 테스트를 위해 테스트를 작성하지 않으면 테스트를 위해 테스트 할 사람은 ...


-1

결국, 그것은 당신이 테스트하고자하는 것에 달려 있습니다.

때로는 클래스의 제공된 인터페이스를 테스트하기에 충분합니다 (예 : 레코드가 작성 및 저장되어 나중에 "다시 시작"한 후 검색 될 수 있음). 이 경우 제공된 테스트 방법을 사용하는 것이 좋습니다. 예를 들어 스토리지 메커니즘 (다른 데이터베이스, 테스트를위한 인 메모리 데이터베이스 등)을 변경하려는 경우 테스트를 재사용 할 수 있습니다.

이것은 클래스가 계약을 준수하는 것 (이 경우 레코드 생성, 저장 및 검색)을 실제로 수행하는 것만 신경 쓰지 않는다는 것을 의미합니다. 클래스가 아닌 인터페이스에 대해 현명하게 단위 테스트를 작성하면 인터페이스의 계약을 준수해야하므로 다른 구현을 테스트 할 수 있습니다.

반면에 어떤 경우에는 실제로 어떻게 데이터가 유지되는지 확인해야합니다 (다른 프로세스가 해당 데이터베이스의 올바른 형식에있는 데이터에 의존하고 있습니까?). 이제 클래스에서 올바른 레코드를 다시 가져올 수있을뿐 아니라 데이터베이스에 올바르게 저장되었는지 확인해야합니다. 가장 직접적인 방법은 데이터베이스 자체를 쿼리하는 것입니다.

이제 계약을 준수하는 클래스 (생성, 저장 및 검색)뿐만 아니라이를 유지하는 방법 (지속적인 데이터가 다른 인터페이스를 준수해야하기 때문에)에 신경 쓰지 않아도됩니다. 그러나 이제 테스트는 클래스 인터페이스 스토리지 형식 에 따라 달라 지므로 완전히 재사용하기가 어렵습니다. (이러한 종류의 테스트를 "통합 테스트"라고 부를 수도 있습니다.)


@ downvoters : 내 대답이 부족하다고 생각하는 측면을 개선 할 수 있도록 이유를 말해 주시겠습니까?
hoffmale
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.