I'm wondering, how do you guys
unit-test in CakePHP? How do you
incorporate tests in projects?
I generally use the simpletest setup used by the Cake Core. I set up a test file for each controller and model. I generally test the output of helpers / components / behaviors if the code has complex options or the helper has a largely variable output. I find my coverage to be about 65-75% and that with even such a low degree of code coverage with my tests ( 65% of a limited subset of files is pretty weak ) I spot or fix more bugs via tests than I found and fixed correctly without.
What
parts of a project do you test? How do
you decide which parts gets to be
unit-tested?
I always test all Model functions. Custom find's, paginated result sets etc. I test them for the following. Correct number of results ( from a find on fixture data ), correct resultsets ( from a find on fixture data ), correctness of the fields returned, number of results returned and a correct dataset for each custom find type. Correct pagination if I am using paginated sets on any finds, custom or otherwise.
I always test controller functions that don't result in a view being rendered. As a habit I tend to move all logic that isn't dedicated to settings view vars or choosing a view to render to private / protected functions in the controller or to model function calls.
This lets me test the leftover controller actions ( ones with view output ) directly. If I render a view at all then those functions are likely behaving fine with any issues with what is rendered being further up the call stack.
I test helpers for their output with particular options set. I don't always cover all permutations of the options array but when two different keys result in mutually exclusive behavior or I can check for predicatble attributes being included in my markup as a result - I test for those scenarios.
If a component takes data from somewhere and manipulates it I check the format or return data on the components functions also. Same for behaviors.
If I have a static class used somewhere I will test the functions in that class for correct return results as well as generating some forced failures or intentional error conditions. Particularly if an error results in a redirect, or data being sent down the pipe in some form. If a failure is silent or returns a default value I also check to make sure that is actually happening.
Do you guys still get to
finish the job before the deadline?
The first pass deadline around here is always slightly "soft" to account for testing and any issues that crop up. I find that if you use a plain old pencil and some graph paper or a whiteboard that you can easily figure out a basic set of tests before you even write any code. With this approach you might find a project takes 25% more time up front but that over the entire lifecycle of the app you will easily save the 25% you spent up front by not having as many issues further down the pipeline.
I'd really appreciate your answers.
Thanks in advance!
Your welcome, in advance.
I edited this to add in some links to look at for both actual testing techniques and as a way to get a visual sense of how they come together.
- http://bakery.cakephp.org/articles/view/testing-models-with-cakephp-1-2-test-suite
- http://book.cakephp.org/view/160/Testing
- http://debuggable.com/posts/unit-testing-in-cakephp-part-1---introduction-to-unit-testing:48102610-c5d0-4398-a010-76974834cda3
- http://mark-story.com/nodes/view/testing-cakephp-controllers-the-hard-way
Also, I have to agree and disagree with the cake devs on writing tests. It is a very good idea to test anything you want to reuse - be it a single component file or a complex plugin - since you will be distributing it and the tests both show working code and are great examples of what can be done with a piece of code.
As for not testing controllers because you have to use mock objects - that is just a weak excuse not to do a little bit of tricky work that once you bother with it becomes quite a bit easier each time you do it and it really, really does cut down the error rate and gives you a huge increase in your own understanding of your own code.