Roy Osherove on Unit Testing Good Practices and Horrible Mistakes
-
Upload
roy-osherove -
Category
Technology
-
view
8.497 -
download
3
Transcript of Roy Osherove on Unit Testing Good Practices and Horrible Mistakes
Unit Testing Good Practices & Horrible Mistakes
@RoyOsherove
What I do (artOfUnitTesting.com)
Courses on TDD, BDD in JS, Ruby, Java and C# TDD (EpiServer TDD, MVC TDD…)Courses for Team Leaders (5whys.com)Consulting & coaching through Bouvet
Contact.osherove.com
Team Agile - All rights reserved
Real World Agenda
Test Reviews
Making your tests TRUSTworthyCreating MAINTAINable testsREADable tests
RTFM
Test review vs. code review
Understand intent of developer10 times quickerDrill in when needed
Important for learning teamsHelps drive change
Maintainable
Trustworthy
Readable
Make Your tests trust worthy
Make it easy to runRemoving or changing testsAssuring code coverageAvoid test logic Avoid Manual Stub\Mock LogicDon’t Repeat Production Logic
Separate Unit From Integration Tests
Code coverage?
Worthless without a code reviewChange production code and see what happens
Make params into constsRemove “if” checks – or make into consts
If all tests pass - something is missing or something is not needed
Avoid test logic (MS Unity)
Another logic example:MVCDev.HtmlHelperTest.GetHttpContext()
Don’t repeat production logic
String user = “a”;String password= “b”;
String SomeResult = UnderTest.CreateMessage(user,password);
Assert.AreEqual( user + “,” + password,
SomeResult);
Don't use things that keep changing
DateTime.NowRandomEnvironment.TickCountThreadsEtc..
Tests that keep changing: NerdDinner
Creating maintainable tests
Avoid testing private/protected membersRe-use test code (Create, Manipulate, Assert)Enforce test isolationTest One Thing
Avoid Multiple AssertsOne mock per test
Use “relaxed” or “Non strict” mocks and stubs
Test only publics
“Unit” testing == “Unit Of Work Testing”Testing a private makes your test more brittleMakes you think about the design and usability of a featureTest-First leads to private members after Refactoring, but they are all tested!
But sometimes there’s not choice
Reuse test code
Create objects using common methods (factories)
[make_XX]Manipulate and configure initial state using common methods
[init_XX]Run common tests in common methods
[verify_XX]
Enforce test isolation
No dependency between tests!Don’t run a test from another test!Run alone or all together in any orderOtherwise – leads to nasty “what was that?” bugs
Avoid Multiple Asserts On different objects
String user = “a”;String password= “b”;
String SomeResult = UnderTest.CreateMessage(user,password);
Assert.AreEqual( user + “,” + password, SomeResult);
Assert.AreEqual (1,UnderTest.MessageCount);
Avoid Multiple AssertsMVCDev.LinkExtensionsTest L. 334
Avoid Multiple Asserts
Like having multiple testsBut the first the fails – kills the othersYou won’t get the big picture (some symptoms)Hard to nameCan lead to more debugging work
Avoid Multiple Mocks
Creating readable tests
StructureNo Magic values
In testIn mock\stub
Naming a unit testNaming variablesSeparate Assert from action
Structure
Are the tests easy to find?Can you find a test for a class, or a method?
Setup Mystery
Bad Naming
No Magic Values
Assert.AreEqual(1003, calc.Parse(“-1”));
Int parseResult = calc.Parse(NEGATIVE_ILLEGAL_NUMBER);
Assert.AreEqual(NEGATIVE_PARSE_RETURN_CODE, parseResult)
Hidden Values
Magic values in Fakes
Magic ValuesUnity InjectionMethodFixture
Call it what it is (mock\stub\fake)
Most “Mocks” are actually stubs.If it can be both, call it “Fake”
Naming a unit test
Method nameState under testExpected behavior/return value
Add_LessThanZero_ThrowsException()Another angle:Add_LessThanZero_ThrowsException2()
Naming
Separate Assert from Action
Assert is less clutteredMore readableAllows handling the return value if neededIt’s all about readability
Input Values Should Differ
X.Divide (1,1)X.Divide (1,2)
X.Check(“1,1”)X.Check(“1,2”)
Maintainable
Trustworthy
Readable
ArtOfUnitTesting.com
Song?
This is a test line
Looks like you’re doing fine
Time for a song of mine
Hello DB My Old Friend
Hellow DB my old friend
I need to work with you again
That stored procedure ain’t working wellWhoever wrote that trigger should go to jail
And that index , it is slower than a snailWhat the hell? I guess it’s time…
FOR VIOLENCE
Man, whoever wrote this codeThat bastard’s gonna hit the road
Now the customer is gonna sueInstead of red, my face is turning blue
And it seems like there is no way out of this.
There’s just a hiss.
I guess it’s time, for violence..
I’m angry and I want a name
That DBA should be ashamed
What’s that you’re saying?It’s ME to blame?
That database was my own sick game?
Oh that’s right.It was me who did the design
It was mine.I guess it’s time…
FOR SILENCE.
Thank You
Coaching, mentoring and trainingFor team leaders, developers, architects and product owners