Добрый день.
Преимущества Selenium Grid для запуска параллельных тестов неоспоримы. Схема кластера (хаб-узлы) позволяет управлять всем хозяйством из одного места, что открывает замечательные возможности для масштабирования среды и запуска тестов с различными браузерами и в различных операционных системах. В то же время, иногда возникает необходимость более гибкого функционирования каждого из узлов без привязки их к одному хабу. Ниже представлен один из вариантов такой реализации.
Задача: запуск параллельных тестов под разными пользователями. Имена пользователей: <Prefix>simuser<UserNumber>. Тесты выполняются многократно (параметр). Тесты запускаются параллельно в рамках одного узла и одновременно на всех узлах.
run.bat:
set Selenium=selenium-server-standalone-2.41.0.jar set Host=10.9.1.15 set Prefix=q365 set StartUser=%1 set EndUser=%2 set HowMuchLoop=%3 set GroovyCmd=start /B groovy -cp %Selenium% portal.groovy FOR /L %%N IN (%StartUser%,1,%EndUser%) DO %GroovyCmd% %HowMuchLoop% %Host% %Prefix%simuser%%N UserPaSsW0RD%%N
У run.bat три параметра:
На каждой машине можно задавать свои имена (номера) пользователей и количество повторов. Примеры запуска:
portal.groovy:
import org.openqa.selenium.* import org.openqa.selenium.firefox.* import org.openqa.selenium.support.ui.Select import org.openqa.selenium.interactions.Actions import java.util.concurrent.TimeUnit import org.apache.commons.io.FileUtils import java.text.SimpleDateFormat HowMuchLoop = args[0].toInteger() Host = args[1] UserName = args[2] UserPassword = args[3] for (int i = 0; i < HowMuchLoop; i++) { driver = new FirefoxDriver() driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS) HostAddr = "https://" + Host + "/portal/" driver.get(HostAddr) Thread.sleep(2000) try { driver.findElement(By.id("loginUserName")).sendKeys(UserName) driver.findElement(By.id("loginPassword")).sendKeys(UserPassword) driver.findElement(By.id("btnLogin")).click() // Any actions required in Web UI are to be done here } catch (e) { takeScreenshot(driver, "portal") println ("Something went wrong: " + e) } driver.quit() } println ("Finished.") // ============================= Functions ========================== // Take a screenshot def takeScreenshot (driver, screenshotName) { screenshotFolder = "Your_path_to_the_screenshot_folder" screenshotFolderHandler = new File (screenshotFolder) if ( !screenshotFolderHandler.exists() ) { screenshotFolderHandler.mkdirs() } timeStamp = new SimpleDateFormat("ddMMyyyy_HHmmss").format(Calendar.getInstance().getTime()) screenshotName = screenshotName + "_" + timeStamp + ".png" println("Screenshot Name: " + screenshotName) screenshotPath = screenshotFolder + screenshotName File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE); FileUtils.copyFile(scrFile, new File(screenshotPath)); }
Перед запуском тестов можно зачистить для них площадку, убив зависшие или ненужные процессы:
killproc.js:
KillThemAll(); function KillThemAll() { var gWbemLocator = new ActiveXObject("WbemScripting.SWbemLocator"); var objWMIService = gWbemLocator.ConnectServer("localhost","root\\cimv2","",""); var colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Process"); var enumItems = new Enumerator(colItems); WScript.Echo("\n\nKilling all firefox, cmd.exe, and java processes before running the tests... \n\n"); for (; !enumItems.atEnd(); enumItems.moveNext()) { var ProcessName = enumItems.item().Name; if (ProcessName == "firefox.exe" || ProcessName == "cmd.exe" || ProcessName == "java.exe") enumItems.item().Terminate(); } }
Запуск:
В итоге, на каждом узле запускается N одновременных тестов (N определяется мощностью узла). Удаленный запуск run.bat на узлах несложно организовать с помощью утилиты psexec.
Всего доброго.
Что такое качество программного обеспечения и как его улучшить: теория и практика, задачи и решения, подводные камни и обходные пути.