Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Writing Tests Effectively

341 vues

Publié le

Part of the internal Codeweavers Development series from our Academy.
Writing Tests are a fundamental part of our development workflow but it's not easy to write them well. This talk dives into this and throws a few spanners in the works from what people traditionally think.

Publié dans : Logiciels
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Writing Tests Effectively

  1. 1. Writing Tests Effectively Codeweavers Development Series
  2. 2. Introduction What do we actually mean by Unit Test? Why we write tests Approaches to writing tests What we can do going forward 2
  3. 3. Unit Test Definition In 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
  4. 4. How big is a Unit Test It depends… 4
  5. 5. How big is a Unit Test ● OO Languages ○ Test at method level ○ Test Fixture per class ■ 1 to Many for every method 5
  6. 6. How big is a Unit Test ● Functional ○ One test module for every domain ○ One to many tests for each function 6
  7. 7. 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
  8. 8. Why Test? ● Be playful! ○ Experiment! ● Can play around in your test framework ● Gain huge confidence in your codebase 8
  9. 9. 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
  10. 10. ... Still not convinced? 10 Unit Tests are a waste of time!
  11. 11. 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
  12. 12. Unit Tests are a waste of time Maybe invest in writing better Unit Tests? 12
  13. 13. 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
  14. 14. TDD vs Unit Tests Not the same thing! 14
  15. 15. TDD vs Unit Tests A 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
  16. 16. 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
  17. 17. 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 value 17
  18. 18. 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
  19. 19. 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
  20. 20. 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
  21. 21. Let’s talk about DRY Apply DRY on a test suite level Apply DRY on a single test 21
  22. 22. 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
  23. 23. 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
  24. 24. Some things to avoid ● Avoid ○ Looping ○ Language Constructs ○ Reflection Stay in domain code as much as possible 24
  25. 25. Maintainability Tests 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
  26. 26. Different Thinking Approach tests in a way where readability is more important than performance Milliseconds don’t matter (probably) However, test suites need to be fast! 26
  27. 27. 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
  28. 28. 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
  29. 29. What to test? The most complex parts of the system that add the most value Lots of tests in Allium for example Maybe too many? 29
  30. 30. 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
  31. 31. 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
  32. 32. 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
  33. 33. Test Categories ● Both are fine! ○ Consider and think which style suits you or the situation best ● Probably a combination of both 33
  34. 34. 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
  35. 35. 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
  36. 36. Unit Tests ● Cascading failures can occur with sociable tests ○ Solitary tests prevent this happening 36
  37. 37. 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
  38. 38. Stub vs Mock ● Mock used in Behaviour based tests ○ For Verification ● Stub you don’t verify ○ Return canned responses 38
  39. 39. 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
  40. 40. 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
  41. 41. 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
  42. 42. 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
  43. 43. Higher Level Tests Also useful Such as Integration tests Unit Tests are just the beginning... 43
  44. 44. Higher Level Tests 44
  45. 45. 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 time 45
  46. 46. 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
  47. 47. Wrap up ● Don’t give up on tests ● Look for ways to improve ROI in writing tests ○ Keep reading - Blogs, Books, Podcasts 47
  48. 48. Reading Working Effectively with Unit Tests https://www.goodreads.com/book/show/22605938-working-effectively-with-unit-tests Growing Object-Oriented Software https://www.goodreads.com/book/show/4268826-growing-object-oriented-software-guided-by-tests Nat Pryce - Data Builders http://www.natpryce.com/articles/000714.html 48