"통과 / 깨진 빌드"표시기의 대안?


14

각 커밋에서 테스트를 지속적으로 통합 할 때 가장 좋은 방법은 모든 테스트를 항상 통과시키는 것입니다 (일명 "빌드를 중단하지 마십시오").

나는 그것에 대해 몇 가지 문제를 발견했다.

예를 들어 티켓에 해당하는 테스트를 작성하여 오픈 소스 프로젝트를 도울 수 없습니다. 실패한 테스트가 포함 된 오픈 소스 프로젝트에 풀 요청을 제안하면 빌드가 실패한 것으로 표시되고 프로젝트가 "빌드를 깨뜨릴"것이기 때문에 저장소에 병합되지 않을 것입니다.

그리고 리포지토리에서 테스트에 실패한 것은 나쁜 일이라고 생각하지 않습니다 . 트랙커에 공개 문제가있는 것과 같습니다. 이것들은 단지 고치기를 기다리는 것입니다.

회사에서도 마찬가지입니다. TDD로 작업하는 경우 테스트를 작성하고 커밋 한 다음 테스트를 수행하는 논리 코드를 작성할 수 없습니다. 즉, 랩톱에서 4-5 개의 테스트를 작성했다면 휴가를 가기 전에 테스트 할 수 없습니다. 아무도 내 일을 되 찾을 수 없습니다. 예를 들어 이메일로 보내는 것 외에는 동료와 "공유"할 수 없습니다. 또한 한 사람이 테스트를 작성하고 다른 사람이 모델을 작성하는 것을 방지합니다.

말하자면, 빌드 프로세스 / 지속적인 통합을 오용 / 오해하고 있습니까? "통과"/ "통과하지 않음"은 너무 좁은 표시기 인 것 같습니다.

지속적인 통합 및 TDD 호환 방법이 있습니까?

어쩌면 "새로운 테스트"(즉, 실패 할 수 있습니다) 및 "회귀 테스트"(즉,해야 구별하는 표준 용액 / 연습이 없는 그들이 작업에 사용했기 때문에 실패)?


1
지난 1 시간 동안 실패한 테스트 수가 증가 (적색) 또는 감소 (녹색) 되었는지 표시하는 표시기가 있습니다.
Joachim Sauer 2013

2
나는 TDD / ALM 전문가가 아니므로 (답변이 아닌 의견) 개인 지점 / 기능 지점으로 문제를 해결할 수 있다고 생각합니다. 기능 A에서 작업하고 있습니까? 분기하고, 동료와 함께 지점에서 작업하고, 완료되면 지속적으로 통합 된 트렁크에 병합하십시오.
Avner Shahar-Kashtan

@JoachimSauer 예.하지만 주요 프로젝트에서 이러한 메트릭이 표준화 / 사용됩니까? 대부분의 프로젝트 (및 CI 도구)가 왜 그렇게 작동하는지 이해하려고합니다.
Matthieu Napoli

"실패 할 수있는 테스트"에 대한 올바른 기준은 "새로운 테스트"가 아니라 "알려진 공개 문제에 대한 테스트"라고 생각합니다. 이러한 테스트가 어떻게 유용한 지 알 수 있습니다. 또한 테스트 통과 / 실패의 의미를 오염시키기 때문에 CI 빌드에서 해당 테스트가 유용하지 않은 방법도 볼 수 있습니다. 통과시키기 위해).
Joris Timmermans

@MadKeithV 정확하게
Matthieu Napoli

답변:


12

어디에서 왔는지 알지만 이러한 유형의 문제는 일반적으로 다른 방법으로 해결됩니다. 이것이 표준 프로토콜 인 이유는 충분합니다. 누군가 컴파일되지 않은 코드를 제출하면, 코드를 업데이트하는 모든 사람은 컴파일되지 않는 프로그램을 갖게됩니다 . 여기에는 현재 완전히 다른 무언가를 작업하는 프로그래머가 포함되며 어떻게 든 작업하고 있는지 컴파일하고 테스트하기 전에 기다려야하는 상황에 처하게됩니다.

표준 프로토콜은 프로그래머가 필요한 경우 매일 코드를 업데이트 할 수 있도록 컴파일 되는 한 완전하거나 불완전한 작업에도 변경 사항을 적용 할 수 있다는 것 입니다.

