복사하여 붙여 넣은 테스트 코드 : 이것이 얼마나 나쁩니 까?


12

내 현재 직업은 주로 우리가 작업하는 다양한 응용 프로그램에 대한 GUI 테스트 코드를 작성하는 것입니다. 그러나 테스트 내에서 많은 코드를 복사하여 붙여 넣는 경향이 있습니다. 그 이유는 테스트하는 영역이 반복이 필요할 정도로 비슷하지만 코드를 메소드 또는 객체로 캡슐화 하기에는 충분히 유사하지 않기 때문 입니다. 클래스 나 메소드를 더 광범위하게 사용하려고 할 때, 테스트는 유지하기가 더 번거롭고 때로는 쓰기가 어려울 때가 있습니다.

대신 일반적으로 한 섹션에서 큰 테스트 코드 덩어리를 복사하여 다른 섹션에 붙여 넣고 필요한 부분을 약간 변경합니다. 더 많은 OO 원칙이나 함수를 사용하는 것과 같이 더 체계적인 코딩 방법을 사용하지 않습니다.

테스트 코드를 작성할 때 다른 코더가 이런 느낌을 받습니까? 분명히 DRY 및 YAGNI 원칙을 따르고 싶지만 테스트 코드 (GUI 테스트를위한 자동화 된 테스트 코드)가 이러한 원칙을 따르기가 어려울 수 있다는 것을 알게되었습니다. 아니면 더 많은 코딩 연습과 더 나은 전반적인 작업 시스템이 필요합니까?

편집 : 내가 사용하는 도구는 SilkTest이며 4Test라는 독점 언어입니다. 또한 이러한 테스트는 주로 Windows 데스크톱 응용 프로그램에 대한 것이지만이 설정을 사용하여 웹 응용 프로그램도 테스트했습니다.


어떤 테스트 도구를 사용하고 있습니까? 테스트 프레임 워크가 작성중인 테스트 유형을 지원하지 않을 수 있습니다. 3 줄 이상의 cut-n-paste는 일반적으로 실제로 좋지 않지만 매번 수동으로 수행하는 것보다 GUI 테스트를 자동화하여 더 많은 장기적인 가치를 명확하게 추가 할 수 있다면 아마도 당신이하는 일이 꽤 힘들 것입니다. 좋은.
GlenPeterson

또한이 언어는 무엇입니까? 당신은 할 수 재사용 (최고 수준의 기능처럼) 할 수 것입니다 그냥 마음에 터지는하지 않는 것이 가능한 무언가를 가지고있다. 다른 한편으로, 테스트 케이스 버그 자체가있을 가능성을 줄이기 위해 단순하게 유지되어야합니다 ...
Izkata

3
내가 작성한 어떤 것에서도 테스트 코드는 리팩토링에서 제외되지 않습니다.
Simon Whitehead

답변:


23

복사하여 붙여 넣은 다음 편집 한 테스트 사례는 종종 좋습니다.

테스트는 가능한 한 적은 외부 종속성을 가져야하며 가능한 한 간단해야합니다. 테스트 케이스는 시간이 지남에 따라 변하는 경향이 있으며 이전에 거의 동일한 테스트 케이스가 갑자기 분기 될 수 있습니다. 다른 사례를 중단 할 염려없이 테스트 사례 하나를 업데이트하는 것이 좋습니다.

물론, 많은 테스트 사례에서 동일 하고 콘서트에서 변경해야하는 상용구 코드는 고려할 수 있으며 제외해야합니다.


1
이것은 주로 내가 느끼는 방식입니다. 많은 경우에 거의 동일한 테스트 코드가 정상이지만 동일한 테스트 코드가 반복되는 것은 나쁜 소식입니다.
joshin4colours

12

반복은 모든 악의 근원이다

맞아 그거야! 반복은 모든 악의 근원이다 . 아마도 그는 자신의 저서에서“미숙 한 최적화는 모든 악의 근원”이라고 말하면서 Knuth 였지만, 그것이 반복적이라고 생각합니다.

프로그램을 보거나 작성할 때마다 어떤 종류의 반복이 발견 될 때마다 제거하십시오! 그것을 즉시 죽여라. .. 그러나 그것을 제거해라 !

반복을 소개하고 버그를 수정해야 할 때마다 복제본을 수정하는 것을 잊었습니다 ... (Donald Knuth) 반복이있을 때마다 가능한 한 최선을 제거하고 해킹하지 마십시오. !

깔끔하고 간결한 디자인 (예 : 도우미 클래스에 반복 코드 블록 캡슐화)을 생각하고 무언가를 변경하기 전에 테스트하십시오. 이것은 작성된 코드 조각에 해당하며 테스트 코드도 예외는 아닙니다.

다음은 Code Horror의 좋은 글 입니다. 복사 및 붙여 넣기 코드 재사용 학교에 대한 겸손한 제안 .


"매번 반복을 소개하고 거기에 버그를 수정해야 할 때마다 복제본을 수정하는 것을 잊었습니다…" 또한 c & p를하고 복사 한 텍스트를 현재 상황에 맞게 조정하는 것을 잊어 버리면 많은 문제가 발생합니다. 버그가있는 테스트 코드가 최적의 상황처럼 들리지 않습니까?
marktani

