Outside-In TDD

@pierodibello

Sandro Mancuso Style

Lessons learned from

WATCHED the "London vs Chicago TDD styles" episodes?

What I like about Sandro's style

Great confidence with IntelliJ IDEA IDE

  • shortcuts,

  • templates,

  • refactoring moves,

  • ...

Keyboard-first

  • Standard shortcuts

  • customized SHORTCUTS

Clear ideas on the design and layering of a webapp 

  • WHERE TO PUT RESPONSIBILITIES

  • How to name Things

High frequency of commits

What I don't like much

still need to think about 🤔

Having to write all the ITs / ATs before start writing any UT / production code

TO USE THE "ATS AS A PROBE", YOU HAVE TO HAVE THE ATS IN PLACE BEFORE START CODING, DON'T YOU 🤔?

this also mean that you actually commit code with red tests (broken build!)

I wonder if this approach could work when working in a team and with a "real project" (something you work on for weeks, months, not days) 🤔

Mocking Spark objects

Mocking Spark objects (like "Request" or "Response") mean you have to know in advance the Spark Web Framework, because otherwise you could not know which method Spark will really call in the end...

Sandro's style is a bit of erratic sometimes

  • Jumping from a UT to another,
  • Jumping from production code to ATs,
  • Filling the holes that you left behind

A TODO list MIGHT HELP?

A strong focus is need With this style

Living with many unresolved compilation errors

Sandro often works and codes with many still unresolved compilation errors, which - I understand - is part of his flow and approach...

Sometimes this goes too far (e.g. you have syntax issues you cannot spot because everything is red...)

A strong focus is need With this style

Again, I think you have to have a strong focus to not get lost while having to deal with many compilation errors

Upfront helper methods

Sandro creates many small helper methods upfront

  • e.g. "postsTextFrom", "jsonContaining", ...
  • They do not even compile at the beginning!
  • This seems coming from his great experience and indeed from his style (he knows he'll need those, so he creates them as early as possible)
  • I tend to prefer to let those helper methods emerge when refactoring with a green bar

use of exceptions as a way to control THE flow... 🤔

WHAT ARE THE ALTERNATIVES?

Noteworthy things I noticed!

Tests

  • Unit test classes are named with the "Should" suffix instead of the classic "Test" suffix
  • Test method names follow the snake case convention (both for UTs and ITs)
PostServiceShould, 
LoginAPIShould, 
UserRepositoryShould 

​inform_when_a_username_is_already_taken
return_user_matching_valid_credentials
return_all_users
detect_a_following_already_exists

Integration test classes are named with an "IT_" prefix

 

  • e.g. IT_RegistrationAPI, IT_UsersAPI

Extensive use of constants in the tests to stand for fixed values

I normally create them as constants because I don't care what they are..."

  • USER_ID, USER for an instance of User,
  • POST_TEXT,
  • POST_ID,
  • DATE_TIME,
  • PASSWORD,
  • USER_CREDENTIALS

Runtime exception or Checked exceptions?

  • Sandro prefers to use checked exceptions for "business-related" error conditions, exceptions from which you could recover from
    • In those case a checked exceptions force the layer above to deal with that condition





  • While he prefers to use runtime exceptions for error conditions you could not recover from.

E.g. The "PostsAPI" class needs to deal with an "InappropriateLanguageException", because it's part of the logic.

 

Sandro prefers concrete classes to interfaces?

Real London School of TDD?

It seems Sandro doesn't use interfaces when designing with TDD:

when some new collaborator emerges while writing a unit test, its implementation will be a concrete class, not an interface.

A different way is the "interface discovery" approach followed by Steve Freeman and Nat Pryce, explained in "Growing Object-Oriented Software, Guided by Tests"

 

I guess this is due to his "pragmatism" in doing TDD...

 

(SEE ALSO HOW HE AVOIDS BABY STEPS)

see also HIS Bank Account Kata

Commit style

  • The commit message used by Sandro contains often the name of the class and methods implemented

    UserService.createUser(registrationData) implemented.

  • The verb is at past tense

AAA and the "backwards" style

When writing a test, I always start from the bottom: the assertion (this is what I expect to happen). (ASSERT)

Then I ask: 'what should I need to trigger this?' (ACT)

Then I think at the bare minimum I have to do in order to have all in place. (ARRANGE)

The role of the Integration tests / Acceptance Tests

The UTs drive the architecture, the ATs probe the architecture

  • "Integration tests / Acceptance Tests act as a probe to where we are and what we have still need to finish, in order to complete the feature. They show me what is left to be tested, and this will guide me to the next step, going inside starting from the outside."
  • "The Acceptance Tests act as a 'north star', a guiding star: they make sure we don't forget anything, because in the ATs I use the real stuff, not mocks."

The UTs drive the architecture, the ATs probe the architecture

  • Classically, ATs probe the completion of behavior (when we're done). In Sandro style, ATs probe the completion of architecture (what is the next layer to code, what is still missing in the architecture).
  • "The ATs guarantee that the app is providing the expected behaviour to the external world, while through the UTs I derive the design, layer by layer."

Use objects, avoid primitive obsession!

"Design in the red"

It's all about confidence. If I don't know, I take small steps, I put all in the same class and then refactor later, when I'll be GREEN.

Using builders in tests

Thanks!

@pierodibello

@xpeppers

Made with Slides.com