Created
June 25, 2013 14:43
-
-
Save jsatt/5859019 to your computer and use it in GitHub Desktop.
Script for running page speed tests with selenium
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from datetime import datetime | |
from math import sqrt | |
from time import sleep | |
import csv | |
import logging | |
import urlparse | |
from selenium import selenium | |
SELENIUM_BROWSERS = ['firefox'] | |
SELENIUM_HOST = 'localhost' | |
SELENIUM_PORT = 4444 | |
# ie | |
# 'iexploreproxy C:\\Program Files\\Utilu IE Collection\\IE800\\iexplore.exe' | |
def page_speed(urls=[], runs=5, delay=5, filename='page_speed.csv', | |
browsers=SELENIUM_BROWSERS, host=SELENIUM_HOST, | |
port=SELENIUM_PORT): | |
''' | |
Loads the urls repeatedly in the browsers using Selenium and calulates | |
pageload times for each page on each browser, including mean, median and | |
standard deviation. | |
Returns a list of dicts containing the url, browser, avg/mean, median, | |
standard deviation, failed test and raw data for each url-browser | |
combination. | |
If filename is not None (default=page_speed.csv), will export a csv of the | |
returned results list to that filename. | |
''' | |
results = [] # start list to store all results | |
# loop through each browser | |
for browser in browsers: | |
# loop through each url | |
for url in urls: | |
url_durations = [] # start a dict to store url results | |
# parse the parts of the current url | |
if not url.startswith('http'): | |
url = 'http://' + url | |
parsed_url = urlparse.urlparse(url) | |
site = parsed_url.scheme + '://' + parsed_url.netloc | |
path = parsed_url.path | |
# connect to the selenum server | |
sel = selenium(host, port, '*%s' % browser, site) | |
sel.start() # start the selenium instance | |
# loop for each run needed | |
for run in range(runs + 1): | |
# if not the first run add delay | |
if run: | |
sleep(delay) | |
try: | |
page_load_start = datetime.now() # get current timestamp | |
sel.open(path) # open the page | |
sel.wait_for_page_to_load(180000) # wait for page to load | |
page_load_end = datetime.now() # get a new timestamps | |
except Exception as e: | |
logging.debug('error (%s) loading run #%d of %s in %s' % ( | |
e, run, url, browser)) | |
else: | |
# calculate elapsed time and add to url results | |
if run: # skip first run | |
url_durations.append( | |
get_elapsed_secs(page_load_start, page_load_end)) | |
sel.stop() # stop the selenium instance | |
raw_results = ','.join([str(n) for n in url_durations]) | |
failed_runs = runs - len(url_durations) | |
url_results = {'browser': browser, 'url': url, | |
'raw_results': raw_results, | |
'failed_runs': failed_runs} | |
if url_durations: | |
# calulate average, median and standard deviation of results | |
url_results['avg'] = (sum(url_durations) / len(url_durations)) | |
url_results['median'] = median(url_durations) | |
url_results['std_dev'] = standard_deviation(url_durations) | |
logging.debug(str(url_results)) | |
# add to results | |
results.append(url_results) | |
if filename: | |
csv_fields = ['browser', 'url', 'avg', 'median', 'std_dev', | |
'failed_runs', 'raw_results'] | |
with open(filename, 'w') as f: | |
writer = csv.DictWriter(f, csv_fields) | |
writer.writerow(dict((n, n) for n in csv_fields)) | |
for row in results: | |
writer.writerow(row) | |
return results | |
def get_elapsed_secs(dt_start, dt_end): | |
dt_delta = (dt_end - dt_start) | |
return float('%.3f' % (dt_delta.seconds + | |
(dt_delta.microseconds / 1000000.0))) | |
def median(values): | |
values = sorted(values) | |
if len(values) % 2 == 1: | |
return values[(len(values) + 1) / 2 - 1] | |
else: | |
lower = values[len(values) / 2 - 1] | |
upper = values[len(values) / 2] | |
return (float(lower + upper)) / 2 | |
def standard_deviation(values): | |
mean = sum(values) / len(values) | |
sum_of_sqr = sum([(n - mean) ** 2 for n in values]) | |
return sqrt(sum_of_sqr / len(values)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment