Slide 1

Slide 1 text

Tests SOLID et psychologie cognitive Johan Martinsson @johan_alps changit.fr

Slide 2

Slide 2 text

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) } }

Slide 3

Slide 3 text

Exceptions throw en bas, catch (tout) en haut

Slide 4

Slide 4 text

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) }

Slide 5

Slide 5 text

On n’a pas envie de tester du code pas important Et si c’était à cause de la duplicaton?

Slide 6

Slide 6 text

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) } }

Slide 7

Slide 7 text

L’angoisse de null • Ne retournez pas de valeur null • Protégez de null en entrée de l'app

Slide 8

Slide 8 text

Conditions function conditionalCode1(data) { if (data.something === 'val') { doSomething() if (data.age <= 40 || 'toto' !== data.something) { doAThirdThing() } else { doSomethingAdditional() } } }

Slide 9

Slide 9 text

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; } } } }

Slide 10

Slide 10 text

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 }

Slide 11

Slide 11 text

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 // }

Slide 12

Slide 12 text

• “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

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

Améliore-t-on le code?

Slide 16

Slide 16 text

Avec tests on a la possibilité de simplifier le code

Slide 17

Slide 17 text

Cercle vicieux/ vertueux

Slide 18

Slide 18 text

TDD requiert une maîtrise cognitive Etat préalable? Action? Résultat attendu?

Slide 19

Slide 19 text

Chunking

Slide 20

Slide 20 text

Mémoire court terme

Slide 21

Slide 21 text

Mémoire long terme - espace infinie Gael Varoquaux flickr Attribution 2.0 Generic (CC BY 2.0)

Slide 22

Slide 22 text

LTM est fait pour être étendu, pas mis à jour

Slide 23

Slide 23 text

Je t’ai refactoré ton code! C'est cadeau!

Slide 24

Slide 24 text

Ce sera plus simple … peut-être … un jour

Slide 25

Slide 25 text

Lorsque le code évolue, on invalide le cache du LTM

Slide 26

Slide 26 text

– Phil Karlton “There are only two hard things in Computer Science: cache invalidation and naming things.”

Slide 27

Slide 27 text

Optimisation de cache! Trouver quoi réécrire
 Réécrire moins

Slide 28

Slide 28 text

Chunk ~= unité de stockage • Un nom pour l’adressage • Couplage fort -> contamination

Slide 29

Slide 29 text

– Robert C Martin "A class should have only one reason to change," SRP

Slide 30

Slide 30 text

– Bertrand Meyer "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification" OCP

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

Notre cerveau a besoin de • Blocs de 4-5 éléments • noms • cohésion • assembler plutôt que modifier

Slide 34

Slide 34 text

Notre code de prod a besoin de • peu de duplication • peux de couplage • cohésion • morceaux à assembler

Slide 35

Slide 35 text

Les tests ont besoin de • Peu de duplication • Isolation des dépendances • Petites choses • Responsabilités séparés • Code simple

Slide 36

Slide 36 text

Les tests, le cerveau et les principes poussent le code dans le même sens Sauf la facilité d’écriture?

Slide 37

Slide 37 text

? • 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)