CI 서버에서 단위 테스트를 실행하는 요점은 무엇입니까?


98

CI 서버에서 단위 테스트를 실행하는 이유는 무엇입니까?

확실히 무언가를 마스터하기 위해 개발자는 이미 모든 단위 테스트를 실행하고 새 코드로 발생했을 수있는 오류를 수정했습니다. 그것이 단위 테스트의 요점이 아닌가? 그렇지 않으면 그들은 깨진 코드를 커밋했습니다.


51
우리 개발자는 마스터 할 수 없습니다. CI를 기능 분기로 푸시 한 다음 CI 서버는 마스터와 병합하고 테스트를 실행합니다. 그들이 성공하면, 다음 변화는 마스터에 병합됩니다. 따라서 깨진 테스트 코드는 마스터가 될 수 없습니다 ...
스파이더 보리스

2
@BoristheSpider-정말 좋은 워크 플로. master내부 QA 및 테스트를 위해 스테이징 환경에 병합 할 때마다 항상 제자리에 있어야하며 자동으로 배포됩니다.
Per Lundberg

130
"물론, 무언가를 마스터하기 위해 노력할 때까지 개발자는 이미 모든 단위 테스트를 실행하고 새 코드에서 발생할 수있는 모든 오류를 수정했습니다." 어떤 환상의 세계에 살고 있습니까?
jpmc26

5
일부 산업에서 중요한 부분은 코드에서 테스트를 실행하는 것이 아니라 바이너리 에서 테스트를 실행하는 것 입니다. CI 출력에서 ​​테스트를 실행하면 클라이언트가받은 정확한 바이너리가 모든 테스트를 통과 한 바이너리이기 때문에 배송 된 제품이 작동하는지 보장 할 수 있습니다. 사소한 것처럼 들리지만 때로는 효과가있을 수 있습니다 (내가 본 것은 난독 화입니다. 복잡한 프로젝트에서 또는 이상하게 설정하면 깔끔한 버전에는 없었던 난독 화 된 빌드에 문제가 발생할 수 있습니다).
anaximander

5
"물론, 마스터하기 위해
노력할

답변:


223

확실히 무언가를 마스터하기 위해 개발자는 이미 모든 단위 테스트를 실행하고 새 코드로 발생했을 수있는 오류를 수정했습니다.

아님 이런 일이 발생할 수있는 많은 이유가있을 수 있습니다

  • 개발자는 그렇게 할 수있는 원칙이 없습니다
  • 그들은 잊었다
  • 그들은 모든 것을 커밋하지 않았고 불완전한 커밋 세트를 밀었습니다 ( Mathieu M에게 감사드립니다 .
  • 그들은 몇 가지 테스트 만 실행했지만 전체 스위트는 아닙니다 (감사합니다 nhgrif )
  • 그들은 병합하기 전에 지점에서 테스트했습니다 (감사합니다 nhgrif * 2).

그러나 실제 요점은 개발자 머신이 아닌 머신에서 테스트를 실행하는 것입니다. 다르게 구성된 것.

이를 통해 테스트 및 / 또는 코드가 개발자 상자에 특정한 항목 (구성, 데이터, 시간대, 로캘 등)에 의존하는 문제를 파악할 수 있습니다.

CI 빌드가 테스트를 실행하는 다른 좋은 이유 :

  • 기본 개발 플랫폼 이외의 다른 플랫폼에서 테스트하기 때문에 개발자가 수행하기 어려울 수 있습니다. ( TZHX 감사 합니다 )
  • 일반적으로 개발자 상자에서 실행되지 않는 CI 서버에서 수락 / 통합 / 종료 / 실시간 장기 실행 테스트를 실행할 수 있습니다. ( Ixrec 감사 합니다 )
  • 개발자는 푸시 / 커밋하기 전에 약간의 변경을 수행 할 수 있습니다 (안전한 변경이라고 생각하므로 테스트를 실행하지 않음). ( Ixrec * 2 감사합니다 )
  • CI 서버 구성에는 일반적으로 모든 개발자 도구 및 구성이 포함되어 있지 않으므로 프로덕션 시스템에 더 가깝습니다.
  • CI 시스템은 매번 처음부터 프로젝트를 빌드하므로 빌드를 반복 할 수 있습니다.
  • 라이브러리 변경으로 다운 스트림에 문제가 발생할 수 있음-라이브러리 서버 뿐만 아니라 모든 종속 코드베이스 를 빌드하도록 CI 서버를 구성 할 수 있음

36
다른 일반적인 이유 : 1) CI 서버는 개발자가 항상이를 실행하는 데 시간이 오래 걸리는 고급 통합 / 수락 테스트를 실행할 수 있습니다. 2) 개발자가 실행 한 다음 아무 것도 깨지 않을 것이라고 확신하기 전에 약간의 변경을가했지만 확실하게 알고 싶습니다.
Ixrec

