Jump to content

qa/test scripts


.josh

Recommended Posts

In my job, I do a lot of QA/Testing of websites.  Many times I need certain things, for instance, I may need a dummy email address so I can go through a registration form.  This has led me to create a little script that helps make my job easier.  For example, one of the things my script does is it generates a timestamp based throwaway email address (and I have a filter setup to redirect to a specific qa email address if it is one of the generated email addresses, so that I can do things like validate email address to complete registration on a site if I need to go that far).  My script also gives ability to save the generated email address along with other notes (like URL of form, password used etc..) for reference if I need it.

 

Other things I have is a timestamp/datestring converter.  Basically just put in a timestamp and it converts to datestring and visa versa.  I also have a textarea where you can put in some random string and do things to it, like count the length of the string, truncate it to n chars, encode/decode, upper case, lowercase, convert from bin/hex/dec, md5 it, etc...

 

Anyways, not really trying to advertise a script or nothin', just trying to give you an idea of what I mean by a "qa/test" script, so that I can ask the following:  do you have any scripts like this, that you use for random things during your coding efforts? And if so, what kind of cool things does it do?

Link to comment
Share on other sites

I've made quick random scripts to do specific tasks such as calculate the UNIX timestamp of a specific date, convert dates to different formats, hash strings with different methods, etc. But I've never grouped them together into a single reusable entity.

 

However, the idea sounds neat so that will give me something to do this afternoon. :)

Link to comment
Share on other sites

Regarding throw-away emails: I have on my VPS postfix setup so that I can send an email to $anything@test.example.com and it will forward it to my email address.  That lets me just create whatever email I want so long is it has that extension.  For example in my test copy of the database I do an UPDATE query to set all the user's emails to Firstname.Lastname@test.example.com

 

Other than that I don't really have much for tools.  For the most part things like cli php and chrome dev console are enough to get by with what I need.

 

- See what a timestamp? (in ssh session)  php -r "var_dump(date('r', 123456789));'

- String length? (in chrome console) "some string".length

- base64 decode? php -r "echo base64_decode('<paste string>');"

- upper/lower a string? edit+ can do that

- md5 a string? (in ssh) md5sum -<enter><paste string>^D^D

 

Some kind of program or page that can do all this and more might be nice to have, I've not really found a need to create one or search for one though.  The tools I have can do most tasks easy enough, or I can generally make a short php script to do what I need easy enough.  The other day I needed to repeatedly base64 decode a bunch of different strings so I created this:


$data=file('php://stdin');

foreach ($data as $d){
        echo base64_decode($d), "\r\n\r\n";
}

 

Then at the bash prompt I could just run php decode.php and paste all the strings one per line, then ^D and it would decode and output them all.

 

Link to comment
Share on other sites

The most useful script I've ever written was a helper function called print_pre

 

function print_pre($a, $r = false ) {
    $d = '<textarea rows="50" cols="300" disabled="disabled">' . print_r($a, true) . '</textarea>';
    if ( $r ) return $d;
    echo $d;
}

I always make it globally available in any project I work on, it's perfect for debugging.  So much cleaner and easier than print_r.

 

Aside from that, I use the CLI.  I run linux and have a button on my sidebar that drops me right into php -a. 

Link to comment
Share on other sites

The most useful script I've ever written was a helper function called print_pre

 

Aye, I have a function like that as well as a few others.  I have them setup to check for an ENABLE_DEBUG constant too and only print/do stuff if it is defined and true.

 

markTime() for benchmarking/timing:

/* example use:
markTime();
..do stuff..
markTime();
..do more stuff..
markTime(true); 
*/
function markTime($finish=false, $lbl=null){
    static $points=array();
static $collecting=false;
if (!defined('ENABLE_DEBUG') || !ENABLE_DEBUG) return;

    if ($finish && $collecting && count($points) > 0){
	$collecting=false;

        if ($lbl == null){ $lbl = count($points); }
        $points[] = array($lbl, microtime(1));

	$firstPoint = reset($points);
	$lastPoint = end($points);

	ob_start();
	printf("<div class=\"timerBlock\" onclick=\"this.className += ' show';\">\r\n");
	printf("\t<p>Total Time: %0.3f seconds; Points: %d</p>", $lastPoint[1]-$firstPoint[1], count($points));
	printf("\t<p>Points:</p>\r\n<ol>\r\n");
	$previousPoint=null;
	foreach ($points as $p){
		printf("\t<li>%s\r\n\t<ul>\r\n", $p[0]);
		printf("\t\t<li title=\"Since Start\">%0.3fs</li>\r\n\t\t<li title=\"Since previous\">%0.3fs</li>\r\n",
			$p[1] - $firstPoint[1],
			($previousPoint)?$p[1] - $previousPoint[1]:'-'
		);
		printf("\t</ul>\r\n\t</li>\r\n");
		$previousPoint=$p;
        }
	printf("</ol></div>");
	$content = ob_get_contents();
	ob_end_flush();

	if (defined('ERROR_LOG')){
		$logDir = dirname(ERROR_LOG);
		$logFile = $logDir.DIRECTORY_SEPARATOR.'timer.log';
		if (file_exists($logDir) && @touch($logFile)){
			$fp = fopen($logFile, 'a');
			fprintf($fp, "<p>URI:%s</p>\r\n<p>SELF:%s</p>\r\n", $_SERVER['REQUEST_URI'], $_SERVER['PHP_SELF']);
			fwrite($fp, rtrim($content));
			fwrite($fp, "\r\n\r\n");
		}
	}
    }
    else if (!$finish){
        if ($lbl == null){ $lbl = count($points); }
        $points[] = array($lbl, microtime(1));
	if (!$collecting){
		$collecting=true;
		register_shutdown_function(create_function('', 'MarkTime(true);'));
	}
    }
}

 

