I created a simple project to launch facebook app on emulator. When the program is run the following error is displayed
Test run failed: Instrumentation run failed due to 'java.lang.ClassNotFoundException
The code is fb.java file
package com.facebook.katana;
import junit.framework.Assert;
import com.jayway.android.robotium.solo.Solo;
//import junit.framework.Assert;
import android.test.ActivityInstrumentationTestCase2;
#SuppressWarnings("rawtypes")
public class fb extends ActivityInstrumentationTestCase2{
private Solo solo;
private static final String TARGET_PACKAGE_ID ="com.facebook.katana";
private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.facebook.katana.LoginActivity";
private static Class<?> launcherActivityClass;
static{
try{
launcherActivityClass = Class.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
} catch(ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
#SuppressWarnings({ "unchecked", "deprecation" })
public fb() {
super(TARGET_PACKAGE_ID, launcherActivityClass);
// TODO Auto-generated constructor stub
}
#Override
protected void setUp() throws Exception{
solo = new Solo(getInstrumentation(), getActivity());
}
public void testCanOpenSettings() throws InterruptedException{
// wait for the specified time
solo.sleep(3000);
solo.clearEditText(0);
solo.enterText(0, "abc#abc");
// wait for the specified time
solo.sleep(3000);
solo.enterText(1, "acd");
solo.sleep(3000);
}
private boolean assertTrue(Object clickOnImage) {
// TODO Auto-generated method stub
return false;
}
#Override
public void tearDown() throws Exception{
try{
solo.finalize();
} catch(Throwable e) {
e.printStackTrace();
}
getActivity().finish();
super.tearDown();
}
}
The manifest. xml file (FB2 Manifest.xml)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.facebook.katana.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="18" />
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.facebook.katana" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<uses-library android:name="android.test.runner" />
</application>
</manifest>
Please help in resolving this issue
The LAUNCHER ACTIVITY FULL CLASS NAME specified was incorrect.
Once this was set to the correct activity name, the program execution was successful.
Related
I'm trying to add Screenshots of the failed test case to the testNG report and I don't have any idea about it
This is my pom class for getting screenshot
package library;
import java.awt.AWTException;
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
public class TakeScreenShot {
WebDriver driver;
public TakeScreenShot(WebDriver driver) {
this.driver=driver;
}
public void CaptureScreenshot(String screenshotName) throws AWTException
{
try {
TakesScreenshot ts=(TakesScreenshot)driver;
File source=ts.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(source, new File("C:\\Users\\Documents\\Eclipse\\WorkSpace\\ScreenShot\\"+screenshotName));
System.out.println("Screenshot taken");
} catch (Exception e) {
System.out.println("Exception "+e.getMessage());
}
}
}
And this is my TestNG class
#AfterMethod
public void CloseBrowser(ITestResult result) throws AWTException {
String name=result.getName()+"."+result.getMethod().getCurrentInvocationCount()+".png";
if(ITestResult.FAILURE==result.getStatus())
{
ScreenshotPageObjectModel screenshotPom= new ScreenshotPageObjectModel(driver);
screenshotPom.CaptureScreenshot(name);
}
driver.close();
}
Thanks for helping and please mention where should I do changes for adding the screenshot in the report
You need to use ITestListeners interface of TestNg, it basically provide 7 methods, those are :
onTestStart(ITestResult result)
onTestFailure(ITestResult result)
onTestSuccess(ITestResult result)
onTestSkipped(ITestResult result)
onTestFailedButWithinSuccessPercentage(ITestResult result)
onStart(ITestContext context)
onFinish(ITestContext context)
Your requirement here is "take screen shot of failed test cases/methods".You should use onTestFailure(ITestResult result) methods.
Demonstration :
public class TestListener implements ITestListener {
WebDriver driver=null;
String filePath = "D:\\SCREENSHOTS";
#Override
public void onTestFailure(ITestResult result) {
System.out.println("***** Error "+result.getName()+" test has failed *****");
String methodName=result.getName().toString().trim();
takeScreenShot(methodName);
}
public void takeScreenShot(String methodName) {
//get the driver
driver=TestBase.getDriver();
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
//The below method will save the screen shot in d drive with test method name
try {
FileUtils.copyFile(scrFile, new File(filePath+methodName+".png"));
System.out.println("***Placed screen shot in "+filePath+" ***");
} catch (IOException e) {
e.printStackTrace();
}
}
public void onFinish(ITestContext context) {}
public void onTestStart(ITestResult result) { }
public void onTestSuccess(ITestResult result) { }
public void onTestSkipped(ITestResult result) { }
public void onTestFailedButWithinSuccessPercentage(ITestResult result) { }
public void onStart(ITestContext context) { }
}
You need to add this tag to your XML file:
<listeners>
<listener class-name="com.pack.listeners.TestListener"/>
</listeners>
To get screen shot use this method:
public static void takeSnapShot(WebDriver driver, String fileWithPath) throws Exception {
TakesScreenshot scrShot = (TakesScreenshot)driver;
File SrcFile = (File)scrShot.getScreenshotAs(OutputType.FILE);
File DestFile = new File(fileWithPath);
FileUtils.copyFile(SrcFile, DestFile);
}
You can call the screen shot under TestNG using below code:
#AfterMethod(
alwaysRun = true
)
protected void afterMethod(ITestResult result, Method method) throws Exception {
// boolean testStatus = false;
String fileName = "FAIL - Error Message Generated on Details Reports";
byte testStatus;
if (result.getStatus() == 2) {
fileName = System.getProperty("user.dir") + "\\Reports\\failure_screenshots\\" + ".png";
takeSnapShot(this.driver, fileName);
ExtentTestManager.getTest().log(LogStatus.FAIL, "Error Screenshot" + ExtentTestManager.getTest().addScreenCapture("failure_screenshots\\" + ".png"));
ExtentTestManager.getTest().log(LogStatus.FAIL, "Test Failed");
testStatus = 2;
} else {
ExtentTestManager.getTest().log(LogStatus.PASS, "Test passed");
testStatus = 1;
}
Ref-> https://www.softwaretestingmaterial.com/screenshots-extent-reports/
http://automationtesting.in/capture-screenshot-in-extent-reports-java/
Hope this helps!!!
PS- Use the most stable extent report version - 2.41.1
I suggest to use ReportNG instead of the TestNG premitive report.
I am currently rewriting the automated testing framework for my company's mobile testing. We are attempting to use an interface which is implemented by multiple Page Object Models dependent on the Operating System of the mobile device the application is being run on. I can get this framework to run sequentially and even create multiple threads but it will not run in parallel no matter what I do. Of Note, we use Appium and something called the DeviceCart/DeviceConnect which allows me to physically remote into multiple devices, thus this isn't running on a grid. With that said I will link my pertinent code (this is my second version of this same code, I wrote one with and one without using ThreadLocal)
This should instantiate a new driver with a new thread for each Test
public class TLDriverFactory {
private ThreadLocal < AppiumDriver < MobileElement >> tlDriver = new ThreadLocal <>();
public synchronized void setTLDriver(OS platform, String server, String udid, String bundleID) {
switch (platform) {
case IOS:
tlDriver = ThreadLocal.withInitial(() -> {
try {
return new IOSDriver < MobileElement > (new URL(server), DesiredCapsManager.getDesiredCapabilities(OS.IOS, udid, bundleID));
} catch(MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
});
break;
case ANDROID:
tlDriver = ThreadLocal.withInitial(() -> {
try {
return new AndroidDriver < MobileElement > (new URL(server), DesiredCapsManager.getDesiredCapabilities(OS.ANDROID, udid, bundleID));
} catch(MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
});
break;
default:
break;
}
}
public synchronized ThreadLocal < AppiumDriver < MobileElement >> getTLDriver() {
return tlDriver;
}
}
This handles browser capbilities
public class DesiredCapsManager {
public static DesiredCapabilities getDesiredCapabilities(OS platform, String udid, String bundleID) {
//Set DesiredCapabilities
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("deviceConnectUserName", "User#Name.com");
capabilities.setCapability("deviceConnectApiKey", "API-Token-Here");
capabilities.setCapability("udid", udid);
capabilities.setCapability("platformName", platform);
capabilities.setCapability("bundleID", bundleID);
//IOS only Settings
if (platform.equals(OS.IOS)) {
capabilities.setCapability("automationName", "XCUITest");
}
else {
//Android only Settings
capabilities.setCapability("automationName", "appium");
}
return capabilities;
}
}
This is the Base Test class from which every test inherits
public class BaseTest {
protected AppiumDriver < MobileElement > driver;
protected AppiumSupport.TLDriverFactory TLDriverFactory = new AppiumSupport.TLDriverFactory();
public enum OS {
ANDROID,
IOS
}
#AfterMethod
public synchronized void tearDown() throws Exception {
driver.quit();
TLDriverFactory.getTLDriver().remove();
}
}
Here is the test case itself
public class Test_SignIn extends BaseTest {
protected SignInPage signInPage;
#Parameters(value = {
"udid",
"bundleID",
"platform",
"server"
})
#BeforeMethod
public void setup(String udid, String bundleID, OS platform, String server) throws MalformedURLException,
InterruptedException {
//Set & Get ThreadLocal Driver
TLDriverFactory.setTLDriver(platform, server, udid, bundleID);
driver = TLDriverFactory.getTLDriver().get();
Thread.sleep(5000);
switch (platform) {
case IOS:
signInPage = new SignInPageIOS(driver);
break;
case ANDROID:
signInPage = new SignInPageAndroid(driver);
break;
default:
break;
}
System.out.println("Current Thread ID BeforeTest: " + Thread.currentThread().getName());
}
#Test
public synchronized void Authenticate() throws Exception {
System.out.println("Current Thread ID Test 1: " + Thread.currentThread().getName());
signInPage.Login("Username", "Password");
}
}
Here is the testng.xml file
< !DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Test" parallel="tests" thread-count="4">
<test name="SignIn" parallel ="instances" thread-count="2">
<parameter name="udid" value="DeviceIdGoesHere" />
<parameter name="bundleID" value="Environment.address.here" />
<parameter name="platform" value="ANDROID" />
<parameter name="server" value="http://deviceconnect/appium" />
<classes>
<class name="Test.Test_SignIn">
</class>
</classes>
</test>
<test name="SignIn2" parallel="instances" thread-count="2">
<parameter name="udid" value="DeviceIdGoesHere" />
<parameter name="bundleID" value="Environment.address.here" />
<parameter name="platform" value="IOS" />
<parameter name="server" value="http://deviceconnect/appium" />
<classes>
<class name="Test.Test_SignIn">
</class>
</classes>
</test>
</suite>
What I'm looking for is if anyone can determine what mistake I've made or what the bottleneck is preventing the tests from running in parallel
Based on what you have shared so far, here's the cleaned-up and fixed code that should support your concurrency requirements.
The Driver factory class which is responsible for creation and clean-up of Appium driver instances for each and every thread, looks like below:
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.ios.IOSDriver;
import java.net.MalformedURLException;
import java.net.URL;
public class TLDriverFactory {
private static final ThreadLocal<AppiumDriver<MobileElement>> tlDriver = new ThreadLocal<>();
public static void setTLDriver(BaseTest.OS platform, String server, String udid, String bundleID) throws MalformedURLException {
System.out.println("Current Thread ID Driver Instantiation: " + Thread.currentThread().getName());
AppiumDriver<MobileElement> driver;
switch (platform) {
case IOS:
driver = new IOSDriver<>(new URL(server), DesiredCapsManager.getDesiredCapabilities(BaseTest.OS.IOS, udid, bundleID));
break;
default:
driver = new AndroidDriver<>(new URL(server), DesiredCapsManager.getDesiredCapabilities(BaseTest.OS.ANDROID, udid, bundleID));
break;
}
tlDriver.set(driver);
}
public static AppiumDriver<MobileElement> getTLDriver() {
return tlDriver.get();
}
public static void cleanupTLDriver() {
tlDriver.get().quit();
tlDriver.remove();
}
}
Here's how the BaseTest which I am guessing is supposed to be the base class for all tests, would look like
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;
public class BaseTest {
private static final ThreadLocal<SignInPage> signInPage = new ThreadLocal<>();
public enum OS {
ANDROID,
IOS
}
#Parameters(value = {"udid", "bundleID", "platform", "server"})
#BeforeMethod
public void setup(String udid, String bundleID, OS platform, String server) throws Exception {
//Set & Get ThreadLocal Driver
TLDriverFactory.setTLDriver(platform, server, udid, bundleID);
Thread.sleep(5000);
SignInPage instance;
switch (platform) {
case IOS:
instance = new SignInPageIOS(TLDriverFactory.getTLDriver());
break;
default:
instance = new SignInPageAndroid(TLDriverFactory.getTLDriver());
break;
}
System.out.println("Current Thread ID BeforeTest: " + Thread.currentThread().getName());
signInPage.set(instance);
}
#AfterMethod
public void tearDown() {
System.out.println("Current Thread ID AfterTest: " + Thread.currentThread().getName());
TLDriverFactory.cleanupTLDriver();
}
protected static SignInPage getPageForTest() {
return signInPage.get();
}
}
Here's how the constructor of your page classes would look like
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;
public class SignInPageIOS extends SignInPage {
public SignInPageIOS(AppiumDriver<MobileElement> tlDriver) {
super(tlDriver);
}
}
Here's how a typical test case could look like
import org.testng.annotations.Test;
public class Test_SignIn extends BaseTest {
#Test
public void authenticate() {
//Get the instance of "SignInPage" for the current thread and then work with it.
getPageForTest().Login("Username", "Password");
}
}
I'm new in Android Development. I reviewed the automatic click button post before but I still cannot configure the these error. The App Stop Working after 5 secs timer.
Below is my code on MainActivity:
package com.example.cynog.autobutton;
import android.content.Intent;
import android.content.res.Resources;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
private Button button1;
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
performClick();
Thread timer = new Thread(){
public void run(){
try{
sleep(5000);
} catch (InterruptedException e){
e.printStackTrace();
}finally{
button1.performClick();
}
}
};
timer.start();
} catch (Resources.NotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void performClick() {
button1 = (Button) findViewById(R.id.button);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this, activity.class);
startActivity(i);
}
});
}
}
And This is my XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.cynog.autobutton.MainActivity">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:onClick="performClick"
tools:layout_editor_absoluteX="153dp"
tools:layout_editor_absoluteY="209dp" />
</android.support.constraint.ConstraintLayout>
Button is created in the ui thread that is main thread.
so if u want to make any action with it do it inside handler.post(new Runnable(){void run(){//perform action here}. make a Handler object in oncreate(). Handler handler=new Handler().
and put the handler.post() code in the timer thread run method after sleep. I hope it works.
I am using testNG 6.9.10 that installed in Eclipse.
I was trying to use retry to make sure the failed tests could run maxcount times that defined.
See below codes.
public class TestRetry implements IRetryAnalyzer {
private int retryCount = 0;
private int maxRetryCount = 1;
public boolean retry(ITestResult result) {
if (retryCount < maxRetryCount) {
retryCount++;
return true;
}
return false;
}
#Test(retryAnalyzer = TestRetry.class)
public void testGenX() {
Assert.assertEquals("google", "google");
}
#Test(retryAnalyzer = TestRetry.class)
public void testGenY() {
Assert.assertEquals("hello", "hallo");
}
}
I got below result:
===============================================
Default test
Tests run: 3, Failures: 1, Skips: 1
===============================================
===============================================
Default suite
Total tests run: 3, Failures: 1, Skips: 1
===============================================
But seems like the result count with some problems. I want below:
===============================================
Default test
Tests run: 2, Failures: 1, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 2, Failures: 1, Skips: 0
===============================================
I tried to defined the listeners to implement it, something like to override the onFinish function. You may find it in http://www.seleniumeasy.com/testng-tutorials/retry-listener-failed-tests-count-update
But finally not works.
can someone who had met this could help?
Its working fine, i hope there is some problem on listener usage. I created TestRetry as same like you but with out #Test methods.
public class TestRetry implements IRetryAnalyzer{
private int retryCount = 0;
private int maxRetryCount = 1;
#Override
public boolean retry(ITestResult arg0) {
// TODO Auto-generated method stub
if (retryCount < maxRetryCount) {
retryCount++;
return true;
}
return false;
}
}
Created Listener class
public class TestListener implements ITestListener{
#Override
public void onFinish(ITestContext context) {
// TODO Auto-generated method stub
Set<ITestResult> failedTests = context.getFailedTests().getAllResults();
for (ITestResult temp : failedTests) {
ITestNGMethod method = temp.getMethod();
if (context.getFailedTests().getResults(method).size() > 1) {
failedTests.remove(temp);
} else {
if (context.getPassedTests().getResults(method).size() > 0) {
failedTests.remove(temp);
}
}
}
}
#Override
public void onStart(ITestContext arg0) {
// TODO Auto-generated method stub
}
#Override
public void onTestFailedButWithinSuccessPercentage(ITestResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onTestFailure(ITestResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onTestSkipped(ITestResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onTestStart(ITestResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onTestSuccess(ITestResult arg0) {
// TODO Auto-generated method stub
}
}
Finally my test class with those methods
public class RunTest {
#Test(retryAnalyzer = TestRetry.class)
public void testGenX() {
Assert.assertEquals("google", "google");
}
#Test(retryAnalyzer = TestRetry.class)
public void testGenY() {
Assert.assertEquals("hello", "hallo");
}
}
Executed this RunTest from testng.xml file by specifying the my custom listener
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite1" parallel="false" preserve-order="true">
<listeners>
<listener class-name="com.test.TestListener"/>
</listeners>
<test name="TestA">
<classes>
<class name="com.test.RunTest"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Please have a try..
Thank You,
Murali
#murali could please see my codes below? I really cannot see any difference.
The CustomLinstener.java
package cases;
import java.util.Set;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
public class CustomLinstener implements ITestListener{
#Override
public void onFinish(ITestContext context) {
Set<ITestResult> failedTests = context.getFailedTests().getAllResults();
for (ITestResult temp : failedTests) {
ITestNGMethod method = temp.getMethod();
if (context.getFailedTests().getResults(method).size() > 1) {
failedTests.remove(temp);
} else {
if (context.getPassedTests().getResults(method).size() > 0) {
failedTests.remove(temp);
}
}
}
}
#Override
public void onStart(ITestContext arg0) {
// TODO Auto-generated method stub
}
#Override
public void onTestFailedButWithinSuccessPercentage(ITestResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onTestFailure(ITestResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onTestSkipped(ITestResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onTestStart(ITestResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onTestSuccess(ITestResult arg0) {
// TODO Auto-generated method stub
}
}
The RunTest.java
package cases;
import org.testng.Assert;
import org.testng.annotations.Test;
public class RunTest {
#Test(retryAnalyzer = TestRetry.class)
public void testGenX() {
Assert.assertEquals("google", "google");
}
#Test(retryAnalyzer = TestRetry.class)
public void testGenY() {
Assert.assertEquals("hello", "hallo");
}
}
The TestRetry.java
package cases;
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
public class TestRetry implements IRetryAnalyzer{
private int retryCount = 0;
private int maxRetryCount = 1;
#Override
public boolean retry(ITestResult arg0) {
// TODO Auto-generated method stub
if (retryCount < maxRetryCount) {
retryCount++;
return true;
}
return false;
}
}
Finally the XML. I right click it and run as the testNG suite.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite1" parallel="false" preserve-order="true">
<test name="TestA">
<classes>
<class name="cases.RunTest" />
</classes>
</test> <!-- Test -->
<listeners>
<listener class-name="cases.CustomLinstener" />
</listeners>
</suite> <!-- Suite -->
The documentation for TestNG's IRetryAnalyzer does not specify test reporting behavior:
Interface to implement to be able to have a chance to retry a failed test.
There are no mention of "retries" on http://testng.org/doc/documentation-main.html and searching across the entire testng.org site only returns links to the documentation of and references to IRetryAnalyzer (see site:testng.org retry - Google Search).
As there is no documentation for how a retried test is reported we cannot make many sound expectations. Should each attempt appear in the test results? If so, is each attempt except for the last attempt marked as a skip and the last as either a success or a failure? It isn't documented. The behavior is undefined and it could change with any TestNG release in subtle or abrupt ways.
As such, I recommend using a tool other than TestNG for retry logic.
e.g. You can Spring Retry (which can be used independently of other Spring projects):
TestRetry.java
public class TestRetry {
private static RetryOperations retryOperations = createRetryOperations();
private static RetryOperations createRetryOperations() {
RetryTemplate retryTemplate = new RetryTemplate();
retryTemplate.setRetryPolicy(createRetryPolicy());
return retryTemplate;
}
private static RetryPolicy createRetryPolicy() {
int maxAttempts = 2;
Map<Class<? extends Throwable>, Boolean> retryableExceptions =
Collections.singletonMap(AssertionError.class, true);
return new SimpleRetryPolicy(maxAttempts, retryableExceptions);
}
#Test
public void testGenX() {
runWithRetries(context -> {
Assert.assertEquals("google", "google");
});
}
#Test
public void testGenY() {
runWithRetries(context -> {
Assert.assertEquals("hello", "hallo");
});
}
private void runWithRetries(RetryRunner<RuntimeException> runner) {
retryOperations.execute(runner);
}
}
RetryRunner.java
/**
* Runner interface for an operation that can be retried using a
* {#link RetryOperations}.
* <p>
* This is simply a convenience interface that extends
* {#link RetryCallback} but assumes a {#code void} return type.
*/
interface RetryRunner<E extends Throwable> extends RetryCallback<Void, E> {
#Override
default Void doWithRetry(RetryContext context) throws E {
runWithRetry(context);
return null;
}
void runWithRetry(RetryContext context) throws E;
}
Console Output
===============================================
Default Suite
Total tests run: 2, Failures: 1, Skips: 0
===============================================
Spring Retry may look slightly more complicated at first but it provides very flexible features and API and enables separation of concerns of the test retry logic and the test reporting.
Here is my code
package com.test.android.calculator2;
import android.app.Activity;
import com.robotium.solo.Solo;
import android.test.ActivityInstrumentationTestCase2;
#SuppressWarnings("unchecked")
public class TestApk extends ActivityInstrumentationTestCase2 {
private static final String TARGET_PACKAGE_ID="com.android.calculator2";
private static final String
LAUNCHER_ACTIVITY_FULL_CLASSNAME="com.android.calculator2.Calculator";
private static Class <?> launcherActivityClass;
static {
try {
Activity act = new Activity();
launcherActivityClass = Class.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
// #SuppressWarnings("unchecked")
public TestApk()throws ClassNotFoundException {
super(TARGET_PACKAGE_ID,launcherActivityClass);
}
private Solo solo;
#Override
protected void setUp() throws Exception {
solo = new Solo(getInstrumentation());
}
public void testCanOpenSettings() {
solo.getActivityMonitor();
getActivity();
solo.sendKey(Solo.DOWN);
solo.goBack();
}
#Override
public void tearDown() throws Exception {
try {
solo.finalize();
} catch (Throwable e) {
e.printStackTrace();
}
getActivity().finish();
super.tearDown();
}
}
Manifest file like this
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.android.calculator2"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="19" />
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.android.calculator2" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<uses-library android:name="android.test.runner" />
</application>
</manifest>
It looks like your defined target package com.android.calculator2 could not be found.
I see that the class you posted is located in the package com.test.android.calculator2
You either have to create a new package com.android.calculator2 or set your target package to a existing package (e.g. com.test.android.calculator2).