Возможность автоматизированного тестирования под несколькими браузерами.
- Подготовка проекта.
- Описание роботы c Selenium.
- Пример 1.
- Пример 2.
- Тестирование под несколькими браузерами.
1. Подготовка проекта.
И так приступим. К примеру, у нас есть webaplplication, который нам нужно протестировать, при чём протестировать с клиентской стороны. В этой ситуации конечно ни что не заменит труд тестировщика, но есть несколько уловок, которые позволят уменьшить монотонный труд.
Для этого устанавливаем Gallio и создаем проект в VS с MbUnit тестами.
Теперь попытаемся интегрировать селениум в наш проект.
Устанавливаем Java.
Качаем Selenium RC. Из скачанного нам нужно всего две библиотеки selenium-remote-control-1.0.3.zip\selenium-dotnet-client-driver-1.0.1\ThoughtWorks.Selenium.Core.dll и \selenium-remote-control-1.0.3.zip\selenium-server-1.0.3\ selenium-server.jar
Добавляем в проект эти две библиотеки.
Добавляем для этого проекта референс на ThoughtWorks.Selenium.Core.dll
Потом добавляем следующий класс, который будет подымать селениум сервер:
using System;
using System.Diagnostics;
using MbUnit.Framework;
namespace EHandelSeleniumTest
{
[TestFixture]
public class SeleniumTestingSetup : IDisposable
{
[SetUp]
public void Setup()
{
seleniumServerProcess = new Process();
seleniumServerProcess.StartInfo.FileName = "java";
//относительный путь к библиотеке
seleniumServerProcess.StartInfo.Arguments ="-jar ../../Tools/Selenium/selenium-server/selenium-server.jar -port " + ServerPort;
seleniumServerProcess.Start();
}
private int _serverPort;
public int ServerPort
{
get
{
if (_serverPort<=0)
{
return 4444;
}
return _serverPort;
}
set
{
_serverPort = value;
}
}
public bool IsStarted()
{
return seleniumServerProcess != null;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (false == disposed)
{
if (disposing)
DisposeOfSeleniumServer();
disposed = true;
}
}
private void DisposeOfSeleniumServer()
{
if (seleniumServerProcess != null)
{
try
{
seleniumServerProcess.Kill();
bool result = seleniumServerProcess.WaitForExit(10000);
}
finally
{
seleniumServerProcess.Dispose();
seleniumServerProcess = null;
}
}
}
private bool disposed;
private Process seleniumServerProcess;
}
}Теперь добавляем класс, который будет базовым для всех тестов:using System;
using System.Text;
using System.Threading;
using MbUnit.Framework;
using Selenium;
namespace EHandelSeleniumTest
{
[TestFixture]
public class SeleniumBase
{
//адрес тестируемого сайта.
private string sitePath = "http://www.google.com/";
//тестируемый броузер.
public string Browser = "firefox";
protected ISelenium selenium;
private StringBuilder VerificationErrors;
SeleniumTestingSetup seleniumServer = new SeleniumTestingSetup();
[SetUp]
public void SetupTest()
{
seleniumServer.Setup();
selenium = new DefaultSelenium("localhost", seleniumServer.ServerPort, "*" + Browser, sitePath);
selenium.Start();
VerificationErrors = new StringBuilder();
}
[TearDown]
public void TeardownTest()
{
try
{
selenium.Stop();
}
catch (Exception)
{
// Ignore errors if unable to close the browser
}
Assert.AreEqual("", VerificationErrors.ToString());
seleniumServer.Dispose();
}
}
}2.Описание роботы с Selenium.
Теперь ознакомимся с тулзой для автоматизирование тестирование Selenium Selenium для этого ставим расширение для Firefox
После этого у вас появиться возможность записывать тест сценарии. На сайте проекта есть видео, как начать работать с этой тулзой. В двух словах это выглядит так:
После установки плагина для FF у вас появиться следующий пункт в меню:
Выбираем этот пункт и у нас появиться следующее окно
жмем кнопку записи и с этого момента плагин будет записывать наши действия на сайте с последующей возможностью воспроизвести их.
3. Пример 1.
И так, давайте протестируем Google.com и попытаемся найти документацию для Selenium
Открываем Google.com, потом ставим селениум на запись и вводим в поиск «Selenium документация», жмем поиск.
У нас примерно будет следующий результат после всех наших действий.
Теперь нам нужно всё это экспортировать в наши тесты.
Экспортируем тест кейс в C# файл.
У нас получиться примерно такой код:
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using NUnit.Framework;
using Selenium;
namespace SeleniumTests
{
[TestFixture]
public class Test
{
private ISelenium selenium;
private StringBuilder verificationErrors;
[SetUp]
public void SetupTest()
{
selenium = new DefaultSelenium("localhost", 4444, "*chrome", "http://change-this-to-the-site-you-are-testing/");
selenium.Start();
verificationErrors = new StringBuilder();
}
[TearDown]
public void TeardownTest()
{
try
{
selenium.Stop();
}
catch (Exception)
{
// Ignore errors if unable to close the browser
}
Assert.AreEqual("", verificationErrors.ToString());
}
[Test]
public void TheTest2Test()
{
selenium.Open("/");
selenium.Type("q", "Selenium документация");
selenium.Click("btnG");
}
}
Добавляем этот класс к нашему проекту.Наследуемся от SeleniumBase класса, после этого удаляем весь мусор, оставив только сам метод с тестом TheTest2Test() переименовываем, и приводим в порядок:
namespace TestProject
{
[TestFixture]
public class UnitTest1 : SeleniumBase
{
[Test]
public void TheGoogleTest()
{
selenium.Open("/");
selenium.Type("q", "Selenium документация");
selenium.Click("btnG");
selenium.WaitForPageToLoad("1000");
Assert.IsTrue(selenium.IsTextPresent("Selenium"));
}
}
}
В тест мы добавили маленький таймаут, чтоб дать возможность странице загрузиться и проверку на вхождение поискового слова в ответе сайта.4.Пример 2.
Для второго примера я создал маленькую вебапликацию которая делает сложение двух чисел и выводит результат.
И так запускаем вебапликацию потом включает Selenium на запись.
Теперь продолжаем роботу с аппликацией. Вставляем операнд 1,2 и жмем кнопку.
Экспортируем тест в С# и добавляем проверку результата, не забываем сменить адрес сайта в SeleniumBase.
[Test]
public void TheSumTest()
{
selenium.Open("/Default.aspx");
selenium.Type("operant1", "3");
selenium.Type("operant2", "2");
selenium.Click("button1");
selenium.WaitForPageToLoad("30000");
Assert.AreEqual(int.Parse(selenium.GetText("result")),5);
}
Спасибо ASP .NET 4.0, а точнее новой фиче как ClientId для контролов. Теперь мы всегда можем знать id элемента и найти его намного проще. Для других версий ASP пришлось бы использовать XPath чтоб найти элемент, так как id элемента динамически перегененрировалось.И наш пример напоминал бы что такое
[Test]
public void TheSumTest()
{
selenium.Open("/Default.aspx");
selenium.Type("//input[@id='operant1']", "3");
selenium.Type("//input[@id='operant2']", "2");
selenium.Click("//input[@id='button1']");
selenium.WaitForPageToLoad("30000");
Assert.AreEqual(int.Parse(selenium.GetText("//span[@id='result']")), 5);
}
Мы запросто можем добавить всевозможные проверки или тело теста в цикл.Представим, что это была не простая задачка на суммирование двух чисел, а более сложные вычисление. Теперь делая изменения в аппликации нам не придётся перепроверять все места, где может возникнуть ошибка, а всего лишь перезапустить тест.
5. Тестирование под несколькими браузерами одновременно.
Если у вас возникло желание протестировать сразу под несколькими браузерами, то нам нужно будет пойти на некоторые ухищрение.
Есть два пути - лёгкий (не совсем корректный) и более тяжёлый:
1. Приводим наш тест метод к следующему виду
[Test]
[Row("firefox")]
[Row("googlechrome")]
public void TheGoogleTest(string browser)
{
Browser = browser;
selenium.Open("/");
selenium.Type("q", "Selenium документация");
selenium.Click("btnG");
selenium.WaitForPageToLoad("1000");
Assert.IsTrue(selenium.IsTextPresent("Selenium"));
}
Минус в том, что метод SeleniumBase.SetupTest() вызывается перед TheGoogleTest, поэтому сначала подыматься дефолтно прописанный браузер в нашем случае это FF.2. Модифицировать SeleniumBase:
Вынести логику с SetupTest в другой метод к примеру
public void RunServer(string browser)
{
seleniumServer.Setup();
selenium = new DefaultSelenium("localhost", seleniumServer.ServerPort, "*" + browser,sitePath);
selenium.Start();
VerificationErrors = new StringBuilder();
}
[SetUp]
public void SetupTest()
{
}
И с каждого теста вызывать его[Test]
[Row("firefox")]
[Row("googlechrome")]
public void TheGoogleTest(string browser)
{
RunServer(browser);
}
Плюс в том, что теперь будет вызываться конкретно прописанный браузер, а большим минусом есть то что нужно не забывать в каждом тесте прописывать вызов метода RunServer(browser); Немного сумбурно, но надеюсь, кому-то упростит роботу.
Полезные ссылки:
http://igorbrejc.net/category/development/testing/gallio-and-mbunit
http://lawrencesong.net/2008/01/selenium-element-locators
http://seleniumhq.org/docs/05_selenium_rc.html






