[ruby-on-rails] 대규모 Rails 애플리케이션에서 RSpec 테스트 속도 향상

내 RSpec 테스트에서 2,000 개 이상의 예제가있는 Rails 애플리케이션이 있습니다. 말할 필요도없이, 그것은 큰 응용 프로그램이고 많은 테스트가 필요합니다. 이 시점에서 이러한 테스트를 실행하는 것은 매우 비효율적이며 시간이 너무 오래 걸리기 때문에 새 빌드를 푸시하기 전에 작성하는 것이 거의 권장되지 않습니다. 가장 오래 실행되는 예제를 찾기 위해 spec.opts에 –profile을 추가했으며 실행하는 데 평균 10 초가 걸리는 예제가 10 개 이상 있습니다. RSpec 전문가들 사이에서 그게 정상입니까? 예를 들어 10 초가 너무 길어? 2,000 개의 예제를 사용하면 모든 것을 철저히 테스트하는 데 사소한 시간이 걸리지 않지만이 시점에서 4 시간은 약간 우스꽝 스럽습니다.

가장 오래 실행되는 예제에 대해 어떤 종류의 시간을보고 있습니까? 병목 현상을 파악하고 작업 속도를 높이기 위해 기존 사양의 문제를 해결하려면 어떻게해야합니까? 이 시점에서 매 순간 정말 도움이 될 것입니다.



답변

10 초는 단일 테스트를 실행하는 데 매우 긴 시간입니다. 내 직감은 사양 대상이 단위 및 통합 테스트를 동시에 실행하고 있다는 것입니다. 이것은 프로젝트에 해당하는 전형적인 것이며 어떤 단계 에서이 기술적 부채를 극복해야합니다. 더 많은 것을 더 빨리 생산하려면 . 이 작업을 수행하는 데 도움이 될 수있는 여러 가지 전략이 있습니다. 과거에 사용했던 몇 가지 전략을 권장합니다.

1. 통합 테스트에서 단위 분리

가장 먼저 할 일은 통합 테스트에서 유닛을 분리하는 것입니다. 다음 중 하나를 수행 할 수 있습니다.

  1. 그것들을 (spec 디렉토리 아래의 별도 폴더로) 이동-레이크 타겟 수정
  2. 태그 지정 (rspec을 사용하면 테스트에 태그를 지정할 수 있음)

철학은 일반 빌드가 빠르기를 원한다는 것입니다. 그렇지 않으면 사람들이 자주 실행하는 것을 너무 좋아하지 않을 것입니다. 그러니 그 영역으로 돌아가십시오. 정기적 인 테스트를 빠르게 실행하고 지속적 통합 서버를 사용하여보다 완전한 빌드를 실행하십시오.

통합 테스트는 외부 종속성 (예 : Database, WebService, Queue 및 일부는 FileSystem을 주장함)을 포함하는 테스트입니다. 단위 테스트는 확인하려는 특정 코드 항목 만 테스트합니다. 빠르게 실행되어야합니다 (45 초에 9000이 가능). 즉, 대부분이 메모리에서 실행되어야합니다.

2. 통합 테스트를 단위 테스트로 변환

단위 테스트의 대부분이 통합 테스트 스위트보다 작 으면 문제가있는 것입니다. 이것이 의미하는 바는 불일치가 더 쉽게 나타나기 시작한다는 것입니다. 따라서 여기에서 통합 테스트를 대체 할 더 많은 단위 테스트를 만들기 시작합니다. 이 프로세스를 돕기 위해 수행 할 수있는 작업은 다음과 같습니다.

  1. 실제 리소스 대신 모의 프레임 워크를 사용합니다. Rspec에는 내장 된 조롱 프레임 워크가 있습니다.
  2. 단위 테스트 스위트에서 rcov를 실행하십시오. 이를 사용하여 단위 테스트 스위트가 얼마나 철저한 지 측정하십시오.

통합 테스트를 대체 할 적절한 단위 테스트가 있으면 통합 테스트를 제거하십시오. 중복 테스트는 유지 관리를 악화시킬뿐입니다.

3. 비품을 사용하지 마십시오