11
의존성에 대한 변경은 종종 모든 다운 스트림 빌드도 실행합니다. 개발자가 변경 한 내용이 다운 스트림에 영향을 미치는 경우 라이브러리를 수정할 때 (기본 데이터 유형을 SortedSet에서 HashSet으로 변경 (Set 계약 만 제공)) 쉽게 알 수 없으며 다운 스트림 누군가가 잘못된 가정을 수행 한 경우 세트가 정렬되었습니다). CI 서버에서 (다운 스트림) 테스트를 실행하지 않으면 해당 버그가 잠시 사라질 수 있습니다.

2
@MichaelT 잘 잡았습니다. 실제로 요즘 CI 고장의 90 % 이상이 원인입니다. 어떻게 잊었는지 잘 모르겠습니다.
Ixrec

34
또한 CI 환경에서 실행하면 일반적으로 프로젝트 를 처음부터 설정 하여 빌드를 반복 할 수 있습니다 .
mgarciaisaia

5
또한 별도로 테스트해도 괜찮은 두 가지 변경 사항을 커밋 할 수 있지만 함께 사용하지 마십시오 (예 : 하나는 사용하지 않는 API 제거 및 다른 하나는 사용 시작).
Simon Richter

74

소스 제어에 전념하기 전에 모든 통합 및 단위 테스트를 실행하지 않는 개발자로서 여기서 방어를 제공 할 것입니다.

응용 프로그램이 올바르게 실행되는지 빌드, 테스트 및 확인해야합니다.

  • Visual Studio 2008 컴파일러가 포함 된 Microsoft Windows XP 및 Vista
  • Visual Studio 2010 컴파일러가 포함 된 Microsoft Windows 7
    • 아, 그리고 MSI는 각각을 위해 빌드합니다.
  • RHEL 5 및 6 (각각 4.1 및 4.4) (유사한 CentOS)
    • 곧 7입니다. p 드 woo.
  • 최근 3 개의 최신 버전에 대한 GCC가 포함 된 Fedora Workstation.
  • 최근 3 개의 최신 버전에 대한 데비안 (및 우분투와 같은 파생어).
  • 최근 3 가지 최신 버전의 Mac OSX
    • 그리고 패키지 (rpm, dmg 등)

Fortran (Intel 및 GNU 컴파일러 모두 포함), Python (및 OS에 따라 다양한 버전) 및 bash / bat 스크립트 구성 요소를 추가하면 나선을 볼 수 있다고 생각합니다

그래서 그것은 하루에 두 번 몇 번의 테스트를 실행하기 위해 내가 가지고 있어야 할 16 대의 머신입니다. 이를 위해 인프라를 관리하는 것은 거의 전일제 일입니다. 나는 거의 모든 사람이 불합리하다는 것을 동의 할 것이라고 생각합니다. 특히 프로젝트에있는 사람들의 수에 그것을 곱하는 것입니다. 따라서 CI 서버가 작업을 수행하도록합니다.

그들이 경우 단위 테스트는 당신이 깨진 코드를 커밋 중지하지 마십시오, 그들은 당신을 말할 알고 당신이 뭔가를 파괴했습니다. 사람들은 "단위 테스트는 빨라야한다"고 말하고 원리와 디자인 패턴 및 방법론에 대해 진행할 수 있지만 실제로는 반복적이고 단조로운 작업을 위해 설계된 컴퓨터가 그러한 작업을 수행하고 참여하는 경우에만 참여하는 것이 더 나은 경우가 있습니다 그들이 뭔가를 찾았다 고 말해줘


3
단위 테스트는 코드 구성이 아닙니다. 새로운 테스트를 추가하고 로컬에서 먼저 실행하지 않고도 벽에 던질 수 있습니다.
Robbie Dee

