| 
  • If you are citizen of an European Union member nation, you may not use this service unless you are at least 16 years old.

  • Stop wasting time looking for files and revisions. Connect your Gmail, DriveDropbox, and Slack accounts and in less than 2 minutes, Dokkio will automatically organize all your file attachments. Learn more and claim your free account.

View
 

Writing Good Unit Tests

Page history last edited by Michael Scott 11 years, 5 months ago

ALT.NET Open Spaces

Sunday, March 1, 2009

Session:  Writing Good Unit Tests

Format:  Discussion

Host:  Michael Scott <mscott@eskimo.com>


 


PRE-SESSION RESEARCH

 

General Tips for Writing Good/Maintainable Unit Tests

- Don't write too many unit tests

 

- DRT Principle

  (Don't Repeat Tests)

 

- Only have 1 test for each unit of functionality

 

- Unit Test ALL of your functionality

 

- Only have 1 assertion per test (maybe two)

 

- Write your tests first (before writing code) - TDD

   - forces you to design your application better

   - forces you to write testable code

   - writing unit tests becomes a habit

 

- Use Assert.That  (constraint model)

  (easier to read)

 

- Avoid writing comments in your tests

   (these must be maintained whenever your test changes)

 

- Avoid specifying message text in your Asserts

   (extra work for little additional value)

 

- Design your code to be testable

 

- Use Stubs / Mocks

   - each test should only test the logic for that specific unit of functionality

   - Integration Tests are not Unit Tests

 

- Don't write tests for each method, write tests for each application behavior

    - allows you to refactor your code without breaking your tests

      (since application functionality has not changed)

 

 

Further Information

  Book: Working Effectively with Legacy Code

    -  by Michael Feathers


 

 


SESSION DISCUSSION

 

Unit Test definitions

  - 1 single test that tests one single piece of functionality

 

  - A unit test is a method that tests a single unit of code with no dependencies (within reason).

 

 

General Principles of Unit Testing

- Make sure that your Unit Tests are not so brittle you have to rewrite them every time your code changes or is refactored.

 

- Unit Test results should be deterministic (i.e. Regardless of how many times a Test is run, it should pass if the functionality it is testing is working correctly).

    - usually don't want to use random numbers in tests

 

- Each Unit Test should only test one thing.

 

- Each Unit Test should only have one Assert.

 

- Don’t test core framework functions such as random, string, etc.  Must assume that the underlying framework code has been tested (unless this is causing tests to fail).

 

- Don't need to Unit Test everything (isn't actually possible to test everything).

 

- Write enough Unit Tests so you are confident with the stability of your code.

 

- Instead of testing entire range of values, test upper, lower bounds and a few values in between.

 

1. Test interaction and how state changes

2. Test the result

 

Testers are developers who write software that tests development.

One way to learn good Unit Testing quickly: Hire someone who can pair program with you.

 

 

Mocks/Stubs/Fakes

   Stub or Fake – an implementation that does nothing – it exists to support a dependency

   Stub or Fake – won’t be used, but needs to be there

   (some disagreement about definitions for Stubs and Fakes)

 

 

TDD = Test Driven Development

BDD = Behavior Driven Development

 

 

[FixtureSetup]

  - Can make code in the individual Unit Tests more readable.

  - But, some people don't like the idea of a FixtureSetup - everything should be in your tests.

 

 

General patterns for Unit Tests

   - Arrange, act, assert (AAA)

         Arrange - set up test

         Act -  do something in the test

         Assert - verify that conditions are what you expect them to be

 

   - Because X, when I execute, should get Y

 

   - State, action, expectation

 

 

Commenting

   - Unit tests should not need comments.

 

   - Use good names for your Unit Tests instead.  Good naming conventions for Unit Tests will adequately communicate what the tests are doing.

 

   (For that matter don't comment any of your code.  Commenting is often a sign that your code is not well written.  Other developers should be able to read and understand the code alone, if it is written well.)

 

 

Sample Unit Test Names

   ShuffleSeedSeedNumberOneVerifyThat

 

   WhenAUserLogsInExpectThat...

 

 

One naming convention for tests

   State_Action_Expectation

 

 

Example Unit Test

   TwoPeople_P1InteractsWithP2_P1IsAnnoyed

   {

    IPerson P1 = JA;

    IPersone P2 = JT;

    P1.Interact(P2);

    Assert.That(P1.IsAnnoyed)

   }


 

 


QUESTIONS FOR FURTHER DISCUSSION

 

 - How isolated should a unit test be?

 

 - Should you use test doubles or the real code?

 

 - What is a mock framework?

 

 - What is a fake vs. what is a stub?

 

 - Any object?

 

 - What are some resources to learn how to write the correct tests? 

Comments (0)

You don't have permission to comment on this page.