I'm starting to use test driven development for JavaScript, but I would 开发者_开发百科like to start using it in my different projects.
I would like to know what are the typical mistakes and how to avoid them?
Also, I would like to know what I should read to make test driven development easier to learn and apply to my code.
Thanks in advance.
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
- Arrange
- Act
- Assert
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.
Make sure your tests only test one piece of functionality. The name and the asserts should be completely aligned with that as well. E.g. if you're adding an expand() function to a variable-handler, then the test should be called (roughly) test_expands_variables or should_expand_defined_variable or whatever fits your naming convention, and the asserts should only be on the returned value or side-effects of the function call. A common mistake is to assert set-up steps, but any functionality in the set up should have its own test with exactly that assert already in place. If you assert the same thing everywhere it's suddenly hard to see which test you should be fixing.
A good starting place to get a feel for the whole TDD loop is to try some code-kata's. Roman-numeral converter is a common first intro to writing tests first. In the beginning, be REALLY anal about running the tests after every little change. Once you get the hang of it you'll get a feel for how obsessive you need to/should be, but getting the rhythm going for a beginner usually requires being really pedantic.
I've started getting into TDD in Javascript with the book "Test-Driven JavaScript Development" by Christian Johansen. It's excellent and addresses pretty much all the aspects of TDD and applies it to JS: http://tddjs.com/
精彩评论