Programing

대규모 Rails 애플리케이션에서 RSpec 테스트 속도 향상

lottogame 2020. 9. 5. 10:29
반응형

대규모 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

Also you can edit the database configuration ( which essentially speeds up the database queries etc ), which will also increase performance for tests.


10 seconds per example seems like a very long time. I've never seen a spec that took more than one second, and most take far less. Are you testing network connections? Database writes? Filesystem writes?

Use mocks and stubs as much as possible - they are much faster than writing code that hits the database. Unfortunately mocking and stubbing also take more time to write (and are harder to do correctly). You have to balance the time spent writing tests vs. the time spent running tests.

I second Andrew Grimm's comment about looking into a CI system which might allow you to parallelize your test suite. For something that size, it might be the only viable solution.


Several people have mentioned Hydra above. We have used it with great success in the past. I recently documented the process of getting hydra up and running: http://logicalfriday.com/2011/05/18/faster-rails-tests-with-hydra/

I would agree with the sentiment that this kind of technique should not be used as a substitute for writing tests that are well structured and fast by default.


If you are using ActiveRecord models, you should also consider the cost of BCrypt encryption.

You can read more about it on this blog post: http://blog.syncopelabs.co.uk/2012/12/speed-up-rspec-test.html


Checkout this presentation: http://grease-your-suite.heroku.com/#1


You can try http://github.com/ngauthier/hydra


faster_require gem might help you. Besides that your only way is to (like you did) profile and optimize, or use spork or something that runs your specs in parallel for you. http://ruby-toolbox.com/categories/distributed_testing.html


There is a very general video here on improving your test speeds. Might help.


You can follow a few simple tips to first investigate where most of the time is spent if you haven't already tried them. Look at the article below:

https://blog.mavenhive.in/7-tips-to-speed-up-your-webdriver-tests-4f4d043ad581

I guess most of these are generic steps which would apply irrespective of the tool used for testing too.


Delete the existing test suite. Will be incredibly effective.

참고URL : https://stackoverflow.com/questions/3663075/speeding-up-rspec-tests-in-a-large-rails-application

반응형