Prólogo
O que você irá ler abaixo são apenas alguns dos vários motivos para se usar testes, especialmente desenvolver guiado por testes.
Como um desenvolvedor iniciante, sempre questionei internamente os porquês dos testes, mesmo com todos ao meu redor dizendo sua importância e valor, nunca havia posto em prática as técnicas necessárias para executar bons testes e/ou desenvolver algo totalmente guiado por eles, antes a vida era bem simples, era só montar no cavalo e escrever tudo às cegas, sem planejamento, sem pensar, o belo e não ideal eXtreme Go Horse. No entanto, com isso me vi perdendo produtividade, testar tudo de um código "na unha" se tornou cansativo demais, brechas e bugs apareciam com facilidade, foi nesse momento em que me dei conta, com a seguinte frase passando pela minha cabeça: "Se eu tivesse os testes escritos, tudo seria mais tranquilo". Dessa forma, com esse pensamento, tomei vergonha na cara e entrei a fundo naquilo que chamam de Test Driven Development, ou melhor, TDD.
Sobre o TDD:
Test Driven Development, ou comumente conhecido como TDD, é uma técnica de desenvolvimento em que o desenvolvedor primeiro pensa nas funções e/ou comportamentos do seu código, escreve os testes para só posteriormente escrever as linhas de código propriamente ditas. Sua importância se dá pela previsibilidade das funções definidas pelo teste, em que você arquiteta todo o código sabendo exatamente o que deve(ria) ser retornado. Desse modo, o TDD é formado pelos seguintes passos:
(RED) Escrever um teste que falhe: Ao escrever o teste, ele obviamente irá falhar a priori, pois você não tem código nenhum para fazer o que o teste espera que seja feito.
(GREEN) Fazer o código funcionar: Ao escrever o código, o desenvolvedor deve fazer o possível para que o teste seja aceito, não importando como.
(REFACTOR) Eliminar a redundância: Após garantir o funcionamento do código, o desenvolvedor deverá aplicar ao máximo as boas práticas da linguagem, buscando sempre o equilíbrio entre legibilidade e qualidade.
Conhecendo o RSpec:
Não vou entrar a fundo na instalação e afins pois esse não é o foco da postagem, mas aqui e aqui você encontrará tudo o que é preciso para entender e utilizar o RSpec com Ruby e Rails.
O RSpec é uma ferramenta (gem) de testes para códigos na linguagem Ruby, sendo uma das mais famosas e geralmente acompanhado de outras gems que amplificam sua utilidade, tais como: Capybara, Cocumber e Factorybot (antigo FactoryGirl).
Sua sintaxe simples e muito semelhante com a lingua inglesa auxília no entendimento e escrita de testes, geralmente com suas descrições feitas na terceira pessoa.
RSpec.describe ArticlesController do
describe '#index' do
it 'returns a success response' do
get '/articles'
expect(response).to have_http_status(:ok)
end
it 'returns articles in a proper order' do
older_article =
create(:article, created_at: 1.hour.ago)
recent_article = create(:article)
get '/articles'
ids = json_data.map { |item| item[:id].to_i }
expect(ids).to(
eq([recent_article.id, older_article.id])
)
end
end
end
Entendendo o código:
.describe: Utiliza-se describe para descrever as classes, módulos ou métodos em que irão ser feitos os testes. Nesse caso o que está sendo descrito acima é a classe ArticlesController. e a chamada index da rota /articles.
it: Utiliza-se it para descrever o que será testado (descrito na terceira pessoa). Nesse caso 'Returns a success response' implica na requisição de get '/articles' retornar uma resposta "Sucesso", ou melhor, o status HTTP 200 (OK).
O próximo passo, sob o viés do TDD, você deverá rodar o comando rspec
no seu terminal para iniciar o teste, que obviamente falhará, na maioria dos casos, a falha do teste te dará um norte sobre o que deve ser feito.
Após isso, será iniciada a linha de pensamento para o código ser aceito pelo teste, nesse caso:
Exemplo do teste feito em uma API.
- Deverá existir um Model e um Controller para articles, juntamente com um Serializer (JSON API gem) para definir os atributos e organizá-los e um método index para renderizar o arquivo em formato .json.
#./app/models/article.rb
class Article < ApplicationRecord
validates :title, presence: true
validates :content, presence: true
validates :slug, presence: true, uniqueness: true
scope :recent, -> { order(created_at: :desc) }
end
# ./app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
def index
articles = Article.recent
render json: serializer.new(articles), status: :ok
end
def serializer
ArticleSerializer
end
end
# ./serializers/article_serializer.rb
class ArticleSerializer
include JSONAPI::Serializer
attributes :title, :content, :slug
end
-
O código deverá ter uma rota definida para o controller articles juntamente com o método index.
# ./config/routes.rb Rails.application.routes.draw do resources :articles, only: %i[index] end
Fazendo isso e rodando novamente rspec
é esperado que o teste passe.
Conclusão
Seguindo dois dos três passos do TDD, consegue-se chegar a um código que terá sempre testes que podem indicar seu funcionamento digitando um simples comando no terminal, o que por sua vez é muito útil caso o desenvolvedor queira seguir o terceiro passo do TDD e refatorar, melhorar e adicionar novas funcionalidades para sua aplicação / API.
Sob essa ótica, o aumento da produtividade e qualidade de código será apenas questão de tempo, conforme o desenvolvedor aprende mais de suas ferramentas de teste, suas nuances e novas técnicas.
Top comments (3)
Ótimo artigo com um exemplo entendível pra quem não sabe nada de Ruby.
Ótima leitura! Recomendo.
gohorse extreme forever👌