Skip to content

Instantly share code, notes, and snippets.

@samflores
Created November 8, 2011 15:26
Show Gist options
  • Save samflores/1348029 to your computer and use it in GitHub Desktop.
Save samflores/1348029 to your computer and use it in GitHub Desktop.
RSpec comparison
class Foo
def say
"Hello"
end
end
require 'foo'
describe Foo do
it "should say hello" do
Foo.new.say.should == "Hello"
end
end
rbx-2.0.0-dev
1.17s user 0.07s system 139% cpu 0.890 total
1.18s user 0.07s system 140% cpu 0.890 total
1.9.2-p290
0.51s user 0.11s system 99% cpu 0.620 total
0.50s user 0.11s system 99% cpu 0.614 total
1.9.3-p0
0.15s user 0.04s system 98% cpu 0.192 total
0.15s user 0.04s system 98% cpu 0.193 total
1.8.7-p352
0.10s user 0.03s system 96% cpu 0.136 total
0.09s user 0.04s system 96% cpu 0.134 total
@rafaelss
Copy link

rafaelss commented Nov 8, 2011

$ RUBYOPT="-I." time -p rspec foo_spec.rb 

1.9.3-p0
real         0.44
user         0.39
sys          0.04

@rafaelss
Copy link

rafaelss commented Nov 8, 2011

O que tu usou pra medir o tempo?

@samflores
Copy link
Author

time rspec -I. foo_spec.rb

O zsh não reconhece a opção -p (e eu não lembro como mudar o formato da saída), mas executei agora no bash pra comparar e obtive valores idênticos:

1.9.3-p0 (zsh)
0.15s user 0.04s system 98% cpu 0.192 total

1.9.3-p0 (bash)
real    0.30s
user    0.15s
sys     0.04s

@samflores
Copy link
Author

Copiei os valores errados. No bash deu:

real    0.19s
user    0.15s
sys     0.04s

@rafaelss
Copy link

rafaelss commented Nov 8, 2011

e tu acha isso lento? :D

@samflores
Copy link
Author

190 milisegundos pra rodar praticamente nenhum código? Acho...
Mas percebi que o gargalo mesmo é o carregamento do RSpec (por isso o 1.9.3 é melhor que o 1.9.2). A execução da spec é quase instantânea (se eu colocar outros specs o tempo não muda quase nada) Troquei pro Bacon (http://github.com/chneukirchen/bacon) e o tempo caiu pela metade. There's too much magic on RSpec :D

@rafaelss
Copy link

rafaelss commented Nov 8, 2011

quanto mais bloated é o framework, mais tempo de load ele consome. por isso perguntei se tu tava achando lento ;)

@rafaelss
Copy link

rafaelss commented Nov 8, 2011

faz um teste com o MiniTest::Spec pra ver o que dá

@samflores
Copy link
Author

Uma coisa curiosa: o Bacon não tem um framework pra mocks/stubs embutido, então carreguei o Mocha junto (além de ter adicionado uma spec que usasse stubs) e, ainda assim, o tempo total foi menor que o do RSpec. ¬¬

@samflores
Copy link
Author

Resultado para a mesma spec usando MiniTest::Spec

1.9.3-p0
real    0.17s
user    0.13s
sys     0.04s

e usando Bacon:

1.9.3-p0
real    0.10s
user    0.07s
sys     0.03s

@dannluciano
Copy link

Man, mas isso nunca foi surpresa para mim. Esse é dos pontos que sempre defendo o Test::Unit pois em projetos grandes com muitos testes o sofrimento é grande.

@samflores
Copy link
Author

Pois nesse ponto vc se engana. Depois de efetuar vários testes e analisar um pouco as coisas verifiquei que o problema não era a execução das specs que era lenta e sim o carregamento das libs (require é conhecido por ser lento em Ruby). Escrevi um teste usando Test::Unit e obtive praticamente o mesmo valor que o RSpec (alguns milisegundos de diferença).

O que precisa ser considerado, e foi o que não havia observado no início, é que esse tempo não é diretamente proporcional à quantidade de testes/specs. Se um spec demorou 0.17s dois não vai demorar 0.34s, na verdade depois que o ambiente está carregado um spec simples como o do exemplo executa tão rapidamente que não consegui medir a diferença de execução entre um spec, dois specs, e nem mesmo cinco specs. Ainda nos testes que realizei executei 1 spec em 0.17s e 5 specs 0.17s (sem diferenças perceptíveis).

Se você acha que sua suite de testes/spec está demorando muito provavelmente os seus testes estão muito integrados, carregando muitas dependência (o Rails inteiro, por exemplo) ou acessando recurso que não deveriam ser acessados, como banco de dados ou rede.

Provavelmente o RSpec tem realmente algum overhead em relação ao Test:Unit, porém acho que a agilidade pra escrever (pelo menos pra mim) bem como a legibilidade compensam e muito.

@samflores
Copy link
Author

Sim, stubs e mocks são puro amor, se usados da maneira correta. Mas isso é assunto pra outro momento ou um post no futuro (quem sabe). :D

@dannluciano
Copy link

Entendo man, na verdade este tipo de experimento é muito complicado (mesma coisa sinatra x rails. ) pois uma coisa é um simples should x assert outra são n specs, mocks, stubs e etc.
A maioria das minhas conclusões são a partir das experiencias de terceiros. Eu ja conhecia o MiniTest e recomendaria ele para quem quer a sintaxe do rspec. Eu concordo que acho o rspec mais elegante, mas não consigo me acostumar com ele, talvez precise mais pratica.

@samflores
Copy link
Author

Na verdade minha intenção inicial não era comparar os diferentes frameworks de testes, mas comparar a execução, ou melhor a carga+execução, de um único framework (RSpec) em diferentes implementações do interpretador (MRI-{1.8.7,1.9.2,1.9.3} e Rubinius 2.0.0).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment