Page 1 of 1

Progressive Testing Rate Topic: ***** 1 Votes

#1 andrewsw  Icon User is offline

  • bin deployable
  • member icon

Reputation: 6261
  • View blog
  • Posts: 25,054
  • Joined: 12-December 12

Posted 03 August 2015 - 05:32 AM

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

However, 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. Besides, you will probably be using the else in the final code.

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.

This post has been edited by andrewsw: 04 August 2015 - 11:12 PM


Is This A Good Question/Topic? 4
  • +

Replies To: Progressive Testing

#2 chris98  Icon User is offline

  • D.I.C Lover

Reputation: 40
  • View blog
  • Posts: 1,094
  • Joined: 06-July 13

Posted 30 August 2015 - 09:20 AM

You set $dbtype to SQLite, but you don't use it. Did you mean to use this on line #13?
Was This Post Helpful? 0
  • +
  • -

#3 andrewsw  Icon User is offline

  • bin deployable
  • member icon

Reputation: 6261
  • View blog
  • Posts: 25,054
  • Joined: 12-December 12

Posted 30 August 2015 - 09:42 AM

Perhaps I started with SQLite but changed my mind. The $dbtype line could be removed. I left it in there as a way of checking whether my tutorial was actually being read ;)

This post has been edited by andrewsw: 30 August 2015 - 10:27 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1