Я предполагаю, что
- вы используете полный AspectJ, а не что-то вроде Spring AOP (потому что тогда ответ не будет применяться),
- вы используете не хотите записывать вызовы методов рекурсивно, но только те, которые вызываются напрямую из ваших
@Test
методов. Например, если Account.login(..)
вызовет внутренний вызов Account.checkPassword(..)
, это не должно быть записано. Это тоже возможно, но тогда решение будет выглядеть по-другому. - все, что вам нужно, - это регистрировать выполнение теста и больше ничего не делать, поэтому совет
@Around
не нужен, @Before
достаточно .
Классы фиктивных приложений:
package de.scrum_master.app;
public class Account {
public void login(String user, String password) {
checkPassword(password);
}
public void checkPassword(String password) {}
}
package de.scrum_master.app;
public class AccountAuthentication {
public void waitForPage() {}
}
package de.scrum_master.app;
public class Home {
public void clickOnAccount() {
doSomethingElse();
}
public void doSomethingElse() {}
}
Аннотации маркера:
Я создал его сам, потому что мне было лень создавать проект с TestNG, который я обычно не использую.
package org.testng.annotations;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(METHOD)
public @interface Test {}
Пример приложения:
package de.scrum_master.app;
import org.testng.annotations.Test;
public class Sample {
Home home = new Home();
Account account = new Account();
AccountAuthentication accountAuthentication = new AccountAuthentication();
@Test
public void loginInvalidCredentials() {
home.clickOnAccount();
account.login("Admin", "secret");
accountAuthentication.waitForPage();
}
public static void main(String[] args) {
new Sample().loginInvalidCredentials();
}
}
Аспект:
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class TestExecutionLogger {
@Before("execution(* *(..)) && @annotation(org.testng.annotations.Test)")
public void logTest(JoinPoint joinPoint) {
System.out.println(joinPoint);
}
@Before("call(* *(..)) && withincode(@org.testng.annotations.Test * *(..))")
public void logTestActions(JoinPoint joinPoint) {
System.out.println(" " + joinPoint);
}
}
Журнал консоли:
execution(void de.scrum_master.app.Sample.loginInvalidCredentials())
call(void de.scrum_master.app.Home.clickOnAccount())
call(void de.scrum_master.app.Account.login(String, String))
call(void de.scrum_master.app.AccountAuthentication.waitForPage())
Конечно, вы можете уточнить свой аспект, если действительно думаете вам необходимо удалить простые имена методов из информативного вывода журнала AspectJ:
@Before("execution(* *(..)) && @annotation(org.testng.annotations.Test)")
public void logTest(JoinPoint joinPoint) {
System.out.println(joinPoint.getSignature());
}
@Before("call(* *(..)) && withincode(@org.testng.annotations.Test * *(..))")
public void logTestActions(JoinPoint joinPoint) {
System.out.println(" " + joinPoint.getSignature());
}
void de.scrum_master.app.Sample.loginInvalidCredentials()
void de.scrum_master.app.Home.clickOnAccount()
void de.scrum_master.app.Account.login(String, String)
void de.scrum_master.app.AccountAuthentication.waitForPage()
Вы можете дополнительно уточнить его, если вы намеренно хотите удалить тип возвращаемого метода или включить фактические значения параметров, как в ваш пример, который легко возможен через JoinPoint.getArgs()
, но я оставляю это на ваше усмотрение. Ваш вопрос касался срезов точек, а не того, как извлекать информацию из точек соединения.