Top Banner
Writing Tests Effectively Codeweavers Development Series
48

Writing Tests Effectively

Jan 21, 2018

Download

Software

Paul Boocock
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Writing Tests Effectively

Writing Tests EffectivelyCodeweavers Development Series

Page 2: Writing Tests Effectively

IntroductionWhat do we actually mean by Unit Test?Why we write testsApproaches to writing testsWhat we can do going forward

2

Page 3: Writing Tests Effectively

Unit Test DefinitionIn computer programming, unit testing is a software testing method by which individual units of source code, sets of one or more computer program modules together with associated control data, usage procedures, and operating procedures, are tested to determine whether they are fit for use. Intuitively, one can view a unit as the smallest testable part of an application. In procedural programming, a unit could be an entire module, but it is more commonly an individual function or procedure. In object-oriented programming, a unit is often an entire interface, such as a class, but could be an individual method.

Unit Testing - Wikipedia

3

Page 4: Writing Tests Effectively

How big is a Unit TestIt depends…

4

Page 5: Writing Tests Effectively

How big is a Unit Test● OO Languages

○ Test at method level○ Test Fixture per class

■ 1 to Many for every method

5

Page 6: Writing Tests Effectively

How big is a Unit Test● Functional

○ One test module for every domain○ One to many tests for each function

6

Page 7: Writing Tests Effectively

Why Test?Or rather, why don’t people write tests?

● No Time to write tests○ Probably because you’re spending so long debugging

● Tests that add value haven’t been written○ How can we do this?

7

Page 8: Writing Tests Effectively

Why Test?● Be playful!

○ Experiment!

● Can play around in your test framework● Gain huge confidence in your codebase

8

Page 9: Writing Tests Effectively

Who are we testing for?2 Approaches● Write Unit Tests for yourself

○ How would you want to maintain it?

● Put the team first○ They can extend your code with confidence○ Provide your team with guidelines to work to

9

Page 10: Writing Tests Effectively

...Still not convinced?

10

Unit Tests are a waste of time!

Page 11: Writing Tests Effectively

Unit Tests are a waste of time● Are writing tests making you more productive?

○ If not then stop writing them!

● Kill wasteful tests○ You want plenty of unit tests that are really helpful!○ Keep test suites quick to keep them useful

■ 10 second test suites?!?11

Page 12: Writing Tests Effectively

Unit Tests are a waste of timeMaybe invest in writing better Unit Tests?

12

Page 13: Writing Tests Effectively

Unit Tests are easy!● Easy to write

○ Easy to write poorly

● What do we do wrong?○ Strongly couple our tests to our code○ Thinking about yourself○ Not getting ‘Bang for the bucks’

13

Page 14: Writing Tests Effectively

TDD vs Unit Tests

Not the same thing!

14

Page 15: Writing Tests Effectively

TDD vs Unit TestsA test you wrote to do TDD may not be valuable for you in the long term

Just because a test was useful to help you create a feature doesn’t mean it needs to

stay

15

Page 16: Writing Tests Effectively

TDD vs Unit Tests● Maybe the test doesn’t add value

○ What is the ROI on having this test?○ How many phone calls does it prevent?

● Maybe deleting it isn’t right but…○ How about making it more useful?

16

Page 17: Writing Tests Effectively

TDD vs Unit Tests● If this test was failing right now what clues

would you want it to give you to help you solve the issue faster○ Work together to find out what that is and then

change your test accordingly○ Test goes from helping you deliver to helping you

maintain value17

Page 18: Writing Tests Effectively

TDD● TDD is a technique to help you write code

and defining a nice way to use it○ Not necessarily a good way to ensure that feature is

well tested if it even needs lots of tests at all○ How much time will be spent maintaining the tests?

18

Page 19: Writing Tests Effectively

Approachability● Let’s imagine a 6 month old failing test

○ What clues does it give me?○ Does it explain the domain?○ How much test code do you have to wade through to

find out what it does?○ Is it DRY?

■ This doesn’t mean the least characters possible…

19

Page 20: Writing Tests Effectively

Let’s talk about DRY● Often see a broken test that is unrelated

○ Wouldn’t it be great if you could quickly see what was going on...

○ Then you wouldn’t be so annoyed!

Repeating yourself to help others understand what is going on is probably a

good idea 20

Page 21: Writing Tests Effectively

Let’s talk about DRY

Apply DRY on a test suite levelApply DRY on a single test

21

Page 22: Writing Tests Effectively

Let’s talk about DRY● In a group of tests you can repeat things

○ What happens when 2 out of 5 tests in a test fixture fail?

○ Duplication can lead to more maintainable tests○ Always ask what is the value of the test?

22

Page 23: Writing Tests Effectively

Data Builders● Avoid using ObjectMother pattern

○ Breaks down when needing different data○ Personas -> Bob & Jane both have different attributes

● Create data builders - Nat Pryce○ http://www.natpryce.com/articles/000714.html

23

