Eu tenho um aplicativo Rails com mais de 2.000 exemplos em meus testes RSpec. Não é preciso dizer que é um aplicativo grande e que há muito a ser testado. Executar esses testes neste ponto é muito ineficiente e, como leva muito tempo, estamos quase no ponto de ser desencorajados de escrevê-los antes de enviar uma nova compilação. Eu adicionei --profile ao meu spec.opts para encontrar os exemplos de execução mais longa e há pelo menos 10 deles que levam em média 10 segundos para serem executados. Isso é normal entre vocês, especialistas em RSpec? 10 segundos são muito longos para um exemplo? Eu percebo que com 2.000 exemplos, levará uma quantidade não trivial de tempo para testar tudo completamente - mas neste ponto 4 horas é um pouco ridículo.
Que tipo de vezes você está vendo em seus exemplos mais antigos? O que posso fazer para solucionar minhas especificações existentes, a fim de descobrir gargalos e ajudar a acelerar as coisas. Cada minuto realmente ajudaria neste ponto.
fonte
perftools.rb
junto com sua estrutura de teste para entender o que está consumindo a maior parte do seu tempo. Atenda às 10 chamadas principais e tente eliminá-las / ignorá-las. Em seguida, repita, até ficar feliz.Respostas:
10 segundos é um tempo muito longo para a execução de um único teste. Meu pressentimento é que seu alvo de especificações está executando testes de unidade e integração ao mesmo tempo. Isso é uma coisa típica em que os projetos se enquadram e, em algum momento, você precisará superar essa dívida técnica se quiser produzir mais e mais rápido. Existem várias estratégias que podem ajudá-lo a fazer isso ... e vou recomendar algumas que usei no passado.
1. Separe a unidade dos testes de integração
A primeira coisa que eu faria é separar a unidade dos testes de integração. Você pode fazer isso:
A filosofia é que você deseja que suas compilações regulares sejam rápidas - caso contrário, as pessoas não ficarão muito felizes em executá-las com frequência. Então volte para aquele território. Faça com que seus testes regulares sejam executados rapidamente e use um servidor de integração contínua para executar a construção mais completa.
Um teste de integração é um teste que envolve dependências externas (por exemplo, Database, WebService, Queue e alguns diriam FileSystem). Um teste de unidade apenas testa o item específico do código que você deseja verificar. Deve ser executado rápido (9000 em 45 segundos é possível), ou seja, a maior parte deve ser executado na memória.
2. Converter testes de integração em testes de unidade
Se a maior parte de seus testes de unidade for menor do que seu conjunto de testes de integração, você tem um problema. O que isso significa é que as inconsistências começarão a aparecer com mais facilidade. Então, a partir daqui, comece a criar mais testes de unidade para substituir os testes de integração. As coisas que você pode fazer para ajudar neste processo são:
Assim que tiver um (s) teste (s) de unidade adequado (s) para substituir um teste de integração - remova o teste de integração. O teste duplicado só piora a manutenção.
3. Não use luminárias
As luminárias são más. Em vez disso, use uma fábrica (mecânico ou robô de fábrica). Esses sistemas podem construir gráficos de dados mais adaptáveis e, mais importante, eles podem construir objetos na memória que você pode usar, em vez de carregar coisas de uma fonte de dados externa.
4. Adicionar verificações para interromper os testes de unidade que se tornam testes de integração
Agora que você implementou testes mais rápidos, é hora de colocar verificações para PARAR que isso ocorra novamente.
Existem bibliotecas que fazem o monkey patch active record para lançar um erro ao tentar acessar o banco de dados (UnitRecord).
Você também pode tentar emparelhar e TDD, o que pode ajudar a forçar sua equipe a escrever testes mais rápidos porque:
5. Use outras bibliotecas para superar o problema
Alguém mencionou spork (acelera os tempos de carregamento para o conjunto de testes em rails3), hydra / parallel_tests - para executar testes de unidade em paralelo (em vários núcleos).
Isso provavelmente deve ser usado POR ÚLTIMO. Seu verdadeiro problema está na etapa 1, 2, 3. Resolva isso e você estará em uma posição melhor para desenvolver a infraestrutura adicional.
fonte
Para obter um ótimo livro de receitas sobre como melhorar o desempenho de sua suíte de testes, confira a apresentação Grease Your Suite .
Ele documenta uma aceleração de 45 vezes no tempo de execução do conjunto de testes, utilizando técnicas como:
fonte
Você pode usar o Spork. Tem suporte para 2.3.x,
https://github.com/sporkrb/spork
ou ./script/spec_server que pode funcionar para 2.x
Além disso, você pode editar a configuração do banco de dados (o que essencialmente acelera as consultas ao banco de dados, etc.), o que também aumentará o desempenho dos testes.
fonte
10 segundos por exemplo parece muito tempo. Nunca vi uma especificação que demorasse mais de um segundo e a maioria demorasse muito menos. Você está testando as conexões de rede? Gravações de banco de dados? Sistema de arquivos escreve?
Use mocks e stubs tanto quanto possível - eles são muito mais rápidos do que escrever código que chega ao banco de dados. Infelizmente, mocking e stubbing também levam mais tempo para escrever (e são mais difíceis de fazer corretamente). Você deve equilibrar o tempo gasto escrevendo testes e o tempo gasto executando testes.
Eu segundo Andrew Grimm comentário é sobre olhar para um sistema de CI que pode permitir que você paralelizar sua suíte de testes. Para algo desse tamanho, pode ser a única solução viável.
fonte
Várias pessoas mencionaram Hydra acima. Nós o usamos com grande sucesso no passado. Recentemente documentei o processo de colocar a Hydra em funcionamento: http://logicalfriday.com/2011/05/18/faster-rails-tests-with-hydra/
Eu concordaria com o sentimento de que esse tipo de técnica não deve ser usado como um substituto para escrever testes que são bem estruturados e rápidos por padrão.
fonte
Se estiver usando modelos ActiveRecord, você também deve considerar o custo da criptografia BCrypt.
Você pode ler mais sobre isso nesta postagem do blog: http://blog.syncopelabs.co.uk/2012/12/speed-up-rspec-test.html
fonte
rapid_require gem pode te ajudar. Além disso, sua única maneira é (como você fez) perfilar e otimizar, ou usar spork ou algo que execute suas especificações em paralelo para você. http://ruby-toolbox.com/categories/distributed_testing.html
fonte
Você pode seguir algumas dicas simples para primeiro investigar onde é gasto a maior parte do tempo, caso ainda não tenha experimentado. Veja o artigo abaixo:
https://blog.mavenhive.in/7-tips-to-speed-up-your-webdriver-tests-4f4d043ad581
Acho que a maioria dessas etapas são genéricas que também se aplicam independentemente da ferramenta usada para o teste.
fonte
Exclua o conjunto de testes existente. Será incrivelmente eficaz.
fonte