3 ms·
So basically: don't test the implementation and don't test the framework. Do test the API. Test the output. Good, smart tests should be a pleasure to work wit
by agentultra 15y ago
So basically: don't test the implementation and don't test the framework.
Do test the API. Test the output.
Good, smart tests should be a pleasure to work with. They should give you the confidence to change the implementation without mercy. They make the feedback cycle faster, bugs more visible, and documentation more thorough.
The only time I've found unit tests to be a pain are when testing asynchronous, event-driven code. The tests aren't any more brittle, but they really need to be supported by good integration tests in order to find the kinds of bugs that can surface in such systems.
I think the point about unit tests is that they should be the default and not the exception. 100% coverage is an asymptotic value. But if you write the test first you can get pretty darn close.
- dspillett 15y ago> So basically: don't test the implementation. I thought that was the point of unit tests... > Do test the API. Test the output. ... and that this would be integration testing. Am I drawing my mental lines separating the range of tests in the wrong places?
- agentultra 15y agoI can't really say, but if you read The Clean Coder we might get on the same page. fwiw, what I mean when I say "don't test the implementation," is that your test should not test "how" a function or object performs its task when called. tldr; unit tests should test units -- the smallest amount of functionality possible A trivial example might be an object that retrieves some data from a persistent store and prints it out. It might have a "fetch" method whose argument is a key in the data store. You could easily write a test case that checks when "fetch" is called that the data is written to the standard output stream. It would pass and you could go home after a hard day of work. But if the requirements change and you need it to write to a socket instead and format the data for a binary stream -- you'll have to modify the "fetch" method and the tests. If we were clever though we'd realize that when we wrote the test to see that "fetch" output its result to standard out we were actually asking the object to do too much and our test was testing several different units of work that could be broken down. Ideally our hypothetical object would take a couple of callable objects that handle things like printing data to streams and formatting it. Then our test for fetch only has to test one small "unit" of functionality -- not several units (retrieving data, formatting it, printing it to a stream). hth