why i can't run my test cases in ServiceTestCase? - android

Here's my service test code.
public class BackgroundTaskServiceTest extends ServiceTestCase<BackgroundTaskService> {
public BackgroundTaskServiceTest(Class<BackgroundTaskService> serviceClass) {
super(serviceClass);
}
public BackgroundTaskServiceTest() {
super(BackgroundTaskService.class);
}
#SmallTest
public void startServiceTest() {
assertEquals(0, 1);
}
#Override
public void setUp() {
try {
super.setUp();
System.err.println("setup called");
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void tearDown() {
try {
System.err.println("teardown called");
super.tearDown();
} catch (Exception e) {
e.printStackTrace();
}
}
}
I right-click the project name and select "Run as Android Junit Test". The setUp and tearDown callbacks are called properly , but my startServiceTest is never run.
This is the screen shot of test results:
And another strange thing is that the "setup called" and "teardown called" both appear twice.
So anyone knows why? Thanks.

I think the way that the ADT plugin for Android JUnit works, you need to name your tests starting with 'test', e.g.:
public void testStartService() {
assertEquals(0, 1);
}
Try that and see if it runs.

Related

Debugger not stoping at breakpoint in RxJava for Android

The Log.d(...) expression in the catch(...) block below gets executed (I can see the log output in Android Studio), but the debugger won't stop at the breakpoint set at that very same line. Why is that? The debugger stops at other breakpoints.
Observable.create(new Observable.OnSubscribe<MobileBankIdSessionResponse.MobileBankIdSession>() {
#Override
public void call(final Subscriber<? super MobileBankIdSessionResponse.MobileBankIdSession> subscriber) {
Schedulers.newThread().createWorker().schedule(new Action0() {
#Override
public void call() {
try {
MobileBankIdSessionResponse r = User.getMobileBankIdSession(reference, nationalIdentity).toBlocking().first();
String progressCode = r.getResponse().progress.progressCode;
if (StringUtils.equals(progressCode, "COMPLETE")) {
subscriber.onNext(r.getResponse());
subscriber.onCompleted();
} else if (StringUtils.equals(progressCode, "USER_SIGN")
|| StringUtils.equals(progressCode, "OUTSTANDING_TRANSACTION")) {
Schedulers.newThread().createWorker().schedule(this, 2, TimeUnit.SECONDS);
} else if (StringUtils.equals(progressCode, "NO_CLIENT")) {
subscriber.onError(new Throwable("Fel vid signering"));
}
} catch (Exception e) {
Log.d("AtError", "here");
subscriber.onError(e);
}
}
});
}
}).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<MobileBankIdSessionResponse.MobileBankIdSession>() {
#Override
public void onCompleted() {}
#Override
public void onError(Throwable throwable) {
mUserLoggedInOutSubject.onNext(Pair.create(throwable.getMessage(), LoginStates.ERROR));
}
#Override
public void onNext(MobileBankIdSessionResponse.MobileBankIdSession mobileBankIdSession) {
setSession(mobileBankIdSession.session, nationalIdentity);
}
});
To anyone who came here for answer, It is possible you have not called .subscribe(e ->{}); on the Single ,Flowable etc Object you are using.

Android - If I try a function, will I catch NullPointerExceptions?

Can I do this:
try {
loadItem();
} catch (NullPointerException e) {
Toast.makeText(getActivity(),"Sorry, we couldn't load that item. Please try again",Toast.LENGTH_SHORT).show();
}
And catch any NullPointerExceptions that might occur in loadItem()?
Yes. Unless loadItem() itself catches the exception without rethrowing, it will bubble up to the caller.
You can test this out with the following program, which outputs Ouch! due to the exception handler kicking in:
public class DodgyProg {
public static void loadItem() {
throw new NullPointerException();
}
public static void main(String []args){
try {
loadItem();
} catch (NullPointerException e) {
System.out.println("Ouch!");
}
}
}

Correct way to take screenshot with Robotium and Cucumber

Which is the best way to take a screenshot when one scenario fails using Robotium and Cucumber?
I have tried (without success, because it doesn't execute runTest method) with this:
import cucumber.api.CucumberOptions;
import cucumber.api.java.After;
import cucumber.api.java.Before;
#CucumberOptions(features = "features", tags = {"~#ignore"})
public class CustomInstrumentationTestCase extends ActivityInstrumentationTestCase2<LaunchActivity> {
protected Solo solo;
public CustomInstrumentationTestCase() {
super(LaunchActivity.class);
}
#Before
public void before() throws Exception {
//...
}
#After
public void after() throws Exception {
//...
}
#Override
protected void runTest() throws Throwable {
try {
super.runTest();
} catch (Throwable t) {
final String testCaseName = String.format("%s.%s", getClass().getName(), getName());
solo.takeScreenshot(testCaseName);
Log.w("Boom! Screenshot!", String.format("Captured screenshot for failed test: %s", testCaseName));
throw t;
}
}
}
And I have set the permissions in the manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Your testclass seems fine. The runTest() methode is used to catch errors and failures and as a result make a screenshot.
To your class simply add a test like this:
public void testFailsForScreenShot(){
fail();
}
Than run the test and you will find a screenshot.
Greetings
EDIT: Test for Screenshot:
import android.util.Log;
import com.robotium.solo.Solo;
public class TestScreenshot extends ActivityInstrumentationTestCase2<LauncherActivity> {
private Solo solo;
public TestScreenshot(){
super(LauncherActivity.class);
}
#Override
protected void setUp() throws Exception {
super.setUp();
solo = new Solo(getInstrumentation(), getActivity());
}
//Test if "Test" fails and takes Screenshot
public void testFailForScreenshot(){
fail();
}
#Override
public void runTest() throws Throwable {
try {
super.runTest();
} catch (Throwable t) {
String testCaseName = String.format("%s.%s", getClass().getName(), getName());
solo.takeScreenshot(testCaseName);
Log.w("Screenshot taken.", String.format("Captured screenshot for failed test: %s", testCaseName));
throw t;
}
}

Can RxJavaErrorHandler prevent an error from crashing the Android app?

I'm trying to suppress an error with RX plugin, but the app is still crashing. Am I doing anything wrong or plugin error handler is just for reporting and cannot prevent the crash?
public void testClick(View view) {
RxJavaPlugins.getInstance().registerErrorHandler(new RxJavaErrorHandler() {
#Override
public void handleError(Throwable e) {
e.printStackTrace();
}
});
final PublishSubject<Integer> hot = PublishSubject.create();
hot
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Integer>() {
#Override
public void call(Integer value) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.info("Result");
}
});
Observable.range(0, 100).subscribe(hot);
}
If you look at _onError method in SafeSubscriber class you'll find :
try {
RxJavaPlugins.getInstance().getErrorHandler().handleError(e);
} catch (Throwable pluginException) {
handlePluginException(pluginException);
}
try {
actual.onError(e);
} catch {
...
}
You can see that RxJavaPlugins ErrorHandler doesn't affect further error processing and it should be used to log/report errors

How to test assert throws exception in Android

is there a more elegant way to do an assert throws exception in Android then this?
public void testGetNonExistingKey() {
try {
alarm.getValue("NotExistingValue");
fail( );
} catch (ElementNotFoundException e) {
}
}
Something like this does not work?!
#Test(expected=ElementNotFoundException .class)
Thanks, Mark
Are you using a junit4 test runner? The #Test annotation won't work if you're running a junit3 test runner. Check the version that you're using.
Secondly, the recommended way to check for exceptions in your code is to use a Rule (introduced in junit 4.7).
#Rule
public ExpectedException exception = ExpectedException.none();
#Test
public void throwsIllegalArgumentExceptionIfIconIsNull() {
// do something
exception.expect(IllegalArgumentException.class);
exception.expectMessage("Icon is null, not a file, or doesn't exist.");
new DigitalAssetManager(null, null);
}
You can continue to use the #Test(expected=IOException.class), but the above has the advantage that if an exception is thrown before the exception.expect is called, then the test will fail.
I did something very similar to hopia's answer with a couple of improvements. I made it return the exception object so that you can check its message or any other properties, and I declared a Testable interface to replace Runnable because Runnable doesn't let your code under test throw checked exceptions.
public interface Testable {
public void run() throws Exception;
}
public <T extends Exception> T assertThrows(
final Class<T> expected,
final Testable codeUnderTest) throws Exception {
T result = null;
try {
codeUnderTest.run();
fail("Expecting exception but none was thrown.");
} catch(final Exception actual) {
if (expected.isInstance(actual)) {
result = expected.cast(actual);
}
else {
throw actual;
}
}
return result;
}
Here's an example of calling it.
InvalidWordException ex = assertThrows(
InvalidWordException.class,
new Testable() {
#Override
public void run() throws Exception {
model.makeWord("FORG", player2);
}
});
assertEquals(
"message",
"FORG is not in the dictionary.",
ex.getMessage());
If you're using Kotlin, you can take advantage of reified types to avoid passing the Exception subclass as an argument:
inline fun <reified T : Exception> assertThrows(runnable: () -> Any?) {
try {
runnable.invoke()
} catch (e: Throwable) {
if (e is T) {
return
}
Assert.fail("expected ${T::class.qualifiedName} but caught " +
"${e::class.qualifiedName} instead")
}
Assert.fail("expected ${T::class.qualifiedName}")
}
#Test
fun exampleTest() {
val a = arrayOf(1, 2, 3)
assertThrows<IndexOutOfBoundsException> {
a[5]
}
}
This is how I do it. I create a static method called assertThrowsException that takes in as arguments an expected exception class and a Runnable which contains the code under test.
import junit.framework.Assert;
public SpecialAsserts {
public void assertThrowsException(final Class<? extends Exception> expected, final Runnable codeUnderTest) {
try {
codeUnderTest.run();
Assert.fail("Expecting exception but none was thrown.");
} catch(final Throwable result) {
if (!expected.isInstance(result)) {
Assert.fail("Exception was thrown was unexpected.");
}
}
}
}
This is the sample code to use the special assert in your test class (that extends AndroidTestCase or one of its derivatives):
public void testShouldThrowInvalidParameterException() {
SpecialAsserts.assertThrowsException(InvalidParameterException.class, new Runnable() {
public void run() {
callFuncThatShouldThrow();
}
});
}
Yes, there's a lot of work, but it's better than porting junit4 to android.
With junit3 the following might help.
public static void assertThrows(Class<? extends Throwable> expected,
Runnable runnable) {
try {
runnable.run();
} catch (Throwable t) {
if (!expected.isInstance(t)) {
Assert.fail("Unexpected Throwable thrown.");
}
return;
}
Assert.fail("Expecting thrown Throwable but none thrown.");
}
public static void assertNoThrow(Runnable runnable) {
try {
runnable.run();
} catch (Throwable t) {
Assert.fail("Throwable was unexpectedly thrown.");
}
}

Categories

Resources