Subscribe to andrewsw's Blog        RSS Feed
***** 2 Votes

Progressive Testing

Icon 5 Comments
We very often have peope post a wall of code with no idea why it isn't working. There are important concerns here about knowing how to test and debug code, and decipher error messages. However, it is even more important for people to understand that they should be running and testing their code at the earliest opportunity, and frequently. If you've typed 50 lines of code before ever running it then, WHEN it doesn't work, it is very difficult to discover where the problem (or problems!) are. You'll often end up re-writing, or deleting, the whole thing before discovering an issue, if you ever discover one at all!

Hints: If you are writing a new method or function then just add the single statement print "here"; and run a piece of code that calls the method. Once it has printed "here" you can then start to code the logic of the method. If a function returns an integer then add the single statement return 5;.

I will illustrate using some PHP (and PDO) code, because:

  • It was a question in the PHP forum that triggered this blog
  • Debugging tools aren't easy to set up with PHP, so testing frequently, and printing output, are the main tools at your disposal

I am not an expert with PDO. The language (and library) isn't important, it is the principles, the approach, that you should concentrate on.

Suppose you have a page with an HTML form that submits to a .php page. The PHP page will check the submitted data and, if valid, insert it into a database. If you've already created the PHP page in full, but never tested it (and it fails), then just modify the action of the form to point to processform_test.php rather than processform.php. Here is the first code to put in this test page:
<?php
echo "Working..";
?>


This is the simplest piece of code that proves that the page is found, and PHP is working. Use it frequently. Fill in your form, click Submit, and see this text appear in the browser.

During development we should persuade PHP to display as much error information as possible:
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
echo "Working..";
?>


Remove these two lines from production code. They should, by that stage, be replaced by formal error handling and error logging routines.

Assuming that your form's method is POST then you can prove that the posted data is received by printing it out in the browser. Using print_r or var_dump makes it much easier to read this output.
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
echo "Working..";
print_r($_POST);
//print_r($_SERVER);
?>


If your code will be using $_SERVER values, such as DOCUMENT_ROOT, then you could print this array as well.

Now that you've shown that the posted data is received, you can test an individual value:
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
echo "Working..";
print_r($_POST);
//print_r($_SERVER);
if (isset($_POST['author']) && !empty($_POST['author'])) {
    echo "author is set";
}
?>


Testing just a single value is sufficent for the moment.

You'll find it more reassuring to always include an else statement, echo "no author";, rather than relying on a missing output as I have done.

Use echo "author is set"; first then change it to echo $_POST['author'];.

Now we want to confirm that we can connect to our database.
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
// configuration
$dbtype     = "sqlite";
$dbhost     = "localhost";
$dbname     = "test";
$dbuser     = "root";
$dbpass     = "admin";

// database connection
try {
    $conn = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
    echo 'Connected..';
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
    die();
}
print_r($_POST);
//print_r($_SERVER);
if (isset($_POST['author']) && !empty($_POST['author'])) {
    echo $_POST['author'];
}
?>


As you go through this process you can remove previous print statements, once they've served their purpose. However, I would keep printing $_POST throughout: you'll need to check its values frequently.

Now that you've shown that the connection works, it is tempting to jump in and start checking and inserting the posted data. I recommend one more step which is to insert some dummy data. We are checking that an INSERT will work, before adding the complication of parsing and validating the posted data.
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
// configuration
$dbtype     = "sqlite";
$dbhost     = "localhost";
$dbname     = "test";
$dbuser     = "root";
$dbpass     = "admin";

// database connection
try {
    $conn = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
    echo 'Connected..';
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
    die();
}
print_r($_POST);
//print_r($_SERVER);
if (isset($_POST['author']) && !empty($_POST['author'])) {
    echo $_POST['author'];
}
// test data
$title = 'test title';
$author = 'test author';

// query
$sql = "INSERT INTO books (author, title) VALUES (:author, :title)";
$q = $conn->prepare($sql);
$q->execute(array(':author'=>$author, ':title'=>$title));
?>


Check that the dummy data is inserted into the database.

However, as we progress, we should also anticipate that we will need to check that every database interaction succeeds. execute() returns a boolean so we can modify the code to:
$success = $q->execute(array(':author'=>$author, ':title'=>$title));
if ($success) {
    echo "insert succeeded";
} else {
    echo "insert failed";
}


Proceed in this manner and you will be in control of your code. When a problem occurs you will have isolated it to a particular part of your code.

5 Comments On This Entry

Page 1 of 1

CTphpnwb 

01 August 2015 - 09:09 AM
Great post! I think this should go in the PHP Tutorials section so more PHP beginners might see it, but I agree that the same principle applies to other languages: write a little test until it works, then repeat.
2

andrewsw 

01 August 2015 - 09:45 AM
Thank you.

It did occur to me that it could go in the PHP tutorials section (as well), but are you happy with the PHP and PDO code as it is?
1

Anarion 

01 August 2015 - 09:58 AM
Unfortunately it's not possible to +1 a blog post! Very well stated! Progressive testing helped me a lot when working with Laravel for the first time.
0

CTphpnwb 

03 August 2015 - 03:40 AM

andrewsw, on 01 August 2015 - 12:45 PM, said:

...are you happy with the PHP and PDO code as it is?

Absolutely. Even the "finished" version is still not too complex or long, so it helps to emphasize how important it is to test early and often. As we see in the forum, many beginners would have written much more code before trying it for the first time!
1

andrewsw 

03 August 2015 - 05:38 AM
Thank you. I've posted it exactly "as is". You are right, any longer and the message would be lost ;)
0
Page 1 of 1

Trackbacks for this entry [ Trackback URL ]

There are no Trackbacks for this entry

November 2019

S M T W T F S
     12
3456789
10111213141516
1718 19 20212223
24252627282930

Tags

    Recent Entries

    Recent Comments

    Search My Blog

    1 user(s) viewing

    1 Guests
    0 member(s)
    0 anonymous member(s)

    Categories