The single biggest issue I ve faced using TDD is developers not being confident about unit testing. Poor unit testing wastes more time than it saves. Confused, untrustworthy, unmaintainable, unreadable tests fall by the wayside very quickly and jaded developers take time to want to unit test automatically again.
Per Fagrell makes some good points, especially about running the tests after every change; it should become second nature to run the tests before and after any test change.
Frameworks:
Consider QUnit as your framework for JS testing: http://docs.jquery.com/Qunit
I ve got a test harness page with the dependent mark up and the tests run at page load very well.
You can follow the
flow for unit tests using QUnit.
However, you will have to manually have to implement test setup and teardown methods and call them in your test methods. These will help with the isolation of test cases by keeping the conditions indentical for all tests and prevent tests being dependent on the ordering of their running.
Look for useful frameworks in the other languages you will be using. NUnit is very popular for .NET.
Isolation:
Per Fagrell also makes a good point about isolation. The distinction between unit testing (testing one aspect of atom of functionality) and integration (testing how multiple atoms work together) should be thoroughly understood before beginning testing. If you have more than one assert in a test method, you are not unit testing and need to change your test method.
Conventions:
A good naming convention from the excellent The Art Of Unit Testing for your tests is MethodUnderTest_Condition_ExpectedBehaviour e.g.
Expand_TextVariable_ExpandsText
From the same book keep your tests:
- Trustworthy
- Maintainable
- Readable
Otherwise you and other developers will not bother running the tests.
Fakes:
A common misunderstanding is the difference between the two types of fakes: stubs and mocks.
A seam is created in code by abstracting functionality that code depends on into an interface. E.g. A controller doesn t depend on a concrete repository, it will depend on an IRepository.
A stub then implements this IRepository and returns faked values; it is used to isolate the controller code to run in isolation. e.g. GetCustomer()
will create a new customer and return that, with no calls to the real repository or any store. Stubs are never tested against.
A mock is like a stub except that it can hold values which can be tested against. e.g. AddCustomer(Customer customerToBeAdded)
, your mock will accept that value and can be asserted against. Mocks can be tested against.
Have a look at a Test Isolation Framework (or Mocking Framework), that can automatically create fakes for a given Interface.
A misunderstanding of the purpose of mocks has lead to more than one developer that I have seen create a mock to test functionality and then write tests against the mocks themselves.
Resources:
I ve mentioned The Art Of Unit Testing and I recommend it thoroughly. It is one of the books, along with Code Complete, that I would grab if the office caught fire.
Hope that helps.