Barauna Hugo - Cucumber e RSpec стр 19.

Шрифт
Фон

# roda esse código uma vez antes de cada teste

end

# ou

63

4.1. Reduzindo duplicação com hooks do RSpec

Casa do Código

# não precisa passar o :each, pois ele é a opção default do before

before do

# roda esse código uma vez antes de cada teste

end

before(:all) do

# roda esse código uma vez só antes de todos os testes

end

Vamos utilizar o before para primeiro extrair o setup comum entre nossos dois

testes:

describe Game, "in the final phase" do

before do

@game = Game.new

@game.phase = :final

end

context "when the player hits the target" do

it "congratulates the player" do

@game.player_hits_target

expect(@game.output).to eq("Congratuations!")

end

it "sets the score to 100" do

@game.player_hits_target

expect(@game.score).to eq(100)

end

end

end

Repare que extraímos o setup para um before hook dentro do escopo do

describe. Poderíamos ter extraído para o escopo do context, mas preferimos ex-

trair para o escopo do describe porque segundo a string desse describe ( Game,

"in the final phase"), todos

os testes dele irão compartilhar o mesmo estado do game, ou seja, o game estar na última fase.

Repare também que ao extrairmos o setup para o before hook, foi necessário

salvar o objeto game como uma variável de instância. Fizemos isso porque esse é

64

Casa do Código

Capítulo 4. Organização, refatoração e reuso de testes com o RSpec

o modo de compartilhar variáveis entre um before hook e os testes dentro do seu

escopo.

Agora que já extraímos parte do código duplicado nos nossos testes, vamos ana-

lisar se vale a pena extrair o resto de duplicação.

4.2

DRY versus clareza nos testes

O

que

ainda

temos

duplicado

entre

ambos

os

testes

é

a

linha

@game.player_hits_target:

context "when the player hits the target" do

it "congratulates the player" do

@game.player_hits_target

expect(@game.output).to eq("Congratuations!")

end

it "sets the score to 100" do

@game.player_hits_target

expect(@game.score).to eq(100)

end

end

Poderíamos tranquilamente extrair essa linha para um before no escopo do con-

texto. Ficaria assim:

context "when the player hits the target" do

before { @game.player_hits_target }

it "congratulates the player" do

expect(@game.output).to eq("Congratuations!")

end

it "sets the score to 100" do

expect(@game.score).to eq(100)

end

end

No entanto, será que vale a pena reduzir a duplicação ao máximo nos nossos

testes? A resposta é não. A aplicação do conceito de DRY no código de testes é

diferente da aplicação do conceito de DRY no código de produção.

65

4.2. DRY versus clareza nos testes

Casa do Código

No código de testes uma das maiores preocupações que você deve ter é se o teste

está claro, ou seja, se o leitor desse código consegue ler e entender o que o teste

está querendo testar. Ou melhor ainda, o leitor deve entender a relação de causa e

consequência do seu teste. Podemos visualizar melhor essa relação com a seguinte

máquina de estados:

Figura 4.1: Relação de causa e consequência de um teste

Ao ler um teste, deve estar claro para o leitor a relação de causa e consequência

demostrada no diagrama acima. Caso esteja difícil de entender essa relação, então

falta clareza no teste.

Por isso, toda vez que você for refatorar seus testes, seja pelo motivo de DRY ou

outra razão, você deve sempre pensar se essa refatoração não irá impactar na clareza

do seu teste. No exemplo que demos acima ela não ficou tão impactada porque os

testes são pequenos:

context "when the player hits the target" do

before { @game.player_hits_target }

it "congratulates the player" do

expect(@game.output).to eq("Congratuations!")

end

it "sets the score to 100" do

expect(@game.score).to eq(100)

end

end

Um modo de avaliar se o seu teste está perdendo a clareza é ler somente o código

do teste em si, ou seja, somente o bloco de código passado para o it. Vamos fazer

isso para o seguinte teste:

66

Casa do Código

Capítulo 4. Organização, refatoração e reuso de testes com o RSpec

it "sets the score to 100" do

expect(@game.score).to eq(100)

end

Só de ler esse teste você poderia se perguntar:

em que estado o objeto game precisa estar para o score ser setado como 100?

o que tem que ser feito no objeto game para que ele sete o score para 100?

Essas perguntas são válidas para ser possível entender a relação de causa e con-

sequência de um teste. Se o teste estivesse sido escrito do seguinte modo:

it "sets the score to 100" do

game = Game.new

game.phase = :final

game.player_hits_target

expect(@game.score).to eq(100)

end

essas perguntas teriam sido respondidas apenas lendo o código do teste em si.

Mas como o refatoramos, é necessário ler o código dos before hooks também.

No caso desse teste, como o arquivo de testes é muito pequeno e o código dos

before hooks está bem perto do código do teste em si, o teste não perde muito em

clareza. No entanto, se o teste estiver em um arquivo muito grande e você tiver que

dar muito scroll, fazendo idas e voltas entre o teste e os before

Ваша оценка очень важна

0
Шрифт
Фон

Помогите Вашим друзьям узнать о библиотеке