그러나 여전히 당신이 무엇을 얻고 있는지 알 수 있습니다. 때로는 단순히 코드 를 저장 하기 위해 커밋하려고합니다 . 이를 위해 대부분의 소스 리포지토리는 분기를 지원합니다. 이를 통해 개인 브랜치를 생성하고 다른 브랜치를 방해하지 않고 작업 한 다음 작업이 완료되면 트렁크에 병합 할 수 있습니다. 이를 통해 빌드 중단과 관련된 백래시없이 커밋 할 수 있습니다.

이것이 적합하지 않은 경우 GIT를 사용하면 로컬 컴퓨터의 리포지토리에 커밋 (푸시) 할 수 있지만 리포지토리는 어디에나있을 수 있습니다. 잠재적으로 부분 / 불완전한 작업을위한 저장소와 완료된 작업을위한 다른 저장소를 작성할 수 있으며 해당 저장소에서 야간 빌드를 추가 할 수 있습니다.

다시 말하지만, 나는 그 중요성을 충분히 강조 할 수 없습니다. 깨진 코드를 트렁크에 커밋하지 마십시오! 귀하의 기여는 다른 프로그래머의 작업에 영향을 줄 수 없습니다.

편집하다

나는 당신이 깨진 테스트를 의도 한 것을 보았지만, 겸손한 의견으로는 거의 차이가 없습니다. 테스트의 요점은 프로그램의 특정 측면이 합격 또는 불합격인지 확인하는 것입니다. 항상 실패하고 아무것도하지 않으면 전통적인 단위 테스트 사용법에서 테스트는 아무 것도 수행하지 않습니다. 이러한 테스트 중 하나가 실패 할 경우 반드시 "실패한"커밋을 수반하지 않는 다른 메트릭을 수행하는 데 사용하는 경우 동일한 작업을 수행하는 다른 방법을 찾는 것이 좋습니다.

그렇지 않으면 테스트를 고려하지 않거나 빌드가 실패 할 경우 동료 프로그래머가 실패한 빌드를 무시할 위험이 있습니다. 프로그래머는 실제 통찰력을 제공하지 않고 나쁜 관행 만 초래할 수있는 테스트를 수행하는 것보다 빌드를 중단 한 시점을 인식하는 것이 더 중요합니다.


1
실제로 당신은 주제 지점을 지적합니다. 그러나 나는 깨진 코드를 커밋하는 것에 대해 이야기하지 않고 테스트를 실패합니다. 예를 들어, 티켓 수정 방법을 모르더라도 들어오는 티켓에 대한 테스트를 작성하여 오픈 소스 프로젝트를 도울 수 있습니다. 이는 관리자에게 시간을 절약 해줍니다.
Matthieu Napoli

내가 당신과 같은 프로젝트에서 작업하고 실패한 테스트를 업로드하면 실패한 테스트가있는 빌드가 생깁니다. 해당 기능이 아직 구현되지 않았기 때문에 테스트를 삭제하거나 기능을 구현하기로 결정하고 코드가 낭비되고 시간이 낭비 될 수 있습니다. 이렇게하는 문화가 있다면, 그런 종류의 반응은 피할 수 있지만, 모든 사람들이 그렇게 할 것입니다. 심지어 모든 시험이 통과 되더라도 모든 것이 아닙니다. 이 경우 빌드 에는 항상 테스트가 실패합니다. 나는 거꾸로 보이지 않습니다.
Michael Shaw

the build would always have failing tests정확히! 그러나 그것은 그렇게 나쁜 것입니까? 우리의 유일한 메트릭은 "빌드가 깨 졌거나 아님"이지만 코드에 알려진 버그가 가득 차서 회귀가 없다는 것을 의미하는 것은 아닙니다. 완벽한 세상에서 모든 트래커 문제는 테스트를 거치게됩니다. 따라서 모든 테스트의 35 개 테스트 / 70 %가 통과하고 분기 A가 회귀없이 40 개 테스트 (80 %)로 개선되고 분기 B에 회귀가 있음을 확인할 수 있습니다. 오늘은 Master와 Branch-A는 정상이고 Branch-B는 고장 났다고 말할 수있었습니다.
Matthieu Napoli