33
@RobbieDee 당신의 요점이 보이지 않습니까? 나는 로컬로 테스트하거나 맹목적으로 그들에게 자신을 테스트하지 않고 소스 제어에 물건을 확인하지 않고 새로운 테스트를 작성하지 않는 것이 좋습니다, 나는 것이 내 자신의 컴퓨터에서 테스트를 실행 -하지만 "구성"일관된 동작을 테스트 할 필요가 않습니다 , 주로 Mac을 사용하는 팀이 4 천 마일 떨어진 곳에서 일어나 사본을 업데이트 할 때 문제를 찾는 것보다 개발자의 생각이 여전히 해당 영역에있을 때 비교적 빠르게하는 것이 좋습니다.
TZHX

7
@RobbieDee 나는 TZHX가 실행됩니다 말하고 싶지만 모두 가 그렇게 할 수 있다면 로컬 테스트를하지만, 그들은 할 수 없습니다 . TZHX는 로컬 테스트를 수행 할 수 없기 때문에 (예를 들어 개발 시스템에서 실행되고 변경된 코드와 충분히 짧거나 가장 짧은 테스트) CI 시스템에서 전체 배터리가 실행되도록합니다. 상당히 합리적입니다.
muru

11
@RobbieDee : 그는 단위 테스트를 믿습니다. 그래서 그는 자신의 Macbook air에서 테스트하고 통과하고 체크인합니다. 그런 다음 Red Hat, Solaris 및 Windows를 실행하는 CI 서버는 해당 테스트를 다시 실행합니다. 테스트 한 것이 프로덕션 플랫폼에서도 작동한다는 것을 아는 것이 좋지 않습니까?
slebetman

2
@ RobbieDee : 종종 특정 플랫폼의 특정 컴파일러와 관련된 단위 테스트를 작성했습니다. 예를 들어 g ++ (GNU C ++ 컴파일러) 버전 4.5 이상에서만 사용할 수있는 AMD (Intel 경쟁 업체) 특정 CPU 명령어를 사용하는 그래픽 하위 시스템을 고려하지만 Atom CPU 및 ICC (Intel C ++)에서 작업합니다. 컴파일러). 해당 머신에서 매번 AMD / g ++ 4.5-tests를 실행하는 것은 말이되지 않지만 릴리스 전에 테스트 할 코드입니다. 또한 내 자체 CPU 독립적 인 코드는 적절한 상호 운용성을 테스트해야합니다. 물론 VM과 에뮬레이터가 있습니다.
phresnel

23

탁월한 Oded 답변 외에도

  • 저장소에서 코드를 테스트합니다 . 커밋을 잊어 버린 파일로 컴퓨터에서 작동 할 수 있습니다. 작성 스크립트 (예 : liquibase)가없는 새 테이블, 일부 구성 데이터 또는 특성 파일에 따라 달라질 수 있습니다.
  • 코드 통합 문제를 피하십시오. 한 개발자가 마지막 버전을 다운로드하고, 단위 및 통합 테스트를 작성하고, 코드를 추가하고, 자신의 컴퓨터에서 모든 테스트를 통과하고, 커밋하고 푸시합니다. 다른 개발자도 같은 작업을 수행했습니다. 두 가지 변경 사항은 모두 적절하지만 병합되면 버그가 발생합니다. 이는 저장소 병합이거나 충돌로 감지되지 않은 것일 수 있습니다. 예를 들어 Dev 1은 전혀 사용되지 않은 파일을 삭제합니다. 이 파일에 대해 Dev 2 코드가 작성되고 Dev 1 변경없이 테스트됩니다.
  • 리포지토리에서 자동으로 배포 할 스크립트를 개발합니다. 보편적 인 빌드 및 배포 스크립트를 사용하면 많은 문제가 해결됩니다. 일부 개발자는 모든 사람이 공유하지 않는 lib 또는 컴파일 옵션을 추가했을 수 있습니다. 이렇게하면 시간이 절약 될뿐만 아니라 배포가 안전하고 예측 가능해집니다. 또한 저장소에서 버전 2.3.1로 돌아가서이 버전에서 작동하는 스크립트를 사용하여이 버전을 배치 할 수 있습니다. 여기에는 뷰, 저장 프로 시저, 뷰 및 버전 관리해야하는 트리거와 같은 데이터베이스 개체가 포함됩니다. 또는 실행 가능한 버전으로 돌아갈 수 없습니다.
  • 기타 테스트 : 통합, 성능 및 엔드 투 엔드 테스트와 유사합니다. 속도가 느릴 수 있으며 Selenium과 같은 테스트 도구가 포함될 수 있습니다. 모의 객체 또는 HSQL 대신 실제 데이터베이스가있는 전체 데이터 세트가 필요할 수 있습니다.