그래, 나는 Knuth에서 역을 가져 갔다 :)
Yusubov

9
당신은 자신을 반복했다 : 당신은 제목과 서론에서 "반복은 모든 악의 근원"이라고 말함으로써 스스로를 반복했다.
Thomas Eding

엡, 나는 의도적으로 :) 중요성을 강조하고 일부 먹으 렴 편집에 오신 것을 환영합니다 것을 한
Yusubov

1
토마스 에딩, 당신도 자신을 반복했습니다. 당신도 자신을 반복했습니다 =)
marktani

7

잘라서 붙여 넣기는 여전히 나쁘다. 몇 가지 문제가 있습니다.

복사하여 붙여 넣은 모든 코드를 변경해야하는 대상에 취약하기 때문에 테스트가 취약 할 수 있습니다. 모든 테스트를 다시 작성해야합니까?

테스트 외부의 도우미 메서드로 논리를 캡슐화 할 수 없으면 해당 도우미 메서드 자체의 테스트를 작성할 수 없습니다. 테스트 방법을 테스트하려면 테스트 코드를 작성해야하기 때문에 테스트 방법의 테스트 작성은 일반적으로 가치가 없습니다. 그러나 도우미 메서드를 단위 테스트 할 수 있습니다 .

테스트를 읽기 어렵게 만들 수 있습니다. 복사 된 코드의 큰 블록은 설명이 포함 된 도우미 메서드 호출보다 읽기가 어려울 수 있습니다.

내가 나열한 모든 것은 문제 있습니다. 당신이 그들 중 누구도를 찾을 수없는 경우에는 사실 입니다 물론 그것의 벌금 다음 문제.


> 기술적 인 이름을 가진 헬퍼 메소드 호출. 단위 테스트가 이제 스스로 프로그램이되고 있다는 것은 문제가되지 않습니다. 일부 테스트가 실패하면 어떻게됩니까? 깨진 코드입니까, 아니면 테스트 도우미입니까?
dwjohnston

4

나는 너에게 동의했었다. 그러나 시간이 지남에 따라 모든 변경 사항 (특히 단위 테스트의 DI 변경 사항)을 변경하려면 많은 테스트가 필요했으며 번거로웠다는 것을 알았습니다. 이제 시험을 작성할 때도 DRY 학교에 가입합니다.

GUI 테스트의 경우 반복되는 코드를 줄이기 위해 PageObject 패턴 을 살펴볼 수 있습니다 .


2

XUnit 패턴을 선택하는 것이 좋습니다. 나는 그 책을 활용할 때까지 똑같은 문제를 겪었다. 객체 어머니의 그것과 같은 패턴의 소리는 시나리오에 가장 도움이 될 것입니다.

다른 사람이 언급 했듯이이 설정 코드를 올바르게 캡슐화하면 번거로울 수 있지만 복사하여 붙여 넣은 모든 위치에서 변경 해야하는 것이 훨씬 더 큽니다.


Object Mother pattern공통 초기화 코드 의 경우 +1
k3b

2

사람들이 할 수있을 때 회개를 제한하고 시도해야합니까? 그러나 그 결과는 상황에 따라 다릅니다. 이것은 '모범 사례'토론으로 돌아갈 수 있습니다. 그러나 문제는이 상황에서 가장 적합한 것입니다. 모든 규칙에는 예외가 있습니다.

내가 물어볼 몇 가지 사항은 다음과 같습니다. 1) UAT에서 테스트중인이 기능이 변경 될 가능성은 얼마나됩니까? 변경되지 않을 경우 각 코드 세트를 업데이트해야 할 가능성이 줄어 듭니다. 2) UAT에 변경이있는 경우, 항상 복사 된 각 코드 세트에 영향을 미치거나 하나 또는 두 세트에만 영향을 줄 수 있습니까? 격리되어 있고 한 세트 만 변경해야하는 경우 사물을 분리하는 것이 도움이 될 수 있습니다. 3) 모든 시나리오를 처리하려고하면 초기 방법이 얼마나 복잡합니까? 중첩 된 if / else / loops를 많이 추가하고 있습니까? 모든 분기를 과도하게 시작하면 이해하기 어려운 코드가 생길 수 있습니다. 모든 분기 논리를 다시 방문하는 것보다 복사 된 각 텍스트를 업데이트하는 것이 더 쉬울까요?

복사 / 붙여 넣기 / 변경이 멈 추면 '이것은 메소드 xyz에 복사됩니다'와 같은 주석을 추가하고 싶다고 생각합니다. 이렇게하면 붙여 넣은 모든 코드 버전을 업데이트하라는 메시지가 표시됩니다. 또는 (다른 SilkTest 사용자가 제공하는)이 반복 코드에만 집중할 별도의 inc 파일을 추가 할 수 있습니다. 이렇게하면 한 곳에서 모든 변형이 이루어지고 업데이트가 필요한 다른 방법을 쉽게 볼 수 있습니다.