Page 24: Writing Tests Effectively

Some things to avoid● Avoid

○ Looping○ Language Constructs○ Reflection

Stay in domain code as much as possible

24

Page 25: Writing Tests Effectively

MaintainabilityTests should be just as maintainable as the rest of the codebase

We don’t need to approach writing tests in quite the same way as production code

25

Page 26: Writing Tests Effectively

Different ThinkingApproach tests in a way where readability is more important than performance

Milliseconds don’t matter (probably)

However, test suites need to be fast!

26

Page 27: Writing Tests Effectively

Too many tests● Too many tests… not enough tests…

○ Both are suboptimal

● Not enough then too long spent debugging● Too many then too long to run and maintain

○ Both lead to WASTE

27

Page 28: Writing Tests Effectively

Code Coverage● Useful!

● Not looking for 100% code coverage○ End up doing random things like testing getters and

setters○ Don’t have to test third party libraries

28

Page 29: Writing Tests Effectively

What to test?The most complex parts of the system that add the most value

Lots of tests in Allium for exampleMaybe too many?

29

Page 30: Writing Tests Effectively

Test different things● What different types of tests?

○ Fast tests - mock things out○ Database tests - slow but useful?○ Etc.

Want test suite to be fast but depends on needs ● Maybe you need one database test per suite?

30

Page 31: Writing Tests Effectively

Test Categories● State Verification

○ Check the state of the system after it has been exercised and compare it to the expected state■ e.g. Assert.AreEqual(a, b)

● Set up -> Call a function -> Check result

31

Page 32: Writing Tests Effectively

Test Categories● Behaviour Verification

○ Capture the indirect outputs of the test as they occur and compare them to the expected behaviour

● Mock out -> Verify behaviour happens

32

Page 33: Writing Tests Effectively

Test Categories● Both are fine!

○ Consider and think which style suits you or the situation best

● Probably a combination of both

33

Page 34: Writing Tests Effectively

Unit Tests● Solitary Unit Test

○ Tests that don’t cross boundaries○ Test a single class at a time

● e.g. Library -> Book○ Library tests still pass if book changes

34

Page 35: Writing Tests Effectively

Unit Tests● Sociable Unit Test

○ Tests that cross boundaries○ Test multiple classes at a time

● e.g. Library -> Book○ Library tests fail if book changes.

35

Page 36: Writing Tests Effectively

Unit Tests● Cascading failures can occur with sociable

tests○ Solitary tests prevent this happening

36

Page 37: Writing Tests Effectively

COMBO TIME● Write lots of solitary unit tests

○ As many as you can

● One or two sociable unit tests○ Makes sure that things work together but don't need

to test edge cases with slow sociable tests

37

Page 38: Writing Tests Effectively

Stub vs Mock● Mock used in Behaviour based tests

○ For Verification

● Stub you don’t verify○ Return canned responses

38

Page 39: Writing Tests Effectively

Going away● Write lots of fast solitary tests

○ With a few sociable ones too

● Keep your tests approachable● Keep your tests maintainable

○ Don’t freak out by breaking some of the production code rules to achieve these

39

Page 40: Writing Tests Effectively

Going away● Make expected literals

○ Don’t call method for expected values○ Convert objects to literals or write custom assertions

(that are also tested) - Think Money object

● Get rid of loops○ Split into individual tests

40

Page 41: Writing Tests Effectively

Going away● Don’t use reflection

○ Being clever in tests isn’t a good idea○ Avoiding LINQ might be a good idea too

● Use Data Builders○ Don’t use Object Mother pattern

41

Page 42: Writing Tests Effectively

More controversial● 1 assertion per unit test rule

● Get rid of setup methods○ Failing tests don’t alert you to go look in the setup○ Write whole story in the tests

42

Page 43: Writing Tests Effectively

Higher Level TestsAlso useful

Such as Integration tests

Unit Tests are just the beginning...

43

Page 44: Writing Tests Effectively

Higher Level Tests

44

Page 45: Writing Tests Effectively

How long should you spend?● 50/50?

● Write Tests -> Write Simplest Thing -> Refactor Test○ Spending longer on tests then?○ Don’t test everything though so probably not more

time45

Page 46: Writing Tests Effectively

How long should you spend?● Anything between 30 and 50% time - unless

your TDDing and then deleting so maybe longer as TDD is part of design phase

● Basically, however long you need to!

46

Page 47: Writing Tests Effectively

Wrap up● Don’t give up on tests

● Look for ways to improve ROI in writing tests○ Keep reading - Blogs, Books, Podcasts

47

Page 48: Writing Tests Effectively

ReadingWorking Effectively with Unit Testshttps://www.goodreads.com/book/show/22605938-working-effectively-with-unit-tests

Growing Object-Oriented Softwarehttps://www.goodreads.com/book/show/4268826-growing-object-oriented-software-guided-by-tests

Nat Pryce - Data Buildershttp://www.natpryce.com/articles/000714.html

48