Dealing with multiple JUnit test cases - selenium

I'm writing JUnit test cases using the selenium web driver, and I'm running into issues when trying to make multiple tests in one file. Here is an example of my code structure:
public class exampleScripts extends SeleneseTestCase {
public void setUp() throws Exception{
SeleniumServer seleniumServer = new SeleniumServer();
seleniumServer.start();
setUp("https://my.target.URL", *firefox");
}
#Test
public void test1() throws Exception {
//do test stuff
try {
//check if results are good
}
catch (Throwable e) {
//handle error
}
}
#Test
public void test2() throws Exception {
//do more test stuff
try {
//check results
}
catch (Throwable e) {
//handle error
}
}
}
Now, the tests by themselves work correctly, but I am getting the error Failed to start: SocketListener1#0.0.0.0:4444 when running my class as a whole. The first test runs correctly, but the second I move on to the next test, it seems like it's trying to re-start the session, when I just want it to continue on the old session. How do I get around this issue?

It seems I was able to find a wonky work-around for this problem, though I wouldn't recommend this to others as a solution. I created a test_suite function to run all my tests, and log the results myself.
public void setUp() {
//setUp stuff
}
public void testAll() throws Exception {
selenium.open("my/target/path");
test1();
test2();
}
#Test
public void test1() throws Exception {
//test stuff
try {
//check results
}
catch (Throwable e) {
log.INFO("There was an error in test1");
}
}
//and so on
The whole test suite would be run on testAll(). Again, would not recommend this solution, as it does not take advantage of JUnit's logging, but it worked for me.

Related

Integrate Extent Reports with AWS Device Farm and Jenkins

I am new to automation and I have been integrating AWS device farm to run my test cases on cloud. I have integrated Jenkins with AWS device farm to run the tests on the go. I want to integrate Extent Reports to see the results of the run inside Jenkins. I can't find any tutorial to do so. Can you please help me with this.
I have installed the HTML publisher in Jenkins and I have implemented Extent Reports for my local run and its working. But, I have no idea how to integrate for the cloud.
Thanks in advance. Stay Safe
Here is my code for local integration of Extent Reports
ExtentTest test;
ExtentReports extent = ExtentReportsBlackstone.getReportObject();
ThreadLocal<ExtentTest> extentTest = new ThreadLocal<ExtentTest>();
AppiumDriver<?> driver ;
#Override
public void onTestStart(ITestResult result) {
test = extent.createTest(result.getMethod().getMethodName()).assignCategory(result.getMethod().getGroups());
extentTest.set(test);
}
#Override
public void onTestSuccess(ITestResult result){
// TODO Auto-generated method stub
extentTest.get().log(Status.PASS, "Test Passed");
Properties prop = UtilityBase.globalProperties();
if(prop.getProperty("captureScreenshotOnTestPass").equals("true")) {
String testMethodName = result.getMethod().getMethodName();
try {
Class clazz = result.getTestClass().getRealClass();
Field field = clazz.getDeclaredField("driver");
field.setAccessible(true);
driver = (AppiumDriver<?>) field.get(result.getInstance());
} catch(Exception e) {
e.printStackTrace();
}
try {
extentTest.get().addScreenCaptureFromPath(getScreenshot(this.driver,testMethodName), result.getMethod().getMethodName());
} catch(IOException e){
e.printStackTrace();
}
}
}
#Override
public void onTestFailure(ITestResult result) {
// TODO Auto-generated method stub
extentTest.get().fail(result.getThrowable());
String testMethodName = result.getMethod().getMethodName();
try {
Class clazz = result.getTestClass().getRealClass();
Field field = clazz.getDeclaredField("driver");
field.setAccessible(true);
driver = (AppiumDriver<?>) field.get(result.getInstance());
} catch(Exception e) {
e.printStackTrace();
}
try {
extentTest.get().addScreenCaptureFromPath(getScreenshot(this.driver,testMethodName), result.getMethod().getMethodName());
} catch(IOException e){
e.printStackTrace();
}
}
#Override
public void onTestSkipped(ITestResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onTestFailedButWithinSuccessPercentage(ITestResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onStart(ITestContext context) {
// TODO Auto-generated method stub
try {
UtilityBase.deleteFolder(System.getProperty("user.dir")+"/reports");
}catch(IOException e) {
e.printStackTrace();
}
}
#Override
public void onFinish(ITestContext context) {
// TODO Auto-generated method stub
extent.flush();
}
}
estimate cannot be integrated, aws is a bit limited and for that option we opted for lambatest, where we send it to run in the cloud but the evidence remains in extend report in our aws node
aws asks to compile the project and upload the project which runs on its own server, I don't like that way of execution

ASP.NET Core Interception with Castle.DinamicProxy doesn't throw Exception with Async Methods !!! How can I solve this?

I have been creating a project with Aspect Oriented Programming paradigm and
I have an "ExceptionLogAspect" class attribute which is used on business methods to log the errors throwing from them.
public class ExceptionLogAspect : MethodInterception
{
private readonly LoggerServiceBase _loggerServiceBase;
private static byte _risk;
public ExceptionLogAspect(Type loggerService, byte risk)
{
if (loggerService.BaseType != typeof(LoggerServiceBase))
{
throw new System.Exception(AspectMessages.WrongLoggerType);
}
_loggerServiceBase = (LoggerServiceBase)Activator.CreateInstance(loggerService);
_risk = risk;
}
protected override void OnException(IInvocation invocation, System.Exception e)
{
var logDetailWithException = GetLogDetail(invocation);
logDetailWithException.ExceptionMessage = e.Message;
_loggerServiceBase.Error(logDetailWithException);
}
}
This Aspect migrates MethodInterception class that I created with Castle.DinamicProxy package. And OnException method included by MethodInterception logs the exception data.
public abstract class MethodInterception:MethodInterceptionBaseAttribute
{
protected virtual void OnBefore(IInvocation invocation){}
protected virtual void OnAfter(IInvocation invocation){}
protected virtual void OnException(IInvocation invocation, System.Exception e){}
protected virtual void OnSuccess(IInvocation invocation){}
public override void Intercept(IInvocation invocation)
{
var isSuccess = true;
OnBefore(invocation);
try
{
invocation.Proceed();//Business Method works here.
}
catch (Exception e)
{
isSuccess = false;
OnException(invocation, e);
throw;
}
finally
{
if(isSuccess)
OnSuccess(invocation);
}
OnAfter(invocation);
}
}
When I run the code and try-catch block doesn't work for Exception. So catch block isn't called and no messages are logged.
If I turn the business method into a syncronous method, exception will be thrown and data will be logged.
How can I solve this asynchronous method problem?
I tried this solution, it works properly.
Intercept method has to be like this to make this process asynchronous.
Otherwise, this method doesn't work properly for async.
There are some other ways, for example Castle CoreAsync Interceptor, you can find it on Github or NuGet.
https://github.com/JSkimming/Castle.Core.AsyncInterceptor
public override void Intercept(IInvocation invocation)
{
var isSuccess = true;
OnBefore(invocation);
try
{
invocation.Proceed(); //Metodu çalıştır
if (invocation.ReturnValue is Task returnValueTask)
{
returnValueTask.GetAwaiter().GetResult();
}
if (invocation.ReturnValue is Task task && task.Exception != null)
{
throw task.Exception;
}
}
catch (Exception e)
{
isSuccess = false;
OnException(invocation, e);
throw;
}
finally
{
if (isSuccess)
OnSuccess(invocation);
}
OnAfter(invocation);
}

Quarkus ExceptionMapper does not handle WebApplicationException

I'm trying to understand if this is a feature or a bug... :-)
For the below controller and exception mapper, for a rest client that will fail with a 401 response, I would expect the exception handler to be invoked for both cases. However it's not invoked for the WebApplicationException. Why is that and how are you meant to register an exception handler for them cases. This is using Quarkus version 0.21.2
#Path("/failable")
public class FailableResource {
#Inject
#RestClient
private SomeHttpClient httpClient;
#GET
#Path("fails")
#Produces(MediaType.TEXT_PLAIN)
public String fails() {
try {
return httpClient.someQuery();
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
#GET
#Path("works")
#Produces(MediaType.TEXT_PLAIN)
public String works() {
try {
return httpClient.someQuery();
} catch (Exception e) {
e.printStackTrace();
throw new IllegalStateException("Not a WebApplicationException");
}
}
}
And the ExceptionMapper
#Provider
public class HandleMySillyError implements ExceptionMapper<Throwable> {
#Override
public Response toResponse(Throwable e) {
e.printStackTrace();
return Response.ok("Some handled response").build();
}
}
I found out when running in quarkus:dev mode the exception mapper is not invoked. It seems that this is caused by an exception mapper from quarkus that is only used in DEV mode (see https://github.com/quarkusio/quarkus/issues/7883).
I launched my code local as normal a normal java program, causing my exception handler to work as expected. Also when running the code on Openshift, my custom exception mapper is used as well.
note: I used quarkus version 1.8.3

how to solve Test run failed: Instrumentation run failed due to 'Native crash' in robotium

I am trying JUnit test but facing following issue.
When I select Android JUnit Test by right clicking on Project it shows following message
Test run failed: Instrumentation run failed due to 'Native crash'
and when I right click on TestApk.java and select Android JUnit Test, it shows
Test run failed: Instrumentation run failed due to java.lang.ClassNotFoundException
Two cases occurs
Here is my source code.
#SuppressWarnings("unchecked")
public class TestApk extends ActivityInstrumentationTestCase2 {
private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.nhn.android.ndrive";
private static Class launcherActivityClass;
static {
try {
launcherActivityClass = Class
.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public TestApk() throws ClassNotFoundException {
super(launcherActivityClass);
}
private Solo solo;
#Override
protected void setUp() throws Exception {
super.setUp();
solo = new Solo(getInstrumentation(), getActivity());
}
public void testDisplayBlackBox() {
//Enter any integer/decimal value for first editfield, we are writing 10
solo.clickOnWebElement(By.id("com.nhn.android.ndrive:id/actionbar_photo_left_button"));
solo.clickOnWebElement(By.id("com.nhn.android.ndrive:id/gnb_group_layout"));
//Enter any integer/decimal value for first editfield, we are writing 20
solo.clickOnWebElement(By.id("com.nhn.android.ndrive:id/actionbar_open_drawer_button"));
//Click on Multiply button
solo.clickOnButton("com.nhn.android.ndrive:id/base_menu_task_open_button");
//Verify that resultant of 10 x 20
//assertTrue(solo.searchText("200"));
}
#Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
}
but package name is not wrong.
how to solve this problem?

Mocking the static method with Mockito

I am trying to mock static method using powermock.
Below is my code:
public class Helper{
public static User getLoggedInUser(HttpServletRequest request) throws NotFoundException {
String access = request.getHeader("Authorization");
if(access == null || access.isEmpty()) {
throw new Exception("Access is null");
}
User user = new User();
return user;
}
}
And this is the controller function from where i am calling the static method getUser:
#RequestMapping(value = "user/userInfo/{Id}", method = RequestMethod.GET, headers = "Accept=application/json")
public #ResponseBody
ResultDTO getUser(#PathVariable("Id") Integer Id, HttpServletRequest request) throws NotFoundException, UnauthorizedException {
Integer userID = -1;
User user = Helper.getLoggedInUser(request);
if(user != null){
userID = user.getUserId();
}
//do something
}
And this is my test class:
//#RunWith(PowerMockRunner.class)
//#PrepareForTest(Helper.class)
public class CustomerControllerNGTest {
#InjectMocks
private userController instance = new PaymentCustomerController();
public PaymentCustomerControllerNGTest() {
}
#BeforeClass
public void setUpClass() throws Exception {
}
#AfterClass
public static void tearDownClass() throws Exception {
}
#BeforeMethod
public void setUpMethod() throws Exception {
try{
MockitoAnnotations.initMocks(this);
}catch(Exception ex){
System.out.println(ex.getMessage());
}
try{
mockMvc = MockMvcBuilders.standaloneSetup(instance).build();
// mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}catch(Exception ex){
System.out.println(ex.getMessage());
}
}
#AfterMethod
public void tearDownMethod() throws Exception {
}
#Test
public void testGetUserInfo() throws Exception {
User user = new User();
user.setUserId(1234);
HttpServletRequest request = mock(HttpServletRequest.class);
//this is for the static method
PowerMockito.mockStatic(Helper.class);
**PowerMockito.when(Helper.getLoggedInUser(request)).thenReturn(user);**
//do something
}
}
Now whenever i am executing the test case, and whenever it is executing the lone marked with bold, it is going inside the static method and throwing the exception "Access is null" rather than mocking the method , it is executing the method. Any idea?
I also tried by uncommenting these lines:
//#RunWith(PowerMockRunner.class)
//#PrepareForTest(Helper.class)
but still same exception.
Thanks
Try to uncomment:
//#RunWith(PowerMockRunner.class)
//#PrepareForTest(Helper.class)
and use
Mockito.when(Helper.getLoggedInUser(request)).thenReturn(user);
I wrote blog post on topic, that contain links to working examples on GitHub. These use TestNg instead of JUnit, but this shouldn't matter.
EDIT
I would suggest to always use latest combination of Mockito and PowerMock available. Older combinations were often pretty buggy with confusing errors. Current latest combination is Mockito 1.9.5-rc1+, PowerMock 1.5+. Pre-1.5 versions of PowerMock wasn't Java7 compliant.