This question might be slightly vague but here goes. I've just started unit testing and I seem to be struggling with the basic notion.
I'm testing a function that checks if a record exists in the database. If not, it adds the new record and returns its ID. So the function is simple to write. And the only way I can think to test it is by using the mocking framework to check that the right properties/methods were called the right number of times.
The part I'm struggling with is that everything I have ever read talks about writing tests first and then the function. But I feel like it'll only work if I write the function first, and then write tests that reflect the inner workings of the functions.
Is there really a golden rule for this?
And how much should I be testing basic transactional logic anyway?
Unit testing is a software development process in which the smallest testable parts of an application, called units, are individually and independently scrutinized for proper operation. This testing methodology is done during the development process by the software developers and sometimes QA staff.
One of the benefits of unit tests is that they isolate a function, class or method and only test that piece of code. Higher quality individual components create overall system resiliency. Thus, the result is reliable code. Unit tests also change the nature of the debugging process.
An example of a real-world scenario that could be covered by a unit test is a checking that your car door can be unlocked, where you test that the door is unlocked using your car key, but it is not unlocked using your house key, garage door remote, or your neighbour's (who happen to have the same car as you) key.
Maybe if you wanna develop at this level you can write the method's contract first and than the test depending on the contract. It is important that your method behaves like defined in the contract, because this is what other developers will expect. Especially the edge cases (exceptions and so on) should be tested.
If you are going to change your contract while developing the method, well, than that's not good. Because than you have not planed your software good and as well you can rewrite your tests =)
Testing is important because when you do code changes, you will later be able to detect the errors easier with the saved tests, when you mashed something up, by trying to develop something new.
The part I'm struggling with is that everywhere i have ever read talks about writing tests first and then the function. But i feel like it'll only work if i write the function first then write tests that reflect the inner workings of the functions.
It sounds like you are suffering from the common chicken/egg problem with test-driven development (TDD). You don't know what you want to test until you have code, and you believe you can't do TDD unless you write tests before you code.
This is really a case of Designer's Block (tm). Just like writer's block, it is often good to work it out by coding - even if you throw all that code away.
Hack up a prototype, and then pretend it doesn't exist. (do not ship it :) This prototype should explore the concepts you weren't familiar with, or didn't have enough information to start designing. It should get you familiar with the problem so that you can start designing.
After you have a proof of concept, code review the heck out of it. In your review, determine what you want the public interface to look like, what architectural patterns would best suit the program, and which dependencies should be isolated from each other (and mocked out in your tests). Take notes, or submit requirements in your project planning software/work items in your project tracking software.
If you have troubles identifying these things in your review, you should try to recruit other programmers (and possibly designers/people who identify your business requirements) to help you through it. A code mentor may be a good idea.
From that review, you should be able to start coding up your tests. Or you could begin writing a technical spec - this advice applies equally well to both.
(if you are working on a team, gathering requirements and getting user feedback/performing UATs is also required; but that might be someone else's job)
Edit
Keep in mind that this is just one approach for dealing with this problem. Another is to simply relax any puritan-like ideals on how TDD should work, and simply develop your tests in parallel with your code. Check them in at the same time.
It is also perfectly fine to do unit testing without TDD. Unit tests confer more benefits than just encoding your design and requirements. They also are a huge help when you add new features or fix bugs (regression testing), or when you port your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With