Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[The Conf 2018] Stop hating your test suite

Camila Campos
September 21, 2018

[The Conf 2018] Stop hating your test suite

We all know that automated tests are extremely important because, among other reasons, they guarantee code quality and correct application behavior. Despite this, many times we end up with a test suite that, additionally to being hard to understand and maintain, is not trustworthy.
This talk will show you how to recognize and avoid some of the most common problems that make us hate our tests, as well as give you tips on how to improve them.

PS. The gifs don't work on speaker deck, sorry about that )):

Video available at: https://www.infoq.com/br/presentations/stop-hating-your-test-suite/

Camila Campos

September 21, 2018
Tweet

More Decks by Camila Campos

Other Decks in Programming

Transcript

  1. @camposmilaa Online collateral loans High quality credit Lower interest rates!

    creditas.com.br vagas.creditas.com.br @CreditasBR
  2. @camposmilaa 4 Communities together Encourage women in Tech Talks &

    Workshops & Panels womendevsummit.com fb.com/womendevsummit @WomenDevSummit
  3. @camposmilaa Tests at Creditas Slow tests Quantity Time to run

    End to End 13 ~ 15 min Integration ~ 3k < 3 min Unit ~ 6k ~ 1 min
  4. @camposmilaa Rules and Conventions Slow tests Database External Dependencies Collaborators

    End to End Yes Yes* Yes Integration Yes No Yes Unit No No No
  5. @camposmilaa Test pyramid e2e integration unit Slow tests When changing

    a class When testing a feature Before commiting
  6. @camposmilaa it 'sends a message' do person = Person.new(name: 'John')

    response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Complicated tests > Unclear
  7. @camposmilaa it 'sends a message' do person = Person.new(name: 'John')

    response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Complicated tests > Unclear
  8. @camposmilaa it 'sends a message' do person = Person.new(name: 'John')

    response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Complicated tests > Unclear
  9. @camposmilaa it 'sends a message' do person = Person.new(name: 'John')

    response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Complicated tests > Unclear
  10. @camposmilaa it 'sends a message' do person = Person.new(name: 'John')

    response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Complicated tests > Unclear
  11. @camposmilaa Bad description it 'sends a message' do person =

    Person.new(name: 'John') response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Complicated tests > Unclear
  12. @camposmilaa Bad description it 'sends a message' do person =

    Person.new(name: 'John') response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Complicated tests > Unclear
  13. @camposmilaa Bad description it 'greets a person' do person =

    Person.new(name: 'John') response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Complicated tests > Unclear
  14. @camposmilaa Bad description it 'greets a person' do person =

    Person.new(name: 'John') response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Complicated tests > Unclear
  15. @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 Complicated tests > Unclear
  16. @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 Complicated tests > Unclear
  17. @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 Complicated tests > Unclear
  18. @camposmilaa Misleading unimportant stuff 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 Complicated tests > Unclear
  19. @camposmilaa Misleading unimportant stuff it 'greets a person' do person

    = Person.new(name: 'John') response = Messenger.new(person).greet expect(response).to eq 'Hello, John' end Complicated tests > Unclear
  20. @camposmilaa Misleading unimportant stuff it 'greets a person' do person

    = Person.new(name: 'any-name') response = Messenger.new(person).greet expect(response).to eq 'Hello, any-name' end Complicated tests > Unclear
  21. @camposmilaa Set up everything needed Call whatever is being tested

    Verify expected behavior Complicated tests > Messy
  22. @camposmilaa 3 things test do 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 Complicated tests > Messy
  23. @camposmilaa 3 things test do 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 Complicated tests > Messy
  24. @camposmilaa 3 things test do 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 Complicated tests > Messy
  25. @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 3 things test do Complicated tests > Messy
  26. @camposmilaa 3 things test do 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 Complicated tests > Messy
  27. @camposmilaa 3 things test do 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 Complicated tests > Messy
  28. @camposmilaa 3 things test do 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 Complicated tests > Messy
  29. @camposmilaa 3 things test do 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 Complicated tests > Messy
  30. @camposmilaa 3 things test do 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 Complicated tests > Messy
  31. @camposmilaa 3 things test do 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 Complicated tests > Messy
  32. @camposmilaa 3 things test do 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 Complicated tests > Messy
  33. @camposmilaa 3 things test do 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 Complicated tests > Messy
  34. @camposmilaa 3 things test do 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 Complicated tests > Messy
  35. @camposmilaa 3 things test do 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 Complicated tests > Messy
  36. @camposmilaa Obscure tests it 'greets a person' do # ...

    end it 'gracefully greets a person' do # ... end Complicated tests > Obscure
  37. @camposmilaa Obscure tests 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 Complicated tests > Obscure
  38. @camposmilaa Obscure tests 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 Complicated tests > Obscure
  39. @camposmilaa Obscure tests 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 Complicated tests > Obscure
  40. @camposmilaa Obscure tests 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 Complicated tests > Obscure
  41. @camposmilaa Obscure tests 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 Complicated tests > Obscure
  42. @camposmilaa Obscure tests 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 Complicated tests > Obscure
  43. @camposmilaa Obscure tests 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 Complicated tests > Obscure
  44. @camposmilaa Obscure tests 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 Complicated tests > Obscure
  45. @camposmilaa Obscure tests 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 Complicated tests > Obscure
  46. @camposmilaa Obscure tests 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 Complicated tests > Obscure
  47. @camposmilaa Obscure tests 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 Complicated tests > Obscure
  48. @camposmilaa Obscure tests 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 Complicated tests > Obscure
  49. @camposmilaa Obscure tests 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 Complicated tests > Obscure
  50. @camposmilaa Obscure tests 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 Complicated tests > Obscure
  51. @camposmilaa Obscure tests 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 Complicated tests > Obscure
  52. @camposmilaa Obscure tests 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 Complicated tests > Obscure
  53. @camposmilaa Mystery Guest it 'gracefully greets a person' do expect(messenger.fancy_greet).to

    eq "Good afternoon, ma'am #{person.name}!" end Complicated tests > Obscure
  54. @camposmilaa Mystery Guest it 'gracefully greets a person' do expect(messenger.fancy_greet).to

    eq "Good afternoon, ma'am #{person.name}!" end Complicated tests > Obscure
  55. @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 Complicated tests > Obscure
  56. @camposmilaa Refactor time! Complex/Big setup Multiple verifications Complex code on

    test (ex. Loops, private method calls) Multiple "exercise" steps Too many dependencies Too many responsibilities Complex API
  57. @camposmilaa Refactor time! Multiple "exercise" steps Complex/Big setup Multiple verifications

    Complex code on test (ex. Loops, private method calls) Multiple "exercise" steps Too many dependencies Too many responsibilities Complex code Complex API