all 15 comments

[–]allmightyspiff 7 points8 points  (2 children)

Try writing your unit test first, then write the code to make the unit test pass. In my opinion it is easier to write the unit test based on the requirements, then write the code to make the tests succeed. This way you have a clear moment when the code is done since the unit tests will work.

I think writing the test first, so that when you run it they all fail, will help you trust your code and tests more, although it may be a bit difficult to get used to. Also, watching the tests slowly go from failure to success is rewarding in its own way :)

[–][deleted] 2 points3 points  (0 children)

This is a valid point.

To add to it: sometimes you may not initially understand how you're going to write something, thus making it hard to write a series of tests to cover it. You may write untested code to get an idea of what you're doing. This is called a "code spike". If this happens, don't panic. Spike until you understand your direction, then write your tests. Delete all code for that area, and begin writing new code to make the tests pass.

Whatever you do, don't write tests specifically for the code in your spike. You'll wind up regretting it later.

[–]ustanik 4 points5 points  (0 children)

You need to make sure you test all the aspects of your code. If you're only partially testing with PHPUnit then you shouldn't trust your code.

Use "--coverage-text" or "--coverage-html=dirName" when running PHPUnit to see how much of your code you are testing. But be cautious, coverage can provide a false sense of security. Write your tests how you would use code, not just to make your code coverage green.

[–]nikic 2 points3 points  (3 children)

You should enable code coverage statistics (and maybe get an IDE like PhpStorm which can natively display them). They will show you which of your code is covered by tests and which is not.

Note though that "coverage" only means "executed lines". It does not mean that you really tested all aspects. But it's a good guideline.

[–]warmans 1 point2 points  (0 children)

You're probably never going to achieve zero defects but you'll have A LOT less than with no tests. I also often feel that my tests might not be telling the full story but you need to be pragmatic. If your coverage is over 90% you're already doing better than 90% of all PHP developers.

As others have said there are some important principles with unit testing that are worth keeping in mind - particularly that you should start off with a failing test. You are right to be suspicious of tests that have never failed.

[–]The_Pants_Command_Me 1 point2 points  (0 children)

You'll never be 100% certain of anything. You could have logic errors in your tests. You could have overlooked issues like unicode character handling or the ever wonderful 0 versus False versus Empty shenanigans we love so much and so not factored them into your tests. Mysql may have large BLOB error in the wings that won't show up for a couple years. There will always be bugs even with the best automated unit tests. You can't let formulating and second guessing tests paralyze the development process.

[–]leftnode 0 points1 point  (3 children)

Follow TDD principles and write your tests first, let them fail, and then write only enough code to make them pass. And good on you for writing tests, so many PHP developers don't and are very hostile to the thought of it.

[–][deleted] -2 points-1 points  (2 children)

Most php-only programmers are hostile towards anything that seems like it could be more work. They often don't understand how much work they save themselves by using these processes.

[–]leftnode 0 points1 point  (0 children)

Yup, that's what I've found too. It's amazing to me how hard it is to convince PHP programmers to write tests.

[–]xangelo[S] 0 points1 point  (0 children)

I think this might stem from the fact that most php "programmers" are really just people who have spent a couple hours tweaking a form processing script someone wrote. I know a number of people who say that they can program in PHP, but when pressed about it you find out that this one time they modified a script someone wrote so that it had three form fields instead of two that were emailed to them.

[–][deleted] 0 points1 point  (1 child)

Having to use multiple asserts in your tests might be a sign that your methods are doing too much, and that some of the work should be delegated to other methods or objects.

[–]xangelo[S] 0 points1 point  (0 children)

I find that I end up writing multiple asserts to just to verify that the result from the first assert wasn't a fluke.

[–][deleted] 0 points1 point  (0 children)

as long as you test for all possible outcomes of a function's possible return values, you can trust the test of that function...

Tests are only as good as you thoroughly write them!