dv() - basically var_dump() wrapped in <xmp></xmp> tags and controlled by the constant.

function dv(/*...*/){
if (!defined('ENABLE_DEBUG') || !ENABLE_DEBUG) return;

echo '<xmp>';
for ($i=0,$len=func_num_args(); $i<$len; $i++){
	$arg = func_get_arg($i);
	var_dump($arg);
	echo "\r\n";
}
echo '</xmp>';

}

 

debug_print_friendly_backtrace() -- prints out a more friendly looking backtrace.

function debug_print_friendly_backtrace($html=true, $return=false){
if ((!defined('ENABLE_DEBUG') || !ENABLE_DEBUG) && !$return){ return; }

$info = debug_backtrace();
unset($info[0]);//First frame is this function call, ignore it.

$frames=count($info);
$retStr='';

if ($html){
	$retStr .= '<div class="stackTrace"><p>Stack Trace ('.date('r').'):</p><ul>';
	foreach ($info as $frameNum=>$frame){
		$fn = $frame['function'];
		if (!empty($frame['class'])){
			$fn = $frame['class'].$frame['type'].$fn;
		}

		$args=array();
		if (isset($frame['args']) && is_array($frame['args'])){
			foreach ($frame['args'] as $arg){
				$args[] = sprintf("(%s) %s", gettype($arg), dpfb_stringify($arg));
			}
		}

		$args = array_map(create_function('$a', 'return "<div class=\"arg\">".htmlentities($a)."</div>";'), $args);
		$retStr .= sprintf(
			"<li>#%d: %s(\r\n\t<div style=\"margin-left: 20px;\" class=\"argList\">%s</div>\r\n) (%s:%d)</li>\r\n",
			($frames-$frameNum)+1,
			htmlentities($fn),
			implode(", ", $args),
			htmlentities($frame['file']),
			htmlentities($frame['line'])
		);
	}
	$retStr .= '</ul></div>';
}
else {
	$retStr .= "\r\nStack Trace (".date('r')."):\r\n";
	foreach ($info as $frameNum=>$frame){
		$fn = $frame['function'];
		if (!empty($frame['class'])){
			$fn = $frame['class'].$frame['type'].$fn;
		}

		$args=array();
		if (isset($frame['args']) && is_array($frame['args'])){
			foreach ($frame['args'] as $arg){
				$args[] = sprintf("(%s) %s", gettype($arg), dpfb_stringify($arg));
			}
		}

		$retStr .= sprintf(
			"\t#%d: %s(\r\n\t%s\r\n) (%s:%d)\r\n",
			($frames-$frameNum)+1,
			$fn,
			implode("\r\n\t, ", $args),
			isset($frame['file'])?$frame['file']:'-',
			isset($frame['line'])?$frame['line']:'0'
		);
	}
	$retStr .= "\r\n";
}

if ($return){
	return $retStr;
}
else {
	echo $retStr;
}
}

function dpfb_stringify($arg, $depth=2){
if (is_array($arg)){
	if ($depth > 0){
		$str = 'array(';
		foreach ($arg as $k=>$v){
			$str .= '['.$k.'] => ('.gettype($v).') '.dpfb_stringify($v, $depth-1).', ';
		}
		$str = substr($str, 0, -2).')';
	}
	else {
		return 'Array(len='.count($arg).')';
	}
	return $str;
}
else if (is_object($arg)){
	return get_class($arg);
}
else if (is_string($arg)){
	$newstr = str_replace(array("\r\n", "\r", "\n", '"'), array('\r\n', '\r', '\n', '\"'), $arg);
	$ret = '('.strlen($arg).') "'.$newstr.'"';
	return $ret;
}
else if (is_bool($arg)){
	return $arg?'true':'false';
}
else {
	return (string)$arg;
}
}

 

I use the above fairly extensively during development.  The enable debug flag is handy  in case I forget to remove them before pushing out changes, the production servers don't define it so they don't output anything.

 

Link to comment
Share on other sites

The only thing I have really made was something that did some bench marking.

 

$d = new Debug(); // pass false to disable
// Do some code
$d->time();
// Do some code
$d->time();
// Do some code
$d->time();
// Do some code
$d->time();
// Do some code
$d->time();

 

every time you called the time() method it would echo something like this:

 

0.0282020983 seconds at line 2 in file /home/www/index.php
0.0282020983 seconds at line 10 in file /home/www/index.php
0.1282020983 seconds at line 81 in file /home/www/index.php
4.0282020983 seconds at line 120 in file /home/www/index.php
4.0482020983 seconds at line 578 in file /home/www/index.php

 

As you can see on the 4th call it jumps up to 4 seconds and is something you might want to take a look at. If you were to place the $d->time() in an included file, it would say that file's name and the line in that file. I don't know if there is a better way to do this, but It has allowed me to pin point slow sections with in code after loops, MySQL queries, or any other constructs/functions/methods.

Link to comment
Share on other sites

Yeah, I've used Selenium before. nifty stuff!

 

Have you messed at all with Sauce Labs?  One super sexy feature they have is the video recording feature.  So not only do you get the test results, but you can watch a playback of the app running on a particular browser/os combo.  They have a free trial to play with.

Link to comment
Share on other sites

Interesting - I have not heard of them before. I will need to check this out, cheers!

 

You can actually use the service interactively, so if you ever get one of those bugs where it's "So and so says the site is FUBAR on IE 6 on XP", you can actually jump into an IE6 environment and load your site up interactively and see if they are full of crap or not.  The only environments they don't have are Mac.  Last I talked to them they even have an IPAD cluster, but I think that is stilll in beta.  Just a great idea, well executed so far.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.