87
@benjamminstl How Not to Suck at Unit Tests A presentation for Code PaLOUsa April 28, 2015

How not to suck at unit tests

Embed Size (px)

Citation preview

Page 1: How not to suck at unit tests

@benjamminstl

How Not to Suck at Unit TestsA presentation for Code PaLOUsa April 28, 2015

Page 2: How not to suck at unit tests

@benjamminstl

How I’ve Sucked at Unit TestsA presentation for Code PaLOUsa April 28, 2015

Page 3: How not to suck at unit tests

@benjamminstl

Ben BishopPurdue University graduate with a degree in Computer Graphics Technology. 10+ years of development experience. Rendr Co-Founder.

Page 4: How not to suck at unit tests

@benjamminstl

David Ortinau15+ years of development experience. Xamarin MVP. Beard Enthusiast. Rendr Co-Founder.

Page 5: How not to suck at unit tests

@benjamminstl

A little about RendrWe are a people focused software studio, building engaging solutions to solve real world problems and improve lives.

Page 6: How not to suck at unit tests

@benjamminstl

Page 7: How not to suck at unit tests

@benjamminstl

Page 8: How not to suck at unit tests

@benjamminstl

Page 9: How not to suck at unit tests

@benjamminstl

Page 10: How not to suck at unit tests

@benjamminstl

Page 11: How not to suck at unit tests

@benjamminstl

Page 12: How not to suck at unit tests

@benjamminstl

GoalsIf you take just one thing from this presentation, then I have achieved my goal.

Page 13: How not to suck at unit tests

@benjamminstl

2009

Page 14: How not to suck at unit tests

@benjamminstl

Typical Production Experience

Time

Productivity

Page 15: How not to suck at unit tests

@benjamminstl

Typical Production Experience

Time

Productivity

We can totally do that! We’re Rockstar Ninjas!

Page 16: How not to suck at unit tests

@benjamminstl

Typical Production Experience

Time

Productivity

Noooooo, the world will end! We hate our lives.

Page 17: How not to suck at unit tests

@benjamminstl

Page 18: How not to suck at unit tests

@benjamminstl

Page 19: How not to suck at unit tests

@benjamminstl

A Culture of NO

Page 20: How not to suck at unit tests

@benjamminstl

A Culture of Friction

Page 21: How not to suck at unit tests

@benjamminstl

NO

NO

NONO

NO

NO

NOT Possible

Can’tNOT within scope

NO

NO Time

Page 22: How not to suck at unit tests

@benjamminstl

Friction wastes energyFriction robs us of efficiency

Page 23: How not to suck at unit tests

@benjamminstl

Page 24: How not to suck at unit tests

@benjamminstl

Scrum

Ken Schwaber

Page 25: How not to suck at unit tests

@benjamminstl

Page 26: How not to suck at unit tests

@benjamminstl

Page 27: How not to suck at unit tests

@benjamminstl

Saying “yes” introduces risk.

Page 28: How not to suck at unit tests

@benjamminstl

The Land Scrum Forgothttps://www.youtube.com/watch?v=hG4LH6P8Syk

Page 29: How not to suck at unit tests

@benjamminstl

Segue

Page 30: How not to suck at unit tests

@benjamminstl

Six Projects with Unit Tests

Page 31: How not to suck at unit tests

@benjamminstl

Six “Failures”

Page 32: How not to suck at unit tests

@benjamminstl

Failed Attempt #1 at Unit Testing

Page 33: How not to suck at unit tests

@benjamminstl

Page 34: How not to suck at unit tests

@benjamminstl

Lessons Learned- Couldn’t automate testing through UI- Video streaming is extremely hard to test- Model/View architecture did not facilitate testing- Any testable state was in the view

Page 35: How not to suck at unit tests

@benjamminstl

Testable View State

Page 36: How not to suck at unit tests

@benjamminstl

Failed Attempt #2 at Unit Testing

Page 37: How not to suck at unit tests

@benjamminstl

Page 38: How not to suck at unit tests

@benjamminstl

Lessons Learned• Tests that test a server API aren’t Unit Tests• Hard to figure out how to not pollute your database with junk

data• Actually considered “integration test”• Best to separate server tests from app tests• Again, architecture didn’t support true unit tests

Page 39: How not to suck at unit tests

@benjamminstl

Separate Server Tests

Page 40: How not to suck at unit tests

@benjamminstl

Stay DRY

Page 41: How not to suck at unit tests

@benjamminstl

Stay DRY

Page 42: How not to suck at unit tests

@benjamminstl

Stay Performant

Page 43: How not to suck at unit tests

@benjamminstl

Failed Attempt #3 at Unit Testing

Page 44: How not to suck at unit tests

@benjamminstl

Page 45: How not to suck at unit tests

@benjamminstl

Lessons Learned• Hard to write tests for already existing classes• Couldn’t test private functions

• Spies• Have your TestCase extend the class you’re testing• Levels!

Page 46: How not to suck at unit tests

@benjamminstl

Jason Sonmezhttp://simpleprogrammer.com/2010/12/12/back-to-basics-why-unit-testing-is-hard/

Level 1 Unit Testing is where we have a single class with no external dependencies and no state. We are just testing an algorithm.

Level 2 Unit Testing is where we have a single class with no external dependencies but it does have state. We are setting up an object and testing it as a whole.

