Location: PHPKode > projects > phpautotest > perform_test.php
<?php
/* Loop through the pages for a particular case, retrieve/execute the pages and store them in a database so that tests can be conducted soon after. The pages are deleted after testing is completed. */
session_start();

require 'includes/phpautotest_config.php';
require 'includes/phpautotest_functions.php';
require 'includes/HttpClient.class.php';

require 'includes/header.php';
require 'includes/top_menu.php';

restrict_access();

if(isset($_GET['case_id']))
{
	$case_id = $_GET['case_id'];
}
else
{
	phpautotest_show_error('$_GET[\'case_id\'] is not set.');
}

// Create a unique id for this test
$test_id = md5(time());
		
// Use case_id to select all pages for this test
$QUERY = <<<END

	SELECT
		*
	FROM
		`$phpautotest_table_page`
	WHERE
		`case_id` = $case_id
	ORDER  BY id ASC
END;

$result = phpautotest_send_query($QUERY);

// Loop through all the pages one by one and store outputs in database
$num_rows = mysql_num_rows($result);

for($i = 0; $i < $num_rows; $i++)
{
	$page = mysql_fetch_assoc($result);
	
	$page_id = $page['id'];
	
	## Create `page` record to store data

	$QUERY = <<<END

	INSERT INTO
		`$phpautotest_table_test_results`
		(`id`, `test_id`, `page_id`)
	VALUES
		('?', '$test_id', $page_id)
END;
	phpautotest_send_query($QUERY);
	
	// We will use this id to update the record with html output, etc
	$test_page_id = mysql_insert_id();
	
	// We dont want to corrupt the current $_POST, also since we're in a loop we have to clear the array repeatedly
	$post_vars = array();
	$post_vars = unserialize($page['serialized_post_vars']);
	
	$post_vars['test_id'] = $test_id;
	$post_vars['test_page_id'] = $test_page_id;
	$post_vars['page_id'] = $page_id;
	
	$rco = HttpClient::quickPost($phpautotest_install_path.'record_for_test.php', $post_vars);	
	
	// Recording failed due to exit/die in target page, buffered HTML is output directly into $rco
	if($rco != $success_text)
	{
		$rco = mysql_escape_string($rco);
		
		// No HTML entities should be stored in the database	
		$rco = htmlentities($rco);
		
		// Store HTML output in the database
		$QUERY = <<<END

			UPDATE
				`$phpautotest_table_test_results`
			SET
				`html_output` = '$rco'
			WHERE
				`id` = $test_page_id
END;

		phpautotest_send_query($QUERY);
	}
}

## Carry out regression test for variable values

// Extract both expected and actual serialized variable dumps in a single query so as to avoid querying mysql repeatedly within the loop
$QUERY = <<<END

	SELECT
		$phpautotest_table_test_results.serialized_variable_dump AS actual_serialized_variable_dump,
		$phpautotest_table_page.serialized_variable_dump AS expected_serialized_variable_dump,
		$phpautotest_table_page.php_test_code,
		$phpautotest_table_page.page_location,
		$phpautotest_table_page.html_test,
		$phpautotest_table_page.method,		
		$phpautotest_table_test_results.html_output,
		$phpautotest_table_test_results.time_taken
	FROM
		$phpautotest_table_test_results	
	LEFT JOIN
		$phpautotest_table_page
	ON
		$phpautotest_table_test_results.page_id = $phpautotest_table_page.id
	WHERE
		$phpautotest_table_test_results.test_id = '$test_id'
	ORDER  BY $phpautotest_table_test_results.id ASC		
END;

$result = phpautotest_send_query($QUERY);

$num_rows = mysql_num_rows($result);

for($i = 0; $i < $num_rows; $i++)
{
	$result_array = mysql_fetch_assoc($result);
	
	// Used in the "execution/retrieval time" part of the report
	if($result_array['method'] == 'R')
	{
		$method = 'Retrieval';
	}
	else
	{
		$method = 'Execution';
	}
	
	$report .= "<p><b>Page URL:</b><i> $result_array[page_location]</i>&nbsp;&nbsp;<b>$method time:</b> <i>$result_array[time_taken]</i> seconds";	
	
	// Perform the html output test
	$html_test = $result_array['html_test'];
	$html_output = $result_array['html_output'];

	// Remove all ASCII control characters (from 0 to 31 inclusive) as they cause problems, i.e some are added to html_test when it is updated using a form.
	$html_output = preg_replace("/[\\x00-\\x1F]/", '', $html_output);
	$html_test = preg_replace("/[\\x00-\\x1F]/", '', $html_test);
	
	// Since we're checking if string is empty, ignore whitespaces	
	$html_test = ltrim($html_test);
	
	// If a regular expression exists i.e if user has set some text
	if(!empty($html_test))
	{
		// This solves a problem that could arise due to the fact that PHP treats a normal whitespace and one replaced by &nbsp; in unhtmlentities as different, they have different ASCII values. &nbsp; (converted using translation table) => 160 but normal whitespace => 32.
		$html_output = preg_replace("/\s/", ' ', $html_output);
		
		preg_match_all("[$html_test]", $html_output, $matches);

		if(strlen($matches[0][0]) > 0)
		{
			$report .= '<br>HTML output test passed successfully';
		}
		else
		{
			$report .= '<br>HTML output test failed';
		}
	}
	else
	{
		$report .= '<br>HTML test was not conducted';
	}
	
	// Unserialize the variable dumps
	$expected = unserialize($result_array['expected_serialized_variable_dump']);
	$actual = unserialize($result_array['actual_serialized_variable_dump']);
	
	// If one of the variable dumps is not an array the test failed for this page, go on to next
	if(!is_array($expected))
	{
		$report .= '<br>PHP variable tests skipped';	
		continue;
	}
	
	if(!is_array($actual))
	{
		$report .= '<br>Could not record PHP variables';	
		continue;
	}
	
	// Execute the PHP test code
	eval($result_array['php_test_code']);
}

// Delete records from the database, they are not required
$QUERY = <<<END

	DELETE FROM
		`$phpautotest_table_test_results`
	WHERE
		`test_id` = '$test_id'
END;

$result = phpautotest_send_query($QUERY);

echo
"
<span class = 'header_text'>test report</span>
<p>phpautotest took another snapshot and carried out tests for each page. Here is what it found:</p>
$report
";

require 'includes/footer.php';
?>
Return current item: phpautotest