Share
Embed
[CapiConf] Como não odiar seus testes
Sabemos que escrever testes automatizados é extremamente importante, pois, entre outras coisas, eles garantem a qualidade do nosso código e o funcionamento da nossa aplicação. Apesar disso, muitas vezes acabamos com uma suíte de testes que, além de ser difícil de entender e manter, não é confiável. Nessa talk, vamos ver como reconhecer e evitar alguns dos problemas mais comuns que nos fazem odiar nossos testes, além de dar algumas dicas de como melhorar nossos testes.
Camila Campos
November 16, 2020
Transcript
172 slides
-
@camposmilaa Camila Campos SumUp Rails Girls São Paulo Women Dev
Summit @camposmilaa -
@camposmilaa @camposmilaa Camila Campos Meu propósito de vida (WIP) é
influenciar pessoas para reduzir desigualdades sócio-culturais dentro de tecnologia, através da educação e do bom humor. -
@camposmilaa Pirâmide de testes e2e integração unidade Testes lentos contrato
componente aceitação -
@camposmilaa Unidade Testes lentos controller service model model service repository
model controller service model model service repository model -
@camposmilaa Unidade Testes lentos controller service model model service repository
model controller service model model service repository model -
@camposmilaa Unidade unidade test double 2 test double 1 colaborador
2 colaborador 1 Testes lentos -
@camposmilaa Integração Testes lentos controller service model model service repository
model controller service model model service repository model -
@camposmilaa Regras e Convenções Testes lentos Bando de Dados Dependências
externas Colaboradores Ponta a Ponta Sim Sim* Sim Integração Sim Não Sim Unidade Não Não Não -
@camposmilaa Pirâmide de testes e2e integração unidade Testes lentos Mudando
uma classe Testando uma feature Antes de commitar -
@camposmilaa Teste que são difíceis de ler, manter e/ou entender
Testes complicados -
@camposmilaa 1. 2. 3. 4. Sem clareza Bangunçados Mágicos Espertos
demais Testes complicados -
@camposmilaa 1. 2. 3. 4. Sem clareza Bangunçados Mágicos Espertos
demais Testes complicados -
@camposmilaa Teste é uma parada que garante que o seu
código “de verdade” funciona Testes complicados > Sem clareza -
@camposmilaa Teste é código (que garante que o código "de
verdade" funciona) Testes complicados > Sem clareza -
@camposmilaa Testes complicados > Sem clareza Pequeno Simples Teste é
código não testado -
@camposmilaa Testes complicados > Sem clareza Fácil de ler Pequeno
Simples Teste é código não testado -
@camposmilaa Testes complicados > Sem clareza Fácil de ler Pequeno
Simples Objetivo Teste é código não testado -
@camposmilaa it 'sends a message' do person = Person.new(name: 'John')
response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Testes complicados > Sem clareza -
@camposmilaa it 'sends a message' do person = Person.new(name: 'John')
response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Testes complicados > Sem clareza -
@camposmilaa it 'sends a message' do person = Person.new(name: 'John')
response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Testes complicados > Sem clareza -
@camposmilaa it 'sends a message' do person = Person.new(name: 'John')
response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Testes complicados > Sem clareza -
@camposmilaa it 'sends a message' do person = Person.new(name: 'John')
response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Testes complicados > Sem clareza -
@camposmilaa Descrição ruim it 'sends a message' do person =
Person.new(name: 'John') response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Testes complicados > Sem clareza -
@camposmilaa Descrição ruim it 'sends a message' do person =
Person.new(name: 'John') response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Testes complicados > Sem clareza -
@camposmilaa Descrição ruim it 'greets a person' do person =
Person.new(name: 'John') response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Testes complicados > Sem clareza -
@camposmilaa Descrição ruim it 'greets a person' do person =
Person.new(name: 'John') response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Testes complicados > Sem clareza -
@camposmilaa it 'greets a person' do person = Person.new(name: 'John',
last_name: 'Doe', age: 27) response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Testes complicados > Sem clareza -
@camposmilaa it 'greets a person' do person = Person.new(name: 'John',
last_name: 'Doe', age: 27) response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Testes complicados > Sem clareza -
@camposmilaa it 'greets a person' do person = Person.new(name: 'John',
last_name: 'Doe', age: 27) response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Testes complicados > Sem clareza -
@camposmilaa Coisas falsamente importantes it 'greets a person' do person
= Person.new(name: 'John', last_name: 'Doe', age: 27) response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Testes complicados > Sem clareza -
@camposmilaa Coisas falsamente importantes it 'greets a person' do person
= Person.new(name: 'John') response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Testes complicados > Sem clareza -
@camposmilaa Coisas falsamente importantes it 'greets a person' do person
= Person.new(attributes.merge(name: 'John')) response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Testes complicados > Sem clareza -
@camposmilaa Coisas falsamente importantes it 'greets a person' do person
= Person.new(name: 'anyname') response = Messenger.new(person).greet expect(response).to eq 'Hello, anyname' end Testes complicados > Sem clareza -
@camposmilaa 1. 2. 3. 4. Sem clareza Bangunçados Mágicos Espertos
demais Testes complicados -
@camposmilaa Ajeita tudo que precisa Chama o que está testando
Testes complicados > Bangunçados -
@camposmilaa Ajeita tudo que precisa Chama o que está testando
Verifica comportamento Testes complicados > Bangunçados -
@camposmilaa Testes fazem 3 coisas it 'greets a person' do
person = Person.new(name: 'any-name') # Setup response = Messenger.new(person).greet # Exercise expect(response).to eq 'Hello, any-name' # Verify end Testes complicados > Bangunçados -
@camposmilaa Testes fazem 3 coisas it 'greets a person' do
person = Person.new(name: 'any-name') # Setup response = Messenger.new(person).greet # Exercise expect(response).to eq 'Hello, any-name' # Verify end Testes complicados > Bangunçados -
@camposmilaa Testes fazem 3 coisas it 'greets a person' do
person = Person.new(name: 'any-name') # Setup response = Messenger.new(person).greet # Exercise expect(response).to eq 'Hello, any-name' # Verify end Testes complicados > Bangunçados -
@camposmilaa it 'greets a person' do person = Person.new(name: 'any-name')
# Setup response = Messenger.new(person).greet # Exercise expect(response).to eq 'Hello, any-name' # Verify end Testes fazem 3 coisas Testes complicados > Bangunçados -
@camposmilaa Testes fazem 3 coisas it 'greets a person' do
person = Person.new(name: 'any-name') # Setup response = Messenger.new(person).greet # Exercise expect(response).to eq 'Hello, any-name' # Verify end Testes complicados > Bangunçados -
@camposmilaa Testes fazem 3 coisas it 'greets a person' do
person = Person.new(name: 'any-name') # Setup response = Messenger.new(person).greet # Exercise expect(response).to eq 'Hello, any-name' # Verify end Testes complicados > Bangunçados -
@camposmilaa Testes fazem 3 coisas it 'sends email to person'
do mailer = double('my mailer') # Setup person = Person.new(name: 'any-name', email: '[email protected]') # Setup expect(mailer).to receive(:notify).with(person.email) # Verify Messenger.new(person, mailer: mailer).send_email # Exercise end Testes complicados > Bangunçados -
@camposmilaa Testes fazem 3 coisas it 'sends email to person'
do mailer = double('my mailer') # Setup person = Person.new(name: 'any-name', email: '[email protected]') # Setup expect(mailer).to receive(:notify).with(person.email) # Verify Messenger.new(person, mailer: mailer).send_email # Exercise end Testes complicados > Bangunçados -
@camposmilaa Testes fazem 3 coisas it 'sends email to person'
do mailer = double('my mailer') # Setup person = Person.new(name: 'any-name', email: '[email protected]') # Setup expect(mailer).to receive(:notify).with(person.email) # Verify Messenger.new(person, mailer: mailer).send_email # Exercise end Testes complicados > Bangunçados -
@camposmilaa Testes fazem 3 coisas it 'sends email to person'
do mailer = double('my mailer') # Setup person = Person.new(name: 'any-name', email: '[email protected]') # Setup expect(mailer).to receive(:notify).with(person.email) # Verify Messenger.new(person, mailer: mailer).send_email # Exercise end Testes complicados > Bangunçados -
@camposmilaa Testes fazem 3 coisas it 'sends email to person'
do mailer = double('my mailer') # Setup person = Person.new(name: 'any-name', email: '[email protected]') # Setup expect(mailer).to receive(:notify).with(person.email) # Verify Messenger.new(person, mailer: mailer).send_email # Exercise end Testes complicados > Bangunçados -
@camposmilaa Testes fazem 3 coisas it 'sends email to person'
do mailer = double('my mailer') # Setup person = Person.new(name: 'any-name', email: '[email protected]') # Setup expect(mailer).to receive(:notify).with(person.email) # Verify Messenger.new(person, mailer: mailer).send_email # Exercise end Testes complicados > Bangunçados -
@camposmilaa Testes fazem 3 coisas it 'sends email to person'
do mailer = spy('my mailer') # Setup person = Person.new(name: 'any-name', email: '[email protected]') # Setup Messenger.new(person, mailer: mailer).send_email # Exercise expect(mailer).to have_received(:notify).with(person.email) # Verify end Testes complicados > Bangunçados -
@camposmilaa Testes fazem 3 coisas it 'sends email to person'
do mailer = spy('my mailer') # Setup person = Person.new(name: 'any-name', email: '[email protected]') # Setup Messenger.new(person, mailer: mailer).send_email # Exercise expect(mailer).to have_received(:notify).with(person.email) # Verify end Testes complicados > Bangunçados -
@camposmilaa 1. 2. 3. 4. Sem clareza Bangunçados Mágicos Espertos
demais Testes complicados -
@camposmilaa Testes mágicos it 'greets a person' do # ...
end it 'gracefully greets a person' do # ... end Testes complicados > Mágicos -
@camposmilaa Testes mágicos it 'greets a person' do person =
Person.new(name: 'any-name') response = Messenger.new(person).greet expect(response).to eq 'Hello, any-name' end it 'gracefully greets a person' do person = Person.new(name: 'any-name') response = Messenger.new(person).fancy_greet expect(response).to eq "Good afternoon, ma'am any-name!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos it 'greets a person' do person =
Person.new(name: 'any-name') response = Messenger.new(person).greet expect(response).to eq 'Hello, any-name' end it 'gracefully greets a person' do person = Person.new(name: 'any-name') response = Messenger.new(person).fancy_greet expect(response).to eq "Good afternoon, ma'am any-name!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos it 'greets a person' do person =
Person.new(name: 'any-name') response = Messenger.new(person).greet expect(response).to eq 'Hello, any-name' end it 'gracefully greets a person' do person = Person.new(name: 'any-name') response = Messenger.new(person).fancy_greet expect(response).to eq "Good afternoon, ma'am any-name!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos it 'greets a person' do person =
Person.new(name: 'any-name') response = Messenger.new(person).greet expect(response).to eq 'Hello, any-name' end it 'gracefully greets a person' do person = Person.new(name: 'any-name') response = Messenger.new(person).fancy_greet expect(response).to eq "Good afternoon, ma'am any-name!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos it 'greets a person' do person =
Person.new(name: 'any-name') response = Messenger.new(person).greet expect(response).to eq 'Hello, any-name' end it 'gracefully greets a person' do person = Person.new(name: 'any-name') response = Messenger.new(person).fancy_greet expect(response).to eq "Good afternoon, ma'am any-name!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos let(:person) { Person.new(name: 'any-name') } it 'greets
a person' do response = Messenger.new(person).greet expect(response).to eq 'Hello, any-name' end it 'gracefully greets a person' do response = Messenger.new(person).fancy_greet expect(response).to eq "Good afternoon, ma'am any-name!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos let(:person) { Person.new(name: 'any-name') } it 'greets
a person' do response = Messenger.new(person).greet expect(response).to eq 'Hello, any-name' end it 'gracefully greets a person' do response = Messenger.new(person).fancy_greet expect(response).to eq "Good afternoon, ma'am any-name!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos let(:person) { Person.new(name: 'any-name') } let(:messenger) {
Messenger.new(person) } it 'greets a person' do expect(messenger.greet).to eq 'Hello, any-name' end it 'gracefully greets a person' do expect(messenger.fancy_greet).to eq "Good afternoon, ma'am any-name!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos let(:person) { Person.new(name: 'any-name') } let(:messenger) {
Messenger.new(person) } it 'greets a person' do expect(messenger.greet).to eq 'Hello, any-name' end it 'gracefully greets a person' do expect(messenger.fancy_greet).to eq "Good afternoon, ma'am any-name!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos let(:person) { Person.new(name: 'any-name') } let(:messenger) {
Messenger.new(person) } it 'greets a person' do expect(messenger.greet).to eq 'Hello, any-name' end it 'gracefully greets a person' do expect(messenger.fancy_greet).to eq "Good afternoon, ma'am any-name!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos let(:person) { Person.new(name: 'any-name') } let(:messenger) {
Messenger.new(person) } it 'greets a person' do expect(messenger.greet).to eq "Hello, #{person.name}" end it 'gracefully greets a person' do expect(messenger.fancy_greet).to eq "Good afternoon, ma'am #{person.name}!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos let(:person) { Person.new(name: 'any-name') } let(:messenger) {
Messenger.new(person) } it 'does an entirely different thing' do # .... end it 'greets a person' do expect(messenger.greet).to eq "Hello, #{person.name}" end it 'gracefully greets a person' do expect(messenger.fancy_greet).to eq "Good afternoon, ma'am #{person.name}!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos let(:person) { Person.new(name: 'any-name') } let(:messenger) {
Messenger.new(person) } it 'does nothing sometimes' do # .... end it 'does an entirely different thing' do # .... end it 'greets a person' do expect(messenger.greet).to eq "Hello, #{person.name}" end it 'gracefully greets a person' do expect(messenger.fancy_greet).to eq "Good afternoon, ma'am #{person.name}!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos let(:person) { Person.new(name: 'any-name') } let(:messenger) {
Messenger.new(person) } it 'does any other thing' do # .... end it 'does nothing sometimes' do # .... end it 'does an entirely different thing' do # .... end it 'greets a person' do expect(messenger.greet).to eq "Hello, #{person.name}" end it 'gracefully greets a person' do expect(messenger.fancy_greet).to eq "Good afternoon, ma'am #{person.name}!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos let(:person) { Person.new(name: 'any-name') } let(:messenger) {
Messenger.new(person) } it 'does something else' do # .... end it 'does any other thing' do # .... end it 'does nothing sometimes' do # .... end it 'does an entirely different thing' do # .... end it 'greets a person' do expect(messenger.greet).to eq "Hello, #{person.name}" end it 'gracefully greets a person' do expect(messenger.fancy_greet).to eq "Good afternoon, ma'am #{person.name}!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos let(:person) { Person.new(name: 'any-name') } let(:messenger) {
Messenger.new(person) } it 'does something' do # .... end it 'does something else' do # .... end it 'does any other thing' do # .... end it 'does nothing sometimes' do # .... end it 'does an entirely different thing' do # .... end it 'greets a person' do expect(messenger.greet).to eq "Hello, #{person.name}" end it 'gracefully greets a person' do expect(messenger.fancy_greet).to eq "Good afternoon, ma'am #{person.name}!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos let(:person) { Person.new(name: 'any-name') } let(:messenger) {
Messenger.new(person) } it 'does something' do # .... end it 'does something else' do # .... end it 'does any other thing' do # .... end it 'does nothing sometimes' do # .... end it 'does an entirely different thing' do # .... end it 'greets a person' do expect(messenger.greet).to eq "Hello, #{person.name}" end it 'gracefully greets a person' do expect(messenger.fancy_greet).to eq "Good afternoon, ma'am #{person.name}!" end Testes complicados > Mágicos -
@camposmilaa Testes mágicos let(:person) { Person.new(name: 'any-name') } let(:messenger) {
Messenger.new(person) } it 'does something' do # .... end it 'does something else' do # .... end it 'does any other thing' do # .... end it 'does nothing sometimes' do # .... end it 'does an entirely different thing' do # .... end it 'greets a person' do expect(messenger.greet).to eq "Hello, #{person.name}" end it 'gracefully greets a person' do expect(messenger.fancy_greet).to eq "Good afternoon, ma'am #{person.name}!" end Testes complicados > Mágicos -
@camposmilaa Mystery Guest it 'gracefully greets a person' do expect(messenger.fancy_greet).to
eq "Good afternoon, ma'am #{person.name}!" end Testes complicados > Mágicos -
@camposmilaa Mystery Guest it 'gracefully greets a person' do expect(messenger.fancy_greet).to
eq "Good afternoon, ma'am #{person.name}!" end Testes complicados > Mágicos -
@camposmilaa Mystery Guest it 'greets a person' do person =
Person.new(name: 'any-name') response = Messenger.new(person).greet expect(response).to eq 'Hello, any-name' end it 'gracefully greets a person' do person = Person.new(name: 'any-name') response = Messenger.new(person).fancy_greet expect(response).to eq "Good afternoon, ma'am any-name!" end Testes complicados > Mágicos -
@camposmilaa it 'greets a person' do person = Person.new( name:
'any-name', att2: 'xpto', att3: 'xpto', att4: 'xpto', att5: 'xpto', att6: 'xpto', att7: 'xpto', att8: 'xpto', att9: 'xpto', att10: 'xpto', att11: 'xpto', att12: 'xpto', att13: 'xpto', att14: 'xpto', att15: 'xpto', att16: 'xpto', att17: 'xpto', att18: 'xpto', att19: 'xpto', att20: 'xpto', att21: 'xpto', att22: 'xpto', att23: 'xpto' ) response = Messenger.new(person).greet expect(response).to eq 'Hello, any-name' end Mystery Guest Testes complicados > Mágicos -
@camposmilaa it 'greets a person' do person = Person.new(person_attributes.merge(name: 'any-name'))
response = Messenger.new(person).greet expect(response).to eq 'Hello, any-name' end Mystery Guest Testes complicados > Mágicos -
@camposmilaa 1. 2. 3. 4. Sem clareza Bangunçados Mágicos Espertos
demais Testes complicados -
@camposmilaa Hora de refatorar!! Setup complexo/grande Múltiplas verificações Muitas dependências
Muitas responsabilidades -
@camposmilaa Hora de refatorar!! Setup complexo/grande Múltiplas verificações Muitos passos
de "exercise" Muitas dependências Muitas responsabilidades -
@camposmilaa Hora de refatorar!! Setup complexo/grande Múltiplas verificações Muitos passos
de "exercise" Muitas dependências Muitas responsabilidades API complexa -
@camposmilaa Hora de refatorar!! Setup complexo/grande Múltiplas verificações Código complexo
no test (ex. Loops, métodos privados) Muitos passos de "exercise" Muitas dependências Muitas responsabilidades API complexa -
@camposmilaa Hora de refatorar!! Muitos passos de "exercise" Setup complexo/grande
Múltiplas verificações Código complexo no test (ex. Loops, métodos privados) Muitos passos de "exercise" Muitas dependências Muitas responsabilidades Código complexo API complexa -
@camposmilaa Testes redundantes controller service model repository A B Testes
desnecessários controller service model repository -
@camposmilaa Testes redundantes controller service model repository A B A
B Testes desnecessários controller service model repository A B -
@camposmilaa Testes redundantes controller service model repository A B A
B A B Testes desnecessários controller service model repository A B A B -
@camposmilaa Testes redundantes controller service model repository A B A
B A B C Testes desnecessários controller service model repository A C A B A B -
@camposmilaa Testes redundantes controller service model repository A B A
B A B C C Testes desnecessários controller service model repository A A A B -
@camposmilaa Testes redundantes controller service model repository A B A
B A B C C C Testes desnecessários controller service model repository A A A -
@camposmilaa Testes redundantes controller service model repository A B A
B A B C C C Testes desnecessários controller service model repository A A A -
@camposmilaa Testes redundantes Menos testes em camadas Teste para tudo
Testes desnecessários -
@camposmilaa Testes redundantes controller service model repository A B A
A C Testes desnecessários controller service model repository A A A -
@camposmilaa Testes ruins são melhor que nada Não ter testes
é melhor que ter testes ruins