One of the most important goals in automated testing is to identify when and why the errors are shown in the test cases. Logging is a useful tool to find the answers to these questions. However the implementation of a logger unit is not so easy in accordance with the object oriented principles. The aspect oriented programing can solve this problem on a way where the logger unit could be a separate module besides the tests and other parts.

There are more slightly different implementations of aspect oriented programing in Java just like JBoss, Java Aspect Components or Spring but in this example the AspectJ is used to present the basic functionalities and to help with the first steps of logging on this way. Eclipse IDE needs to contain the appropriate plugin which is available here: https://eclipse.org/aspectj/

The aspects are very similar to Java classes. They contain one or more advice and joinpoints and the inheritance is possible. The joinpoints are specific places in classes where the code is inserted. Meanwhile advice is a code which will be inserted in the original code. If you are more familiar with annotations you can implement the aspects through them. Click this link for details:
https://eclipse.org/aspectj/doc/released/adk15notebook/ataspectj.html

The sample project is available on GitHub. Download and try it yourself:
https://github.com/WeDoQA/aspectJLoggingExample

A simple test case is created which inserts the word “wedoqa” into Google and compares the top result with the name of the company. However this time the accent is on the PageUtils.java class and LoggerAspect.aj aspect. The goal is to every single wait, click and sendChar event be logged by the aspects.

Let me show you a concrete example:

public WebElement waitForElementToAppear(By locator) {
int count = 0;
	while (count < 5){
		try {				
			WebDriverWait wait = new WebDriverWait(driver, WAIT_TIME / 5);	
			Return wait.until(ExpectedConditions.visibilityOfElementLocated(locator));
		}catch (StaleElementReferenceException e){
			count = count+1;
		}
		catch (TimeoutException e) {
			count = count+1;
		}
	}
	Assert.fail("Element is not appeared.");
	return null;
}

Here is a classic wait method from PageUtils.java file that waits until the element with the locator appears or if it is not available the method will throw an AssertionError. It would be useful if the logger catches when the element does or does not appear. In LoggerAspect.aj file a pointcut is created to handle the mentioned situations:

pointcut waitForElementToAppeareWithByParam(By locator): execution(* utils.PageUtils.waitForElementToAppear(By)) && args(locator);

The pointcut’s name is waitForElementToAppeareWithByParam and has a By parameter just like the wait function. “execution” means that the aspect will track the execution process of the function. In the brackets is defined the type (it could be anything), the location, the name and the parameter of the function which is observed. After signs “&&” the argument value is requested and it will be used later on.

after(By locator) returning: waitForElementToAppeareWithByParam(locator){
System.out.println("WebElement found with locator: " + locator);
}
	
after(By locator) throwing (AssertionError e): waitForElementToAppeareWithByParam(locator) {
System.out.println(thisJoinPointStaticPart.getSignature());
e.printStackTrace();
}

Two advice is created to handle both cases when the element is found and the assertion is thrown. The keyword “after” means that this part of code will be executed after the original method but it will depends on the result of the process. The advice with “returning” keyword will print its message when the element is found successfully meanwhile the other advice will print the signature of the method and the text of the assertion.
At the end of the test case the console contains the following lines:

WebElement found with locator: By.xpath: //*[@name = ‘q’]
“wedoqa” inserted into element xpath: //*[@name = ‘q’]
WebElement found with locator: By.name: btnG
Element is clicked: name: btnG
WebElement found with locator: By.selector: #rso>li .rc>h3 a

Feel free to user any logger what you are familiar with instead of printing.
This type of logging could be exceptionally useful in large projects with many files because on this way it is not necessary to find all logger actions in affected files therefore the logging could be handled on a higher level.

Similar Posts from the author: