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

SOLID, tests and Cognitive Psychology

SOLID, tests and Cognitive Psychology

If we look at what we know about Cognitive Psychology we may discover that those needs overlap the needs of our tests. As we learn about cognitive psychology we gain a deeper understanding of why and how good design is indeed good for us.

Presentation given at NewCrafts Toulouse

martinsson

April 05, 2019
Tweet

More Decks by martinsson

Other Decks in Programming

Transcript

  1. Exceptions! exceptionalMethod(userId, data) { try { let isOwner try {

    isOwner = this.auth.isOwnerOf(userId, data.id) } catch (e) { this.logger.error('got http exception from authService') } if (isOwner) { this.dao.update(data.id, data) } } catch (daoException) { this.logger.error('exception caught') } } nonExceptionalMethod(userId, data) { let isOwner = this.auth.isOwnerOf(userId, data.id) if (isOwner) { this.dao.update(data.id, data) } }
  2. Duplication registerMobile(person) { if (person.age < 13) { throw new

    Error('too young') } if (person.name === null) { throw new Error('person must have name') } if (this.hasNonDigits(person.phoneNumber)) { new Error('invalid phone number') } console.log('do some stuff') this.dao.insertPerson(person) } registerEmail(person) { if (person.age < 13) { throw new Error('too young') } if (person.name === null) { throw new Error('person must have name') } if (person.email.indexOf('@') <= 0) { throw new Error('invalid email') } console.log('do some stuff') this.dao.insertPerson(person) }
  3. On n’a pas envie de tester du code pas important

    Et si c’était à cause de la duplicaton?
  4. l’angoisse de null function printItemNames(data) { if (data.prop) { if

    (data.prop.cart) { if (data.prop.cart.getList() !== null && data.prop.cart.getList() !== undefined) { for (let listItem of data.prop.cart.getList()) { if (listItem.description) { if (listItem.description.name) { console.debug('Phew, finally here!') // actual business logic console.log('And the item name is... ' + listItem.description.name) } } } } } } } function printItemNames(data) { for (let listItem of data.prop.cart.getList()) { console.debug('Phew, finally here!') // actual business logic console.log('And the item name is... ' + listItem.description.name) } }
  5. L’angoisse de null • Ne retournez pas de valeur null

    • Protégez de null en entrée de l'app
  6. Conditions function conditionalCode1(data) { if (data.something === 'val') { doSomething()

    if (data.age <= 40 || 'toto' !== data.something) { doAThirdThing() } else { doSomethingAdditional() } } }
  7. Conditions, quand on aime … function conditionalCode(data) { if (data.prop)

    { if (data.prop.service) { if (data.prop.service.getList() === null && data.prop.service.getList().size > 0) { return 'processed ' + data.prop.service.getList().length + ' results' } else { let defaultResult = 'waiting' return defaultResult; } } } }
  8. Arguments indirects function updateCartItems() { let httpSession = HttpSession.getInstance() let

    rawCart = httpSession.getCookie().getValue('cart') let cart = new Cart(rawCart) if (cart.lastModificationDate < Date.now() - 24 * 60 * 60 * 1000) { cart.removeAllItems(); } // etc ... // heavy logic to make sure availability is still ok, // that prices haven't changed // that items in the cart haven't expired etc }
  9. Code inspectable function hardToTest() { let data = getStuffFromWebservice() //

    // pure logic // pure logic // pure logic // pure logic // pure logic // pure logic // pure logic // pure logic // pure logic // let result let saveResult = saveToDatabase(result) } function easyToTest() { let data = getStuffFromWebservice() let result = easyToTestPureFunction(data) let saveResult = saveToDatabase(result) } function easyToTestPureFunction(data) { // // pure logic // pure logic // pure logic // pure logic // pure logic // pure logic // pure logic // pure logic // pure logic // }
  10. • “The tests are a canary in coal mining revealing

    by their distress the presence of evil design vapors” - Kent Beck • “Sometimes we find it difficult to write a test … this usually means that our design can be improved” - S. Freeman, N. Pryce
  11. – Phil Karlton “There are only two hard things in

    Computer Science: cache invalidation and naming things.”
  12. – Bertrand Meyer "software entities (classes, modules, functions, etc.) should

    be open for extension, but closed for modification" OCP
  13. Notre cerveau a besoin de • Blocs de 4-5 éléments

    • noms • cohésion • assembler plutôt que modifier
  14. Notre code de prod a besoin de • peu de

    duplication • peux de couplage • cohésion • morceaux à assembler
  15. Les tests ont besoin de • Peu de duplication •

    Isolation des dépendances • Petites choses • Responsabilités séparés • Code simple
  16. Les tests, le cerveau et les principes poussent le code

    dans le même sens Sauf la facilité d’écriture?
  17. ? • changit.fr • cognitive psychology • Tom Mullen, Writing

    code for other people, 2009 • Kessler, Y., & Meiran, N. (2006), • Michael Feathers (synergy between testability and good design)