F.I.R.S.T



Source: Brett Schuchert, Tim Ottinger

In my Object Mentor days Brett and I were looking at ways to improve some class materials on the topic of unit testing. I noticed that our list of properties almost spelled FIRST. We fixed it.

We refer to these as the FIRST principles now. You will find these principles detailed in chapter 9 of Clean Code (page 132). Brett and I have a different remembrance of the meaning of the letter I and so I present for your pleasure the FIRST principles as I remember them (bub!). He had it right the first time so we will cut him some slack.

The concepts are very simple, and of course achieving them once you've gone off the track can be very hard. Always better to start with rigor here, and maintain it as you go.

Fast: Tests must be fast. If you hesitate to run the tests after a simple one-liner change, your tests are far too slow. Make the tests so fast you don't have to consider them.

A test that takes a second or more is not a fast test, but an impossibly slow test.

A test that takes a half-second or quarter-second is not a fast test. It is a painfully slow test.

If the test itself is fast, but the setup and tear down together might span an eighth of a second, a quarter second, or even more, then you don't have a fast test. You have a ludicrously slow test.

Fast means fast.

A software project will eventually have tens of thousands of unit tests, and team members need to run them all every minute or so without guilt. You do the math.

Isolated: Tests isolate failures. A developer should never have to reverse-engineer tests or the code being tested to know what went wrong. Each test class name and test method name with the text of the assertion should state exactly what is wrong and where. If a test does not isolate failures, it is best to replace that test with smaller, more-specific tests.

A good unit test has a laser-tight focus on a single effect or decision in the system under test. And that system under test tends to be a single part of a single method on a single class (hence "unit").

Tests must not have any order-of-run dependency. They should pass or fail the same way in suite or when run individually. Each suite should be re-runnable (every minute or so) even if tests are renamed or reordered randomly. Good tests interferes with no other tests in any way. They impose their initial state without aid from other tests. They clean up after themselves.

Repeatable: Tests must be able to be run repeatedly without intervention. They must not depend upon any assumed initial state, they must not leave any residue behind that would prevent them from being re-run. This is particularly important when one considers resources outside of the program's memory, like databases and files and shared memory segments.

Repeatable tests do not depend on external services or resources that might not always be available. They run whether or not the network is up, and whether or not they are in the development server's network environment. Unit tests do not test external systems.

Self-validating: Tests are pass-fail. No agency must examine the results to determine if they are valid and reasonable. Authors avoid over-specification so that peripheral changes do not affect the ability of assertions to determine whether tests pass or fail.

Timely: Tests are written at the right time, immediately before the code that makes the tests pass. While it seems reasonable to take a more existential stance, that it does not matter when they're written as long as they are written, but this is wrong. Writing the test first makes a difference.

Testing post-facto requires developers to have the fortitude to refactor working code until they have a battery of tests that fulfill these FIRST principles. Most will take the expensive shortcut of writing fewer, fatter tests. Such large tests are not fast, have poor fault isolation, require great effort to make them repeatable, tend to require external validation. Testing provides less value at higher costs. Eventually developers feel guilty about how much time they're spending "polishing" code that is "finished" and can be easily convinced to abandon the effort.

32 comments:

  1. To give credit where it is due... Tim completed it. We (Tim I and other OM'ers) had come up with 4 characteristics.

    We were missing one letter, T (I think). The letters were in a different order. Tim said "add a T". I said "what?". He repeated, "Add a t." I said "I understand the individual words you are saying, but not what you mean." He finally said "Add the letter T and it spells first." I got his "a-ha".

    ReplyDelete
  2. Thanks Brett. Note that my contributions to the body of knowledge are both many and miniscule. But sometimes they are cute. ;-)

    ReplyDelete
  3. Looks like you need FIRST class test to make your code SOLID!

    All principles in the "FIRST" makes a lot of sense.

    ReplyDelete
  4. How do you make sure that the tests that need the database connections run that fast?

    ReplyDelete
  5. If you end up having to use the database connection for a large number of tests (because ultimately, a large chunk of your app could be dependent on the database), they won't run that fast. You have a few things to consider:
    - separate your tests into a "fast" and a "slow" suite
    - introduce an in-memory database such as HSQL, though I've heard these create their own problems, and you are no longer "unit" testing at this point anyway
    - introduce test doubles. Also rework the design of your app--many classes that are dependent on the database should really only be dependent on pojos (that you instead inject).

    Remember that a goal of a unit test is to determine if a unit works in isolation: is its own logic proper, and does it interact with collaborators properly?

    ReplyDelete
  6. This comment has been removed by a blog administrator.

    ReplyDelete
  7. not too many things I know but I am actually very interested in that.

    ReplyDelete
  8. The first sentence that I always remember is when getting thanks is aid from someone.

    ReplyDelete
  9. today's technology makes life easier to be passed. all activities can be done with ease thanks to the latest technology

    ReplyDelete
  10. la technologie d'aujourd'hui rend la vie plus facile à passer. Toutes les activités peuvent être réalisées en toute simplicité grâce à la dernière technologie

    ReplyDelete

  11. My cousin recommended this blog and she was totally right keep up the fantastic work!


    Software Testing Course Chennai

    ReplyDelete
  12. There are many principles that guide Software Testing Principle. Before applying methods to design effective test cases, a software engineer must understand the basic principles that guide software testing. The following are the main principles for testing

    ReplyDelete
  13. While it seems reasonable to take a more existential stance, that it does not matter when they're written as long as they are written, but this is wrong. Writing the test first makes a difference.

    ReplyDelete
  14. I am fascinated by this post. Thank you very much.

    ReplyDelete
  15. Tim completed it. The letters were in a different order. Tim said "add a T". hanks Brett. Note that my contributions to the body of knowledge are both many and miniscule.

    ReplyDelete
  16. Toutes les activités peuvent être réalisées en toute simplicité grâce à la dernière technologie

    ReplyDelete
  17. all activities can be done with ease thanks to the latest technology

    ReplyDelete
  18. Writing the test first makes a difference.

    ReplyDelete
  19. I think this is a real great article post.Really looking forward to read more. Want more.

    ReplyDelete
  20. I am fascinated by this post. Thank you very much.
    Gadget Terbaru

    ReplyDelete
  21. I was very encouraged to find this site. I wanted to thank you for this special read. I definitely savored every little bit of it and I have bookmarked your site to check out new stuff you post.

    ReplyDelete
  22. la tecnología actual facilita la vida que se pasa. todas las actividades se pueden hacer con facilidad gracias a la última tecnología
    Evercoss A7S
    Harga Evercoss A7S
    Spesifikasi Evercoss A7S

    ReplyDelete
  23. Contain elements that your article is so good and easy on impregnated . all the activities that I do comes to your article so good that this .

    ReplyDelete
  24. I think this is a real great article post.Really looking forward to read more. Rumah Minimalis

    ReplyDelete
  25. very informative post. thanks...
    Harga Kamera DSLR

    ReplyDelete
  26. Acetech who have been one of the leading software development company in Delhi giving creative custom software development to meet interesting business challenges for the absolute most distinguished organizations and associations in the country.

    ReplyDelete
  27. nice share and informative. thank you..
    http://www.erahp.com/

    ReplyDelete
  28. it's so inspiring, amazing. thankyou for share :)

    ReplyDelete