병합 및 배포 프로세스로 인해 배포에 많은 버그가있는 회사에서 근무한 적이 있습니다. 이것은 테스트와 CI를 어렵게 만드는 이상한 독점적 프레임 워크로 인해 발생했습니다. 개발에 완벽하게 작동하는 코드가 프로덕션에 적합하지 않다는 것을 알게 된 것은 행복한 경험이 아니 었습니다.


그러나 변경 사항 중 일부를 커밋하는 것을 잊어 버리는 것은 매우 일반적입니다. 새 파일을 "svn add"하는 것을 잊고 나중에 커밋하는 것을 잊는 것이 실패한 자동 빌드를 얻는 가장 일반적인 방법입니다.
sharptooth

22

당신은 그렇게 생각하지 않을 것입니다-그러나 개발자는 인간이며 때로는 잊어 버립니다.

또한 개발자는 종종 최신 코드를 가져 오지 못합니다. 체크인 시점에 최신 테스트가 제대로 실행될 수 있으며 다른 누군가가 중대한 변화를 저지 릅니다.

테스트는 로컬 (체크인되지 않은) 리소스에 의존 할 수도 있습니다. 지역 단위 테스트에서 찾을 수없는 것.

위의 모든 것이 환상적이라고 생각한다면 실패한 테스트가있는 빌드가 보류되고 코드베이스에 커밋되지 않은 Gated 라는 CI 이상의 레벨이 있습니다 (적어도 TFS에서) .


7
내가 인정해야 할 CI 장애를 저지르는 것을 잊어 버린 더 많은 죄송합니다.
Dan Neely

@DanNeely 공평하게 말하면, 당신이 그 / 그녀에게 무언가에 대해 이야기하는 것을 잊었 기 때문에 빌드 매니저가 엉덩이를 걷어차는 것을 이길 수 있습니다 ... :-)
Robbie Dee

3
그것이 CI를 좋아하는 이유 중 하나입니다. 자신의 ooopses를 찾고 수정하는 것이 다른 사람이 나를 찾도록하는 것보다 훨씬 낫습니다.
Dan Neely

14

무언가가 숙달 될 때까지

나는 보통 모든 단일 커밋에서 CI가 실행되도록 설정합니다. 지점이 테스트 될 때까지 지점은 마스터로 병합되지 않습니다. master에서 테스트를 실행하는 경우 빌드가 손상되는 창이 열립니다.

CI 시스템에서 테스트를 실행하는 것은 재현 가능한 결과에 관한 것입니다. CI 서버에는 VCS에서 알려진 깨끗한 환경이 있으므로 테스트 결과가 정확하다는 것을 알고 있습니다. 로컬로 실행하는 경우 전달하는 데 필요한 일부 코드를 커밋하거나 커밋되지 않은 코드가 있어야 실패 할 때 전달할 수 있습니다.

또한 서로 다른 제품군을 병렬로 실행하여 개발자의 시간을 절약 할 수 있습니다. 특히 일부 변경 사항이있을 때마다 로컬에서 실행되지 않는 느린 다중 분 테스트가있는 경우 더욱 그렇습니다.

현재 작업에서 프로덕션 배포는 모든 테스트를 통과하는 CI를 기반으로합니다. 배포 스크립트는 통과하지 않는 한 배포를 방지합니다. 이로 인해 실수로 실행하는 것을 잊을 수 없습니다.

워크 플로우의 일부인 CI는 개발자의 부담을 덜어줍니다. 개발자는 대개 단일 변경마다 린터, 정적 분석기, 단위 테스트, 코드 적용 범위 및 통합 테스트를 실행합니까? CI는 완전히 자동으로 생각할 필요없이 의사 결정 피로를 줄일 수 있습니다.


1
실제로 느린 단위 테스트를해서는 안됩니다 . 이는 첫 번째 원칙을 위반하는 것입니다.
Robbie Dee

