CodeIgniter Forums

Full Version: Unit Testing
You're currently viewing a stripped down version of our content. View the full version with proper formatting.

El Forum

[eluser]richzilla[/eluser]
Ill hold my hands up and admit that ive never done unit testing, having always relied on just running my code and gradually focusing in on any areas that arent producing the desired result. Ive done a bt of reading up, and ive a few questions about how unit testing would be implemented in a framework like codeigniter?

Firstly, im assuming that if i had
Code:
class Foo
to test this i would have a separate class (in the same file?) called
Code:
class Test_Foo
this would provide the methods of
Code:
Foo
with predetermined values and check to see if they received the expected results?

Is this correct?

Also im assuming in this instance, that all test classes are to be considered infallible?

And finally, how do you run your tests over an entire project? Do you need to create some sort of directory traversal script that just runs every class starting
Code:
Test_
or is there a better integrated way to do this?

Any clarification on these points would be greatly appreciated.

El Forum

[eluser]Michael Wales[/eluser]
Each Unit Testing library handles things a bit differently, but yes you have the general "gist" of how it works. Let's say I had an accounts class and I was about to write the register() method. Before writing that method I can assert the following things (and write tests for each):

1. A unique username is required to register.
2. A unique email address is required to register.
3. A password is required to register.
5. A 5-character alphanumeric salt must be generated.

So, I'd write a test case (psuedo-code here), before ever writing my register() function:

Code:
function test_usernameValid() {
  // Build a User object that does not include a username
  // Assert that this will fail, because username is empty

  // Give that user a username
  // Assert that this will pass, because username is not-empty

  // Create a new user with the same username
  // Assert that this will fail, because username is not unique
}

Okay, so we run our tests and we see something like this:
Quote:_usernameValid(): 1 Pass, 2 Fail

What happened here was our first test we believed it would fail. But, since we haven't written any code to prevent against this test-case, it went ahead and created our user. So, we fail our test.

The second test correctly passed - just by coincidence. The third test also failed, because we believe our user will not be created when in fact, it was (because we haven't written any code to confirm uniqueness).

So, now we go and write our register() function and the first thing we do is validate against the username field - it's now required. We run our tests again:

Quote:_usernameValid(): 2 Pass, 1 Fail

Alright, our required username code is working correctly - it didn't make the user the first time, did the second, but then it did again the third (our one failure). Now, let's add some uniqueness checks to our register() method.

Quote:_usernameValid(): 3 Pass, 0 Fail

Hooray! Our code is rock-solid and we know it works (with regard to usernames). Now, write tests for all of the other situations, then write code and run tests until you pass all of them.

The good thing about tests is - what if one day your boss comes in and tells you to make some change to how users are registered. Depending on the codebase, it can be difficult to understand the ramifications of making such a change and how it will change other business process down the line. With unit tests, you can write your new code and really quick tell if your application is functioning exactly as you expect it (and how it has since the creation of the tests).

El Forum

[eluser]richzilla[/eluser]
Brilliant, thanks for the reply. Just one more thing, if i wanted to get an overall view of how my app was looking from a test point of view, how do you go about running all tests in an application 'remotely' so to speak, i.e. without explicitly running each test class for each file?

Are there any existing libraries that will automatically search for and run all classes starting 'test_' for example?

El Forum

[eluser]Michael Wales[/eluser]
Once again, it's all on a case-by-case basis. Usually you'll have all of your tests in one directory, so it would be trivial for a library to scan through, grab all test classes and execute them.

The most difficult part in working with tests is in maintaining your "closures" - the data the test cases will use with your application.

PHPUnit is by far the de-factor Unit Testing library for PHP. Googling will provide hundreds of tutorials and information on it all.