Level 3 Unit Testing is when we have a single class with at least one external dependency, but it does not depend on its own internal state.

Level 4 Unit Testing is when we have a single class with at least one external dependency and depends on its own internal state.

Page 47: How not to suck at unit tests

@benjamminstl

How do you test protected elements?

Page 48: How not to suck at unit tests

@benjamminstl

Test Spy

Page 49: How not to suck at unit tests

@benjamminstl

Test Spy

Page 50: How not to suck at unit tests

@benjamminstl

Failed Attempt #4 at Unit Testing

Page 51: How not to suck at unit tests

@benjamminstl

Page 52: How not to suck at unit tests

@benjamminstl

Lessons Learned• Use TestCase data meta tags• ViewModel architecture is very testable• Beware Yak Shaving

• testing setter/getters• constructor assignments!

!

Page 53: How not to suck at unit tests

@benjamminstl

Solution

Page 54: How not to suck at unit tests

@benjamminstl

Solution

Page 55: How not to suck at unit tests

@benjamminstl

Solution

Page 56: How not to suck at unit tests

@benjamminstl

Failed Attempt #5 at Unit Testing

Page 57: How not to suck at unit tests

@benjamminstl

Page 58: How not to suck at unit tests

@benjamminstl

Lessons Learned• Don’t use static/hard-singleton classes

• Static classes and/or extension methods cannot be replaced with Fake or Mock

• TestData brittleness• Use data fixtures like AutoFixture, otherwise you have to

constantly update your test data generators.• When testing integration test behavior not results• Beware of the Red, Green, Refactor blur

Page 59: How not to suck at unit tests

@benjamminstl

VMIC

View

CommandInputInvoker OutputInvoker

Mediator

Page 60: How not to suck at unit tests

@benjamminstl

Page 61: How not to suck at unit tests

@benjamminstl

Testing Results

Page 62: How not to suck at unit tests

@benjamminstl

Static Class

Page 63: How not to suck at unit tests

@benjamminstl

FakeItEasy

Page 64: How not to suck at unit tests

@benjamminstl

FakeItEasy

Page 65: How not to suck at unit tests

@benjamminstl

Homegrown Brittleness

Page 66: How not to suck at unit tests

@benjamminstl

AutoFixture

Page 67: How not to suck at unit tests

@benjamminstl

Failed Attempt #6 at Unit Testing

Page 68: How not to suck at unit tests

@benjamminstl

Page 69: How not to suck at unit tests

@benjamminstl

Lessons Learned• Set up brittleness

• Don’t use DI containers• Readability

• What is easy to write is not easy to read• Find ways to write less code

• Use interface tools/markup• Binding frameworks• Share code across platforms!

Page 70: How not to suck at unit tests

@benjamminstl

Improve Readability

Page 71: How not to suck at unit tests

@benjamminstl

Improve Readability

Page 72: How not to suck at unit tests

@benjamminstl

SolutionLess code

Page 73: How not to suck at unit tests

@benjamminstl

All of the Native, None of the IsolationThe best of both worlds: Code Portability and Tailored UIs

Number of Classes Percent (with Unit Tests) Percent (no Unit Tests)Core 207 43.2% 64.4%Tests 158 32.9%

Android 58* 12.2% 18.1%

iOS 56 11.7% 17.5%

Total 479 (321)

*includes .axml and .xml files

Page 74: How not to suck at unit tests

@benjamminstl

All of the Native, None of the IsolationThe best of both worlds: Code Portability and Tailored UIs

Number of Lines Percent (with Unit Tests) Percent (no Unit Tests)Core 9,886 35.3% 44.9%Tests 5,979 21.4%

Android 5,606* 20.0% 20.0%

iOS 6,512 23.3% 29.6%

Total 27,983 (22,004)

*includes .axml and .xml files

Page 75: How not to suck at unit tests

@benjamminstl

MVVM

View

ViewModel

(via bindings)

Service

Page 76: How not to suck at unit tests

@benjamminstl

Example

Page 77: How not to suck at unit tests

@benjamminstl

Closing Thoughts

Page 78: How not to suck at unit tests

@benjamminstl

Unit Testing is a habit that is no different than dieting or working out.

Page 79: How not to suck at unit tests

@benjamminstl

Small steps to a larger goal works better than trying to be perfect from the get go.

Page 80: How not to suck at unit tests

@benjamminstl

Small steps to a larger goal works better than trying to be perfect from the get go.

Page 81: How not to suck at unit tests

@benjamminstl

Test Code isn’t easyThe quality of your test code has to be equal to or greater than your production code. If test code is an after thought and isn’t refactored it too will become brittle.

Page 82: How not to suck at unit tests

@benjamminstl

Get used to failureA lot of devs want to avoid unit testing because seeing failed tests forces you to deal with the consequences of your change.

Page 83: How not to suck at unit tests

@benjamminstl

Ignorance is bliss…Until a client asks you to change something and you don’t know what’s going to break.

Page 84: How not to suck at unit tests

@benjamminstl

Research

Page 85: How not to suck at unit tests

@benjamminstl

Practice

Page 86: How not to suck at unit tests

@benjamminstl

Code Reviews

Page 87: How not to suck at unit tests

@benjamminstl

Thank You

David Ortinau 314.280.8445 [email protected]

Ben Bishop 314.775.8800 [email protected]