Практически каждый тестовый сценарий состоит из трех частей:
- pre-conditions
- scenario
- post-conditions
В мире программирования такие методы принято называть setUp, test, tearDown:
- метод setUp отвечает за подготовку данных или системы в определенное состояние;
- метод test отвечает непосредственно за выполнение тестовой логики;
- метод tearDown отвечает за очистку от тестовых данных или возвращение системы в изначальное состояние.
В контексте web приложений и языка программирования Java, это будет выглядеть следующим образом:
@Before
public void setup() {
//Login to the system
steps.login();
}
@Test
public void addNewMember() {
// Test Logic
steps.openAddNewMember();
steps.addMember(newMember);
asserts.thatEditUserPageOpened();
asserts.thatUserPresentInViewMembers(newMember.getName());
}
@AfterMethod
public void tearDown() {
//Removing created member
steps.removeMember(newMember.getName());
}
Все функции реализованы с использованием WebDriver API, то есть взаимодействуют с браузером напрямую.
Пример функции removeMember:
public void removeMember(String name) {
viewMembersPage.open();
viewMembersPage.clickDeleteMemberBy(name);
viewMembersPage.acceptConfirmation();
}
public void clickDeleteMemberBy(String name) {
driver.findElement(By.xpath(String.format(CELL_MEMBER_NAME +
LINK_DELETE_MEMBER, name))).click();
}
Это простой пример. Но представьте каким количеством действий может обладать функция tearDown() для более комплексной системы. Или когда эта функция встречается в каждом тесте. Все это значительно отразится на скорости выполнения тестов.
Самый простой выход из ситуации, который я применяю на своих проектах – это использование библиотеки HttpClient (библиотека доступна в дистрибутиве selenium). Это бесплатная Java библиотека, позволяющая формировать HTTP запросы, отправлять их на сервер и принимать ответы в виде Java объектов.
При помощи этой библиотеки возможно самостоятельно формировать необходимые запросы, чтобы взаимодействовать с тестируемой системой посредством обращения к серверу, минуя взаимодействие с браузером. Таким образом, наши функции будут отрабатывать быстрее.
Как это выглядит:
private static int deleteUser(String name) throws IOException {
HttpGet deleteUserRequest = new HttpGet("http://cells.org.ua/scrum-selenium/admin/pageDeleteMember.php?memberID=" + name);
HttpResponse response = getHttpClient().execute(deleteUserRequest);
return response.getStatusLine().getStatusCode();
}
private static DefaultHttpClient getHttpClient() {
if (httpClient == null) {
PoolingClientConnectionManager cm = new PoolingClientConnectionManager();
cm.setMaxTotal(100);
httpClient = new DefaultHttpClient(cm);
}
return httpClient;
}
Для тех случаев, когда в вашу систему нужно предварительно залогиниться, вызываем POST запрос на вход до вызова функции removeMember.
Пример POST запроса, функция login:
private static int login() throws IOException {
HttpPost loginRequest = new HttpPost("http://cells.org.ua/scrum-selenium/admin/pageHome.php");
List<NameValuePair> credentials = new ArrayList<NameValuePair>();
credentials.add(new BasicNameValuePair("username", "admin"));
credentials.add(new BasicNameValuePair("password", "admin"));
loginRequest.setEntity(new UrlEncodedFormEntity(credentials, Consts.UTF_8));
HttpResponse response = getHttpClient().execute(loginRequest);
return response.getStatusLine().getStatusCode();
}
Пример класса на GitHub.
Небольшие замеры
long start = System.nanoTime();
steps.removeMember(newMember.getName());
// HttpActions.removeMember(newMember.getName());
long elapsedTime = System.nanoTime() - start;
Среднее время выполнение с использованием WebDriver API ~ 1055 milliseconds.
Среднее время выполнение с использование HTTPClient ~ 360 milliseconds.
Заменить WebDriver на использование HttpClient рискованно, так как мы принимаем все риски, связанные с работой приложения в браузере. Потому все, что вызывается внутри функции test, лучше делать при помощи WebDriver API, так как мы эмулируем действия конечного пользователя. Подготовительную же или завершающую части можно отнести на HttpClient.
Как альтернативу можно использовать HtmlUnit, этот инструмент работает по похожему принципу, но обернут в WebDriver API. При этом стоит учитывать риски, которые ограничивают работу HtmlUnit, а именно работа с тяжелыми JavaScript приложениями. При помощи HttpClient мы сами формируем запросы на сервер, что дает нам больше гибкости и снижает вероятность головной боли.
Все примеры кода доступны на GitHub.
Не хочешь пропускать ничего интересного? Подпишись на ленту RSS или следи за нами в Twitter!