Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
1
Аспектно-ориентированное
программирование для Java
автоматизаторов
Сергей Мишанин
#COMAQA
4 ноября 2017
2
Кто я?
Sergey Mishanin
Lead Software Test
Automation Engineer
• 9 лет в автоматизации
• Тестирую UI и web-сервисы
• Изучаю и разрабатываю фреймворки и инструменты
• Джавист
Email: sergey_mishanin@epam.com
Skype: ssmishanin
3
Уверен, что вы уже сталкивались а аспектами
4
Что будет
• Знакомство с AOП на примере AspectJ
• Некоторые примеры применения аспектов а AT
• Нюансы использования
• Демо (после презентации)
5
Чего не будет
• Детального разбора всех вариантов использования
• Сложных примеров
6
Допустим, у вас есть Page Object’ы
7
Много Page Object’ов
8
Очень много Page Object’ов!
9
И в каждом есть всякие методы
10
Задача звучит так
Писать в лог все вызовы методов Page Object’ов
11
Варианты?
Писать в лог все вызовы методов Page Object’ов
Добавлять логгирование в
каждый метод руками?
12
Варианты?
Писать в лог все вызовы методов Page Object’ов
Добавлять некую
прослойку?
13
Варианты?
Писать в лог все вызовы методов Page Object’ов
Добавлять некую
прослойку?
14
Переформулируем задачу
Писать в лог все вызовы методов Page Object’ов
Вызывать метод логгирования перед вызовом
любого метода любого Page Object’а
15
К чему это я?
Писать в лог все вызовы методов Page Object’ов
Так аспекты именно это и позволяют!
Вызывать метод логгирования перед вызовом
любого метода любого Page Object’а
16
Немного теории
Аспектно-ориентированное программирование –
парадигма программирования помогающая реализовать
сквозную функциональность.
17
Немного теории
Аспектно-ориентированное программирование –
парадигма программирования помогающая реализовать
сквозную функциональность.
Сквозная функциональность –
функциональность, распределённая по
различным модулям программы.
18
Поясню на примере
19
Поясню на примере
20
Поясню на примере
21
Поясню на примере
22
Подключим зависимость
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.12</version>
</dependency>
23
Создадим aspect
Aspect (аспект) — модуль или класс,
реализующий сквозную функциональность.
Аспект изменяет поведение остального кода,
применяя совет в точках соединения,
определённых некоторым срезом.
24
Создадим aspect
package com.epam.aspects;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class PageObjectsAspects {
}
25
Определим pointcut
Join Point (точка соединения) — точка в
выполняемой программе, где следует
применить совет, например, вызовы
методов и обращения к полям объекта.
Pointcut (срез) — набор точек соединения.
Срез определяет, подходит ли данная точка
соединения к данному совету.
26
@Pointcut("call(public * com.epam.pages..*.* (..))")
public void anyPageObjectMethod() {
//Тут ничего писать не надо!
}
Определим pointcut
27
call(public * com.epam.pages..*.* (..))
вызов метода
Разберем паттерн
28
с любым именем
call(public * com.epam.pages..*.* (..))
Разберем паттерн
29
и любым набором аргументов
call(public * com.epam.pages..*.* (..))
Разберем паттерн
30
с модификатором public
call(public * com.epam.pages..*.* (..))
Разберем паттерн
31
И немного практики
и любым возвращаемым типом
call(public * com.epam.pages..*.* (..))
32
у типа с любым именем
call(public * com.epam.pages..*.* (..))
Разберем паттерн
33
из любого под-пакета
call(public * com.epam.pages..*.* (..))
Разберем паттерн
34
этого пакета
call(public * com.epam.pages..*.* (..))
Разберем паттерн
35
Добавим advice
Advice (совет) — средство оформления кода,
которое должно быть выполнено до, после или вместо
точки соединения.
36
@Before("anyPageObjectMethod()")
public void logMethod(JoinPoint joinPoint) {
Logger log = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
String message = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
if (args.length > 0){
message += " " + Arrays.toString(args);
}
log.info(message);
}
Добавим advice
37
А как же будет происходить внедрение?
СTW
Compile-time weaving
на этапе компиляции
LTW
Load-time weaving
на этапе загрузки
классов
38
Ну и какой вид мне лучше использовать?
39
Compile-time weaving
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.10</version>
<configuration>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
<target>1.8</target>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
Добавим аспектный
компилятор
40
Load-time weaving
Создадим src/main/resources/META-INF/aop.xml
<!DOCTYPE aspectj PUBLIC
"-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver>
<include within="com.epam..*"/>
<exclude within="com.epam.aspects..*"/>
</weaver>
<aspects>
<aspect name="com.epam.aspects.PageObjectsAspects" />
</aspects>
</aspectj>
41
Load-time weaving
<plugin>
<groupId>org.codehaus.mojo</groupId>
…
<configuration>
…
<includes>
<include>**/com/epam/aspects/*.java</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
Компилируем
только аспекты
42
Load-time weaving
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.20.1</version>
<configuration>
…
<argLine>
-javaagent:${settings.localRepository}/org/aspectj/aspectjweaver
/${aspectj.version}/aspectjweaver-${aspectj.version}.jar
</argLine>
</configuration>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
43
Запустим!
12:16:37.993 [main] INFO com.epam.pages.Header – clickSearchIcon
12:16:38.316 [main] INFO com.epam.pages.SearchForm - enterSearchText [webdriver]
12:16:38.881 [main] INFO com.epam.pages.SearchForm - submitSearchForm
44
А что там есть ещё?
@Before
@After
@AfterReturning
@AfterThrowing
@Around
call
execution
get
set
within
withincode
@annotation
…
Advices Pointcuts
45
@AfterThrowing
@AfterThrowing(value = "anyPageObjectMethod()", throwing= "ex")
public void logException (Exception ex, JoinPoint joinPoint) {
Logger log = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
log.info("URL: {}", WebDriverFactory.getDriver().getCurrentUrl());
log.info("Title: {}", WebDriverFactory.getDriver().getTitle());
}
46
@AfterReturning
@Pointcut("call(public !void com.epam.pages..*.* (..))")
public void notVoidPageObjectMethod() {
//Тут ничего писать не надо
}
@AfterReturning(value = "notVoidPageObjectMethod()", returning = "ret")
public void logReturnMethod(Object ret, JoinPoint joinPoint) {
Logger log = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
String message = joinPoint.getSignature().getName() + " returned " + ret;
log.info(message);
}
47
@Around
@Pointcut("call(* cucumber.runtime.model.CucumberScenarioOutline.examples (..))")
public void pointcutCucumberScenarioOutlineExamplesCall() {}
@Around(value="pointcutCucumberScenarioOutlineExamplesCall()")
public Object adviceAroundSeleniumCall(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs();
if (args.length > 0){
Examples examples = (Examples) args[0];
//…
//Тут был длинный код для генерации новой таблицы Examples
//…
joinPoint.proceed(new Object[]{examples});
} else {
joinPoint.proceed();
}
return null;
}
48
Итого
Использование аспектов позволяет:
• Упростить архитектуру фреймворка
• Адаптировать сторонние инструменты под ваши
нужды
49
Однако
50
Есть нюансы
CTW
LTW
51
А что с другими языками?
52
Полезные ссылки
53
Время для вопросов

More Related Content

Аспектно ориентированное программирование для Java автоматизаторов