18

Okay, I develop web applications in PHP and JavaScript and a lot of times here on Stack Overflow I have seen the word unit test passing by, but nowhere on the website have I been able to found a satisfactory answer to what exactly a unit test is.

So what are unit tests and should I, as a PHP and JavaScript programmer, care, or are they only for 'real' programming languages?

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Pim Jager
  • 30,915
  • 16
  • 70
  • 97

8 Answers8

25

Unit tests are for any code you wish to maintain.

In a nutshell, the idea is to write many small tests, each of which can be run in isolation, and test the smallest possible part of your codebase (often individual classes or individual functions). If I give this function the input it expects, does it return the output I expect? If it does, that means the rest of the application can pretty much assume it works. And if it doesn't, I'd rather catch the error in a small, simple, isolated unit test function than trying to trace it through the entirety of my application.

Of course, it also requires you to be fairly disciplined in how you write your code, both because it has to be possible to isolate individual functions or classes to test them, and because, well, the tests don't write themselves. You have to do that. ;)

Given the quality of most of the PHP code I've seen, I'd say unit testing definitely has its place in the PHP community. More so than in almost any other language, in fact. ;)

jalf
  • 229,000
  • 47
  • 328
  • 537
  • 1
    Do you know of an Unit Testing frameworks that work with PHP? Frankly if you see PHP complex enough to make unit testing viable then you have to question whether PHP is the right language for the job. – AnthonyWJones Dec 06 '08 at 21:00
  • SimpleTest and PHPUnit are two. – JW. Dec 06 '08 at 21:22
  • Anothony: I don't think the complexity of the language matters. Unit tests are beneficial whenever you have code you wish to test (and don't you usually wish to test *all* your code?). Whether they're easy to write against your codebase is the real question, but depends more on design than language. – jalf Dec 06 '08 at 21:57
  • Perhaps you can clarify by saying: it also requires you to be fairly disciplined in how you write your code: it has to be taken apart into units to test. – reinierpost Jan 04 '10 at 09:21
  • @AnthonyWJones: I would personally question whether PHP is the right language for **any** job. But if you find yourself using it, then you need all the help you can get to ensure that your code is less broken than the language used to write it. So yes, all the more reason to unit test your code – jalf Nov 24 '11 at 09:29
  • I can imagine writing code that generates inputs. How do I write code to separately verify that the function/class/code-under-test (CUT) produces the correct output? One way to "verify" is to not write code at all and just to verify the input-output manually. If I were to write code to try to generate outputs with which to verify the outputs of the CUT, then how is that different from writing the CUT in the first place? Or is that the point -- to check that two different implementations of a function/class produce the same output? – Minh Tran Feb 07 '16 at 18:08
19

Unit tests are automated tests that test whether a given piece of code does what you expect it to do under a given set of circumstances. Good unit tests test small pieces of functionality, often at the level of individual functions.

Unit tests are usually structured such that you set up some state, run the function or method you want to test, and then assert either the output of that function, or a change in other state as a result of that function. Most unit testing frameworks have utilities for supporting and structuring this, such as:

  • Test cases: Ways to group similar tests together, often that test the same file or section of code.
  • Setup/teardown functions: functions that are called before each test that setup and cleanup state that is the same across multiple tests.
  • Assertion functions: functions that allow you to assert that specific things are true, such as a value is equal to another expected value, that a value is true/false, etc. When they fail, they show you what the expected and actual values were.
  • A test running application: An application that runs all of your tests for you one after another, showing you whether each succeeded or failed, and if it failed, what specific assertions failed, and what the actual value was as opposed to the expected value.

Unit tests are useful for a number of reasons:

  • They ensure your code works, as you're writing it, without having to test it manually. As you're writing a function, you can test your assumptions about how it works, catching bugs right away.
  • They keep working code working, even as you or someone else changes it. Once a function is written and fully unit tested (ie, all of the things it should do have associated unit tests that verify they actually do that), then if you or anyone else breaks any of that functionality, you'll know right away when you run the unit test, and can easily rectify it.
  • They help you debug. Rather than having to look through large volumes of code when trying to diagnose a bug observed from manually testing your application, unit tests allow you to focus on smaller pieces of functionality, reducing the amount of complexity you need to think about.
  • They document your code in a way that stays updated as the code changes. Design documents and comments are easy to forget to update. Unit tests, on the other hand, break when they're not updated. If clearly written, they show what code actually does in a specific situation, and can prove that to you.

Unit tests are useful on any code that's larger than a few lines, regardless of language. I've definitely unit tested php code, even for relatively small projects, and have gotten immediate rewards from it.

Scotty Allen
  • 11,695
  • 9
  • 34
  • 51
3

A unit test is a test of a small portion of the code that you write. You test it in isolation from the rest of the system in order to ensure that that portion of your code works.

It is easier to test a lot of small portions of code, ensure that they work, and then test them working together, rather than testing the system as a whole.

It is important to distinguish between unit testing and automated unit testing. You should always unit test your code. However, automating your unit tests is a whole other subject.

Matthew Farwell
  • 58,043
  • 17
  • 119
  • 166
3

In addition to what has already be answered, having tests cases covering your code allows you to proceed to Refactoring (improving your code design without modifying its observable behavior).

Unit test frameworks for PHP comprise PHPUnit and SimpleTest that have been compared on StackOverflow.

Community
  • 1
  • 1
philant
  • 31,604
  • 11
  • 64
  • 107
1

On why unit testing should be done in the first place, I would like to add the argument by Barry Boehm: "a fault discovered and corrected in the unit testing phase is more than a hundred times cheaper than if it is done after delivery to the customer."

While the multiplier does sound a bit rough, I think the argument definitely justifies testing.

miek
  • 3,426
  • 2
  • 27
  • 30
1

Most of the php I've seen is almost impossible to do unit testing on.

Wikipedia has an article on unit testing if you are interested.

epochwolf
  • 11,534
  • 13
  • 55
  • 69
  • Partly because people mix logic and presentation and don't use functions. Why people seem to hate functions in PHP is beyond me - DDRY (definitely do repeat yourself) seems to be the PHP mantra. – Rich Bradshaw Dec 06 '08 at 19:52
  • 1
    This is common in script style coding, its a throw away coding style often by people more interested in being a designer of a website than being a developer. It just as common in the ASP/VBScript community. Frankly if you need ot UT you should consider another language. – AnthonyWJones Dec 06 '08 at 21:04
1

If you write an application of any description, you should consider unit tests. Done properly, they force you to think about the quality of code you are delivering to your users. I think the issue you have here, is the difference between unit testing code and automated unit testing. Unit testing can be done as simply as writing down a set of tests and then manually running through them.

Automated unit testing, on the other hand, relies on you having some form of application/harness to run and rerun tests. With automated unit tests you can rerun tests just by pressing a button. So why is rerunning a test so important? Simply speaking, you don't write applications run tests on them once and then walk away from them. Write your tests so that you exercise your code in discrete little runs and run them throughout the development process. By doing this, with a well written set of tests, you stand a much better chance of identifying code that's been broken by upgrades.

Pete OHanlon
  • 8,871
  • 2
  • 25
  • 28
0

A google search for "php unit testing" yields a treasure trove of information on this subject. The PHPUnit project looks interesting.

converter42
  • 6,979
  • 2
  • 26
  • 23