0

하나의 큰 절차

한 가지 생각 : 다음과 같은 방법으로 cut-n-paste 코드를 피하려고하는 것 같습니다.

testScreen(title, fieldList, linkList, param1, param2, param3,...) {
    test that the layout at the top of the screen is correct
    test if PageTitle == title?
    for each field in fieldList:
        check that it appears in order on the screen
    for each field in linkList:
        check that it appears in order on the screen
    test if param1 is whatever...
    test if param2 is whatever...
    etc.
    test that the bottom of the screen is correct
}

많은 작은 절차 (툴킷)

반대의 접근 방식도 고려 했습니까? 하나의 큰 testScreen () 프로 시저에 백만 개의 매개 변수를 전달하는 대신 필요에 따라 채울 작은 도우미 프로 시저로 자체 프레임 워크 또는 툴킷을 작성할 수 있습니다. 처럼:

testScreenTop()
verifyLinks(list)
testScreenBottom()

여전히이 절차를 잘라내어 모든 화면에 붙여 넣지 만 작은 코드 조각을 잘라 붙여넣고 잘라 내지 않고 붙여 넣지 않은 공통 부분 (각 작은 절차의 내용)을 조각합니다.

잘라 붙여 넣기

코드를 잘라 내지 않은 유일한 시간은 코드를 변경하기 전에 코드를 버릴 때였습니다. UI 테스트에 대한 나의 가장 큰 관심사는 얼마나 빨리 쓸모 없게 되는가입니다. 코드를 변경하기 전에 모든 코드를 버린다면 잘라내어 붙여 넣기가 가능한 틈새를 발견했을 것입니다! 또한 잘라서 붙여 넣은 코드의 다운 스트림 코드가없는 경우 (예 : 응용 프로그램의 UI) 그렇게 나쁘지 않습니다. 3 줄 이상을 붙여 넣는 경우 실제로 그것에 대해 뭔가를 고려할 것입니다. 최소한 최소화하기위한 조치를 취하십시오!

자동화 된 UI 테스트

그렇습니다. 어떤 기술을 사용 하는 수동 테스트보다 자동화 된 UI 테스트를 통해 생산성을 향상시킬 수 있다면 (자동 테스트를 작성 / 유지하는 비용은 매번 수동으로 테스트하는 것보다 저렴하지만 품질은 동일합니다) 종이를 작성해야한다고 생각합니다. 나는 그것을 읽을 것이다! 이제 제목을 볼 수 있습니다. "UI 테스트를위한 코드 잘라 내기 및 붙여 넣기!"


0

정말 그렇게 나쁘지 않습니다. 실제로 특정 코드 패턴이 매우 자주 사용되고 변경이 매우 일상적인 경우 (예 : 몇 개의 문자열 또는 매개 변수 값), 작은 코드를 기반으로 반복 테스트 코드를 생성하는 코드 생성기를 작성할 수도 있습니다 (- ish?) 변경되는 값의 입력 목록입니다. 배치 파일, SQLPlus 스크립트, 심지어 Excel 매크로 (추악한 소리가 들리지만 다른 테스트 스크립트의 변수는 이미 스프레드 시트에 있음)를 사용 하여이 (생성 테스트 코드)를 여러 번 수행했으며 시간을 크게 절약 할 수 있습니다. . 문제는 반복 테스트 사례 코드의 전체 구조에서 변경 사항이 있으면 필요한 것을 다시 생성 할 수 있다는 것입니다.


0

이는 대부분의 다른 답변과 동일하지만 기술 관리자가 아닌 사람이 이해할 수있는 방식입니다.

다음과 같은 오류 시나리오를 상상해보십시오.

  • 누군가는 많은 테스트가 의존하는 데이터베이스 테이블을 변경합니다.
  • 결과 : 2933 개의 자동 테스트 중 117 개가 갑자기 실패합니다.

당신은 무엇을 할 것인가?

  • (1) 117 개의 테스트를 수정 하시겠습니까?
  • (2) 117 개의 테스트를 삭제하고 새로운 복사 및 붙여 넣기를 통해 다시 구현하십시오. 이것은 (1)보다 쉬울 수 있습니다
  • (3) 공통 코드를 추출하도록 테스트를 리팩터링하여 향후 테스트를 수정하기 위해 하나의 방법 (또는 몇 가지) 만 적용해야합니다 (@pdr 또는 @Michael Brown의 답변 참조)
  • (4) 테스트를 다시 구현하지 않고 117 테스트를 삭제하십시오.

내 경험에서 :

자동화 된 테스트 관리를 도입 할 때 "복사 및 붙여 넣기 테스트"를 좋아합니다. 단시간에 많은 테스트를받습니다.

"오류 시나리오"중 일부는 "복사 및 붙여 넣기 테스트"를 수정하는 것이 비용이 많이 들기 때문에 (4)를 선호합니다.

첫 번째 장소에서 바로 수행하십시오 (3) 그렇게 빠르지는 않지만 테스트가 생존 할 확률을 높입니다.

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