4
@RobbieDee : 일반적으로 CI 서버는 단위 테스트뿐만 아니라 모든 테스트를 실행한다고 생각합니다.
RemcoGerlich

4
@RobbieDee : 이론적으로 모든 단위 테스트는 빠릅니다. 실제로 .... CI는 린터, 정적 분석, 단위 테스트, 통합 테스트 등 모든 테스트를 실행할 수 있으며 실행해야합니다 .
데니스

2
@RobbieDee 분명히 구성의 세부 사항은 팀마다 다릅니다. 빌드가 몇 분이 걸리더라도 여러 빌드를 동시에 실행할 수 있습니다. 단일 모 놀리 식 코드베이스가 주어지면 더 큰 단점이 될 수 있지만 IME는 장벽이 아닙니다.
데니스

1
@RobbieDee 나는 그것이 당신의 아키텍처에 더 의존한다고 생각합니다. 나는 ~ 80의 엔지니어링 팀이 수작업으로 작동하는 것을 보았지만 제품 영역에 대해 잘 정의 된 하위 팀이 있습니다.
데니스

4

무언가를 숙달하기 위해 개발자 이미 모든 단위 테스트를 실행해야합니다. CI 서버에서 단위 테스트를 실행하지 않으면 다른 사람이 자신의 컴퓨터에서 변경 사항을 가져 와서 테스트가 중단 된 것을 발견 할 때까지 알 수 없습니다.

또한 개발자가 실수하여 자신의 컴퓨터에 특정한 로컬 리소스를 참조했을 수 있습니다. 코드를 체크인하고 CI 실행에 실패하면 문제가 즉시 식별되어 수정할 수 있습니다.


3

(다른 답변과 달리) 개발자가 커밋하기 전에 꽤 훈련되고 단위 테스트를 수행한다고 가정하면 몇 가지 이유가 있습니다.

  • 일부 특수 설정의 경우 실행 단위 테스트에 시간이 오래 걸릴 수 있습니다. 예를 들어 valgrind와 같은 메모리 검사기로 단위 테스트를 실행하면 시간이 훨씬 오래 걸릴 수 있습니다. 모든 장치 테스트가 통과되었지만 메모리 검사에 실패 할 수 있습니다.
  • 결과는 일부 특수 설정에서 중요하지 않습니다. 예를 들어 코드 범위를 확인하기 위해 단위 테스트를 실행하려면 특수 컴파일 플래그가 필요합니다. 일반적인 개발자에게는 코드 적용 범위가 그다지 중요하지 않습니다. 코드를 관리하는 사람들이 팀 리더와 같이 특정 품질을 유지하는 것이 더 중요합니다.

3

변경 A가 테스트를 중단하지 않고 변경 B가 테스트를 중단하지 않지만 A와 B가 함께 발생하는 경우를 상상할 수 있습니다. A와 B가 다른 개발자에 의해 만들어진 경우 CI 서버 만 새 버그를 감지합니다. A와 B는 더 긴 문장의 두 부분 일 수도 있습니다.

두 기관차 A와 B로 구동되는 열차를 상상해보십시오. 아마도 하나가 충분하고 이것이 적용 할 수있는 해결책 일 것입니다. 그러나 두 "픽스"를 적용하여 둘 다 제거하면 열차가 움직이지 않습니다.

또한 모든 개발자가 모든 단위 테스트를 실행하는 것은 아니지만 대부분의 훌륭한 개발자는 수행합니다.


2

동등한 질문을하자 :

CI 서버에서 코드를 작성하는 이유는 무엇입니까?

확실히 무언가를 마스터하기 위해 개발자는 이미 코드를 작성하고 새 코드에서 발생할 수있는 오류를 수정했습니다. 이것이 코드 작성의 요점이 아닌가? 그렇지 않으면 그들은 깨진 코드를 커밋했습니다.


CI를 수행하는 데는 몇 가지 이유가 있지만 CI의 주요 요점은 시간이 지남에 따라 코드의 상태를 파악하는 것입니다. 이것이 제공하는 주요 이점 (몇 가지 중 하나)은 빌드가 중단 된 시점을 파악하고 고장난 부분을 파악한 다음 해결할 수 있다는 것입니다.

코드가 끊어지지 않으면 왜 CI를 사용합니까? 테스트 용 빌드를 제공하려면 야간 빌드로 충분합니다.

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