Сбор статистики загрузки веб-страниц

в 14:18, , рубрики: python, selenium, Веб-разработка, загрузка, Клиентская оптимизация, тестирование, метки: , , ,

Хотел бы поделитья с сообществом полезным инструментом для фронт-разработчиков, в основном. Инструмент достаточно сыроват, нуждается в развитии. Попросту говоря, это банальный говнокод, который решает поставленную задачу. Для рефакторинга мне не хватает компетенции.

Какую задачу решаем?

Скрипт позвляет собрать статистику по «полной» загрузке страницы на стороне браузера. Это не равняется времени выдачи страницы сервером, очевидно. Под полной загрузкой я подразумеваю загрузку всех ресурсов страницы (картинки, стили, скрипты) и выполнение браузерного события onload. Как все знают, это время можно посмотреть в firebug. Но очевидно, что для адекватной оценки нужно собрать статистику, т.е. открыть страницу и запомнить время ее полной загрузки не один и не два раза. На основе сотни запусков уже можно говорить о среднем времени полной загрузки, и это будет хорошей метрикой, в моем понимании.

В свое время было написано расширение для firebug Firefox v.3.6, которое позволяло собирать такую статистику, причем можно было выключать браузерный кэш — Hammerhead ( stevesouders.com/hammerhead/ ). С новыми версиями оно, к сожалению, не совместимо.

Мне такая статистика была нужна для оценки эффективности проведенных оптимизаций загрузки файлов javascript. В итоге, не найдя ничего подходящего, я сделал свой велосипед. Как основа выбрана система автоматического тестирования веб-интерфейсов Selenium WebDriver. Я использовал python-версию. Для измерения времени используется относительно новый объект HTML5 window.performance (подробнее см. www.html5rocks.com/en/tutorials/webperformance/basics/).

Запуск скрипта

Это был мой первый (и пока последний!) тест для Selenium, так что столкнулся с некоторыми трудностями установки и запуска. В общем, советую ориентироваться на мастер-класс Михаила Поляруша «How to write your first selenium test?» ( youtu.be/IPraAY78jGY?t=22m22s )
Чтобы скрипт успешно запустился, необходимо соблюдение ряда условий:
а) наличие python на машинке
б) установка непосредственно продукта автоматического тестирования:

pip install selenium

в) установка python интерпертатора для тестов, аналога JUnit:

pip install pytest

Команда для запуска теста, помещенного, к примеру, в файл test.py:

py.test test.py

Как выглядит запуск, скриншот:
image

Описание кода

(как уже договорились, весь код находится в единственном файле test.py)

# author: ivn_cote
# MIT license
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
import unittest, time

class Test3(unittest.TestCase):
    def setUp(self): # блок выполняется перед запуском тестов
        self.driver = webdriver.Firefox() 		# указываем драйвер браузера, можно также указать webdriver.Chrome('./chromedriver')
        self.driver.implicitly_wait(10) 		# 10 сек в качестве максимального таймаута для выполнения методов
        self.base_url = "http://www.amazon.de"  # тестируемый сайт
        self.verificationErrors = []
        self.driver.get(self.base_url + "/gp/yourstore/home?ie=UTF8&ref_=topnav_ys") # открываем конкретную страницу
    	
    	
    def test_stat(self): # единственный тест для запуска 
		loops = 2 # число переоткрытий страниц
		driver = self.driver
		total = 0
		# в случае, если сайт работает с куками, их нужно проставить,
		# напр., так:
		#self.driver.execute_script( "document.cookie='name=value'" )
		# есть еще идеологически правильный способ, но он у меня не срабатывал:
		#self.driver.add_cookie({'name':'value'})
		for j in range(loops):
			driver.refresh()
			#time.sleep(3) # ждем 3 сек загрузку страницы, раскомментировать для Chrome!
			# получаем число миллисекунд для браузерного события onload
			stext = self.driver.execute_script( "return ( window.performance.timing.loadEventEnd - window.performance.timing.navigationStart )")
			total = total + int(stext)
			print "Value is: %s" % stext
		print "TOTAL is: %s" % (total / loops ) 
		self.assertEqual("0", total) # сравнение никогда не выполняется, это единственный способ (который я нашел), чтобы скрипт выводил стандартный вывод в консоль
    
    def tearDown(self): # блок выполняется после запуска тестов
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
    unittest.main()

Возможности:

Итак, еще раз о том, что позволяет делать инструмент:

  • Автоматический сбор статистики по полной загрузке любой страницы.
  • Запуск в Chrome или Firefox (при этом можно настравивать профили браузеров, насколько я понимаю).

Буду рад, если этот инструмент пригодится еще кому-то!
Хотелось бы его усовершенствовать, конечно. Во-первых, разобраться с выводом информации со статистикой — помещать ее в файл. Во-вторых, собирать большее число параметров из window.performance. В-третьих, было бы замечательно вместо цифр видеть графики.

Автор: ivnC


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js