@ Matthieu 나는 당신이 무엇을 받고 있는지 참조하십시오. "이 테스트가 실패하면 괜찮습니다. 우리는 그것에 대해 알고 있습니다. 그러나 우리는 여전히 실행을 원하고 통과하면 더 나아지고 특수 범주를 제거해야합니다. 우리는 이제 그것이 깨 졌는지 걱정한다 "
Earlz

@Earlz 정확하게! 내가 궁금해하는 것은 "어딘가에 의해 이루어 졌습니까? 그리고 그것을 지원하는 툴이 있습니까 (CI 및 단위 테스트 라이브러리)?"고전적인 CI 및 단위 테스트 도구로 테스트를 분류하면 빌드는 항상 어쨌든 실패하고 어떤 테스트가 실패했는지에 대한 차이점을 볼 수 없으므로 유용하지 않습니다 : /
Matthieu Napoli

4

테스트에 실패한 마스터 브랜치가 주어지면 목록을 이전 빌드와 비교하지 않고 버그를 도입하지 않았다는 것을 어떻게 확신 할 수 있습니까?

실패한 테스트 수를 추적하는 것만으로는 충분하지 않습니다. 한 테스트를 수정하고 다른 테스트를 중단 할 수 있습니다. 휴가 중이라면 실패한 빌드를보고있는 다른 사람들에게는 분명하지 않습니다.

항상 마스터 지점을 깨끗하고 녹색으로 유지하십시오 . 지점에서 일하십시오. 지점을 CI 아래 별도의 작업으로 유지하고 마음의 내용에 대한 테스트에 실패했습니다. 그냥 마스터를 깨지 마십시오.

지점의 검토자가 모든 테스트를 통과 한 경우에만 지점을 병합하도록하십시오. (더 강하게 : 지점을 병합 한 결과가 모든 테스트를 통과하면 검토자가 지점을 병합 할 수있게하십시오!)


2
Simply tracking the number of failing tests is insufficient이것이 유일한 메트릭은 아닙니다. 예를 들면 다음과 같습니다 Branch-A improves it to 40 tests (80% passing) with no regression.. 회귀 없음은 이전에 통과 한 테스트가 항상 통과 함을 의미합니다. 요컨대, 테스트는 결코 통과하지 않는 한 실패 할 수 있습니다. 주요 지점에서 실패한 테스트를 금지하도록 제한함으로써 좋은 일을 놓치고있는 것 같습니다. (물론 다르게 작동하는 도구가 필요할 것입니다 : 단위 테스트, CI, ...)
Matthieu Napoli

나는 여전히 내 입장을 고수하고있다 : 주인은 명확하고 모호하지 않기 때문에 항상 녹색 이어야한다 . 피처 브랜치에서 마커 테스트가 실패했습니다. CI는 사람들에게 뛰어난 버그를 계속 상기시켜 줄 수 있습니다.
Frank Shearar

나는 Matthieu가 제안하는 것은 "녹색"에 대한 약간 다른 정의이며 항상 녹색 인 마스터에서 벗어나지 않는다고 생각합니다. 이해가되지 않는다는 것은 분명하지 않습니다. 물론 추적을 위해 사소한 툴링이 필요하지는 않습니다. (테스트를 통과 한 변경 사항을 롤백해야합니까? 만약 그 상태가 갑자기
붉다

NUnit은 무시 된 테스트 개념을 가지고 있습니다. 대안이 될 수도 있습니다. 실행되지 않아 실패하지는 않지만 여전히 무시되는 것으로보고됩니다.
Frank Shearar

2

지속적인 통합에 대한 잘 이해되고 수용된 관행을 버리지 않고 문제를 해결할 수있는 방법이 있습니다.

티켓에 해당하는 '파산 테스트'를 시작하는 문제부터 시작하겠습니다. 한 가지 해결책은 문제를 드러내는 하나 이상의 주요 테스트를 만든 다음 실제로 문제를 해결 하여 주 코드 줄에 다시 병합 할 수 있도록하는 것입니다. 두 번째 해결책은 테스트를 중단하는 것이지만 실제로 무시 하고 빌드하지 않도록 일부 무시 플래그를 사용 하는 것입니다. 이 테스트에 대한 테스트가 실패했음을 명확히 하는 주석 또는 특수 주석추가 할 수 있습니다Ticket#N . 또한 무시 및 실행 대기중인 작성된 테스트를 나타내는 티켓 자체에 메모를 첨부하십시오 . 이것은 티켓을 고치는 사람에게 도움이 될 것이지만, 시험을 보는 사람에게는 붉은 깃발이 아닙니다.

그리고 TDD의 다음 문제에. TDD는 작은 테스트를 작성한 다음 작은 테스트 덩어리를 작성하여 테스트에 합격하는 것 입니다. 그런 다음 작은 기능 모듈이있을 때까지 반복하십시오. 4-5 번의 시험을 썼다면 휴가를 갔다면 잘못하고있는 것 같습니다. 테스트 중 하나를 작성하고 다른 하나는 해당 코드를 작성하여 프로그램을 다른 사람과 페어링 할 수 있습니다. 그러나 완성 된 모듈을 커밋 할 준비가되기 전에 기본 코드 라인 리포지토리를 사용하여이 코드를 공유하지 않아야합니다. 다른 사람들이 제안했듯이 공유 지점은 문제를 해결할 것입니다.

지속적인 통합 만트라를 깨려고하면 예상치 못한 무서운 길로 이어질 수 있습니다. 예를 들어, 이 유형의 환경에서 코드 범위는 무엇을 의미 합니까? 개발자들은이 시스템에 많은 " Broken Windows " 가 있다고 생각하지 않습니까? 어떻게 변경하고, 테스트를 수행하고, 실제로 새로운 것을 깨고 있는지, 아니면 오래된 것만 알 수 있습니까?


페어링 프로그래밍을하는 사람과 공유하기 위해 툴링이 필요하지 않습니다. 키보드를 넘기면됩니다. 다른 컴퓨터를 사용하고 있다면 아무 문제가 없습니다. 단지 "페어 프로그래밍"이 아닙니다.
Christopher Creutzig 2016 년

1

근본적인 문제는 빌드의 일부로 테스트 결과를 포함시키는 것입니다. 분명히 어떤 사람들은 당신에 동의하지만 다른 사람들은 그렇지 않습니다. 빌드하지 않으면 빌드가 중단됩니다. 오류없이 빌드되지 않을 때는 아닙니다.

Windows 또는 Linux와 같은 주요 프로젝트 또는 Firefox와 같은 프로젝트를 고려하십시오. 버그가 없다고 생각하십니까? 당연히 아니지. 이제 이러한 프로젝트는 TDD를 수행하지 않지만 실제로는 관련이 없습니다. TDD는 두 가지 기본 사실을 변경하지 않습니다. 버그가 존재하며이를 해결하는 데 시간이 걸립니다. 프로젝트 (오픈 소스인지 아닌지)가 우선 순위가 낮은 버그를 낭비 할 수없는 시간. KDE는 최근 10 년 이상 수정 된 버그를 가지고있었습니다. "프로젝트를 시작하기 위해 10 년을 기다렸 다니 기쁘다"라는 말을 마지막으로들은 적이 언제입니까?

어떤 방식 으로든 TDD는 버그를 쉽게 제공 할 수 있습니다. 결함이 무엇인지 더 잘 이해할 수 있기 때문입니다. 버그의 원인을 정확하게 정의 할 수 있으면 버그 수정 비용을 계산할 수있는 훌륭한 근거가됩니다.

내 추천은 녹색을 띤 빨간색을 신경 쓰지 않는 프로젝트를 찾는 것입니다.


1
 > a common best practice is to have all the tests passing (green) at all times.

모든 테스트 가 실패하지 않는 것을 선호합니다 (빨간색이 아님).

이 약간 다른 정의를 사용하면 다음과 같은 테스트를 정의 할 수도 있습니다

  • 아직 구현되지 않음 (NotImplementedException이있는 경우 nunit에서 회색)
  • 테스트를 무시 됨 (노란색)으로 표시 / 주석으로 표시하여 "실패해야합니다"

지속적인 빌드가 손상되지 않았으므로 유효 한 저장소에 이것들을 저장소에 체크인합니다.


0

두 가지 CI 빌드 "개념"을 고려할 수 있습니다.

  1. 정기적 인 CI 빌드. 일반 CI 빌드는 테스트 통과 / 실패에 대한 CI 보고서가 이전에 승인 된 코드 상태에 대한 명확하고 명확한 회귀 지표가되도록 코드가 작성된 테스트 만 컴파일하고 실행해야합니다.
  2. "미래"CI 빌드. 이 빌드는 코드를 특별히 작성하지 않은 테스트 만 컴파일하고 실행합니다. 이러한 테스트를 받아야하는 몇 가지 이유가있을 수 있습니다.

    • 아직 문제를 해결하지 않은 이슈 트래커에서 특정 실패 사례에 대한 테스트를 추가 할 수 있습니다. 수정 없이도 문제에 대해 체계화 된 테스트를 이미 실행하는 것이 분명히 유용합니다.

    • 아직 구현되지 않은 새로운 필수 기능에 대한 테스트가 추가되었습니다.

    • 기능 또는 수정을 구현하는 방법을 아는 것보다 실패 또는 기능을 테스트하는 방법을 아는 것이 더 쉬운 경우가 많으며 테스트를 소스 제어에 적용하여 두 단계를 분리하면 정보가 손실되지 않도록하는 데 유용 할 수 있습니다.

"표준"CI에서와 같이 정규 개발 체제에서 팀은 정규 빌드의 일일 빌드 결과 만보고 있습니다.

또한 팀은 "미래"CI 빌드에서 테스트 사례의 진화를 주시 할 수 있습니다. 특히 일반 CI에 대한 변경 사항이 실제로 "미래"빌드의 문제를 해결하는지 여부를 확인할 수 있습니다. 이는 중요한 표시 일 수 있습니다. 근본적인 문제 또는 디자인 개선.

마지막으로, 팀원이 추가 시간을 갖고 있다면 "미래"에서 문제 중 하나를 수정하고 문제가 "일반"(문제 추적기 상태를 업데이트하는 동안)으로 마이그레이션하는 것을 살펴볼 수 있습니다.


0

또한 리포지토리에서 테스트에 실패한 것은 나쁜 일이라고 생각하지 않습니다. 트래커에서 열린 문제가있는 것과 같습니다. 이것들은 단지 고치기를 기다리는 것입니다.

문제는 테스트에 실패하지 않고 단순하고 컨텍스트가 적은 회귀 표시기입니다. 일명 : 개발자로서 단일 지표를 확인하고 회귀 또는 침입 코드를 도입했는지 알 수 있습니까?

'소프트'실패의 개념을 소개하는 순간 (괜찮습니다. 우리는 아직 작동하지 않고 / 아직 구현되지 않았으며 / 새 버전을 기다리고 있습니다 /이 다른 빌드가 수정되면 다시 전달됩니다) 예상 상태를 알기 위해 테스트를 실행하거나 볼 수있는 모든 사람. 충분히 큰 팀에서 시간이지나면서 변경 될 것입니다. 지표는 의미가 없습니다. 더 작은 맥락 (예 : 팀 개인 통합 테스트)에서는 기술적 부채와 같으며 괜찮습니다. 관리하면됩니다.

'녹색 / 통과'라는 대부분의 도구 주소 방식은 코드가 작동하는 것이 아니라 예상 결과를 반영합니다.

  • 피트니스에는 예상되는 실패라는 개념이 있습니다.
  • JUnit에는 @Ignored / @Test (expect =)가 있습니다.
  • 오이는 '아직 구현되지 않음'(또는 호출 된 것) 상태입니다.

그들에게는 자체 문제가 있습니다 ( '예, 우리는 그것이 깨 졌다는 것을 알고 있습니다.'와 '올바른 행동은 예외입니다')를 구별합니까?


0

건너 뛴 테스트를 사용합니다.

내가 사용하는 특정 단위 테스트 프레임 워크에서 SkipTest 예외를 발생시킬 수 있습니다. 테스트는 실제로 실행되지 않으며 실패해도 빌드가 중단되지 않습니다. 그러나 건너 뛴 테스트 수와 해당 영역에서 수행 할 작업이 있는지 확인할 수 있습니다.

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