비품은 사악합니다. 대신 팩토리를 사용하십시오 (기계공 또는 팩토리 봇). 이러한 시스템은보다 적응 가능한 데이터 그래프를 구축 할 수 있으며, 더 중요한 것은 외부 데이터 소스에서 데이터를로드하는 대신 사용할 수있는 메모리 내 개체를 구축 할 수 있다는 것입니다.

4. 통합 테스트가되는 단위 테스트를 중지하기위한 검사 추가

이제 더 빠른 테스트가 준비되었으므로이 문제가 다시 발생하지 않도록 확인해야합니다.

데이터베이스 (UnitRecord)에 액세스하려고 할 때 오류를 발생시키기 위해 원숭이 패치 활성 레코드가있는 라이브러리가 있습니다.

다음과 같은 이유로 팀이 더 빠른 테스트를 작성하도록 할 수있는 페어링 및 TDD를 시도 할 수도 있습니다.

  1. 누군가 확인 중입니다. 그래서 아무도 게으르지 않습니다.
  2. 적절한 TDD에는 빠른 피드백이 필요합니다. 느린 테스트는 모든 것을 고통스럽게 만듭니다.

5. 문제를 극복하기 위해 다른 라이브러리 사용

누군가는 spork (rails3 아래 테스트 스위트의로드 시간을 단축), hydra / parallel_tests를 언급하여 병렬로 (여러 코어에 걸쳐) 단위 테스트를 실행했습니다.

이것은 아마도 마지막에 사용되어야합니다. 실제 문제는 1, 2, 3 단계에 있습니다.이 문제를 해결하면 추가 인프라 역할을 수행 할 수있는 더 나은 위치에있게됩니다.


답변

테스트 스위트의 성능 향상에 대한 훌륭한 요리 책은 Grease Your Suite 프레젠테이션을 확인하십시오 .

그는 다음과 같은 기술을 활용하여 테스트 스위트 실행 시간이 45 배 빨라 졌다고 기록합니다.


답변

Spork를 사용할 수 있습니다. 2.3.x를 지원합니다.

https://github.com/sporkrb/spork

또는 2.x에서 작동하는 ./script/spec_server

또한 데이터베이스 구성을 편집하여 (기본적으로 데이터베이스 쿼리 속도를 높이는 등) 테스트 성능도 높일 수 있습니다.


답변

예제 당 10 초는 매우 긴 시간처럼 보입니다. 1 초 이상 걸리는 사양은 본 적이 없으며 대부분은 훨씬 적게 걸립니다. 네트워크 연결을 테스트하고 있습니까? 데이터베이스 쓰기? 파일 시스템 쓰기?

모의와 스텁을 가능한 많이 사용하십시오 . 데이터베이스에 접근하는 코드를 작성하는 것보다 훨씬 빠릅니다. 불행히도 조롱과 스터 빙은 작성하는 데 더 많은 시간이 걸립니다 (올바르게 수행하기가 더 어렵습니다). 테스트 작성 시간과 테스트 실행 시간의 균형을 맞춰야합니다.

테스트 스위트를 병렬화 할 수있는 CI 시스템을 조사하는 것에 대한 Andrew Grimm 의 의견을 두 번째 로드립니다. 이 정도 크기의 경우 유일한 솔루션 일 수 있습니다.


답변

여러 사람이 위에서 Hydra를 언급했습니다. 우리는 과거에 큰 성공을 거두었습니다. 나는 최근에 hydra를 시작하고 실행하는 과정을 문서화했습니다 : http://logicalfriday.com/2011/05/18/faster-rails-tests-with-hydra/

나는 이런 종류의 기술이 기본적으로 잘 구조화되고 빠른 테스트를 작성하는 대신 사용되어서는 안된다는 의견에 동의합니다.


답변

ActiveRecord 모델을 사용하는 경우 BCrypt 암호화 비용도 고려해야합니다.

자세한 내용은이 블로그 게시물에서 읽을 수 있습니다. http://blog.syncopelabs.co.uk/2012/12/speed-up-rspec-test.html


답변

faster_require gem이 도움이 될 수 있습니다. 그 외에도 유일한 방법은 프로필을 작성하고 최적화하거나 spork 또는 사양을 병렬로 실행하는 것을 사용하는 것입니다. http://ruby-toolbox.com/categories/distributed_testing.html