[android-developers] Re: Unit Testing - Activity shutdown
Got this all working and reliably. I still use a state variable to tell me where I am in the state machine - not ideal. My reliability problems seem to have been down to using SharedPreferences to hold state between tests. Thanks for the responses. Ian Hunter On Nov 29, 8:10 pm, Ian ian.fawcett.hun...@gmail.com wrote: Thanks for your response - I think this could be enlightening However, a few questions... On Nov 29, 7:30 pm, A. Elk lancaster.dambust...@gmail.com wrote: Can I get clarification here? Does your application call finish() at some point? If so, at what point? The Android design guidelines strongly discourage the use of an exit button. You should see that most apps don't have one. The way to exit an application is to switch to another one (including a phone call) or go to the Launcher/Home. Whenever you switch, the onPause() method for the foreground Activity of your app should be called. Whenever you switch back, the onResume() method should be called. Can you please point me at the guidelines you are referring to? I have seen many references to the finish() method, but nothing discouraging its use. In the API it states... void finish() - Call this when your activity is done and should be closed. In my scenario, the user rejects the Terms Conditions in a dialog - and this seems the ideal thing to do, No? I acknowledge that sometimes you may want to start a child *Activity* and then kill it when you're done with it. To do this, use finishActivity() with a result code. You may also want to start a service when your app starts, but give the user the option to stop the service if it's not being used. That's OK too, but you shouldn't shut down the app itself. In short, the Android model is that you leave the application paused, and let Android destroy it to free up resources. If Android does this, it should always call the onPause() method of any Activities that are still running. Can you describe your test harness in more detail? To unit test an Activity, you shouldn't need anything more than InstrumentationTestRunner and ActivityInstrumentationTestCase2. This is documented under Testing and Instrumentation in the Android 2.2 Developer's Guide. I am using the ActivityInstrumentationTestCase2 as you suggest and calling getActivity() to start the Activity. I then do button.performClick() which causes 'finish()'. I am hoping to reliably test that the Activity has paused, stopped or whatever happens. I have refactored and now have a unit test which (via a state variable) does work, but not reliably - this may be another story :-) Thanks Ian Hunter -- You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en
[android-developers] Re: Unit Testing - Activity shutdown
I'm not sure that the discouragement of exit is in any written guidelines. I just know that exiting applications is both discouraged and unnecessary. I did not say that *finish()* is disallowed. You certainly can use it to close an Activity that is done with its work. It's not normally used for the main Activity of an application, because it's assumed that this Activity is always waiting around for something to do. I can't say more without knowing more about your code. Your design seems to be this: You display Terms and Conditions dialog. If the user does not accept them, you want to go away from the application. I would design this so that the dialog returns to the Activity that called it. That Activity would then call finish(). Leave it up to the user to uninstall the application. You are free to leave the app installed and present (loaded but not doing anything). You shouldn't be having a problem with SharedPreferences. In Android unit tests, it's common for a test method to set up SharedPreferences with the necessary dependencies before running the actual test. If possible, you should put this part of the test into setUp(), so that it's clear that it's part of the fixture. This also isolates the dependency. In a perfect world, the stuff in SharedPreferences would be injected as a mock dependency, but in Android this is not easy to do. Within the scope of a single test method in a test case, however, SharedPreferences should not change. I don't rely on SharedPreferences maintaining its state across tests. In fact, you can run into trouble because of the subtleties of SharedPreferences. It's not totally clear in the documentation, but a single instance of SharedPreferences is shared by all of the instances of an application. In the Android 2.2 documentation, there's a tutorial on Activity testing. It's under the Resources Tab, under Tutorials Activity Testing. The sample test package for that tutorial demonstrates how to test saving preferences when an application is completely stopped using finish() and then re-started. IOn Nov 30, 12:15 am, Ian ian.fawcett.hun...@gmail.com wrote: Got this all working and reliably. I still use a state variable to tell me where I am in the state machine - not ideal. My reliability problems seem to have been down to using SharedPreferences to hold state between tests. Thanks for the responses. Ian Hunter On Nov 29, 8:10 pm, Ian ian.fawcett.hun...@gmail.com wrote: Thanks for your response - I think this could be enlightening However, a few questions... On Nov 29, 7:30 pm, A. Elk lancaster.dambust...@gmail.com wrote: Can I get clarification here? Does your application call finish() at some point? If so, at what point? The Android design guidelines strongly discourage the use of an exit button. You should see that most apps don't have one. The way to exit an application is to switch to another one (including a phone call) or go to the Launcher/Home. Whenever you switch, the onPause() method for the foreground Activity of your app should be called. Whenever you switch back, the onResume() method should be called. Can you please point me at the guidelines you are referring to? I have seen many references to the finish() method, but nothing discouraging its use. In the API it states... void finish() - Call this when your activity is done and should be closed. In my scenario, the user rejects the Terms Conditions in a dialog - and this seems the ideal thing to do, No? I acknowledge that sometimes you may want to start a child *Activity* and then kill it when you're done with it. To do this, use finishActivity() with a result code. You may also want to start a service when your app starts, but give the user the option to stop the service if it's not being used. That's OK too, but you shouldn't shut down the app itself. In short, the Android model is that you leave the application paused, and let Android destroy it to free up resources. If Android does this, it should always call the onPause() method of any Activities that are still running. Can you describe your test harness in more detail? To unit test an Activity, you shouldn't need anything more than InstrumentationTestRunner and ActivityInstrumentationTestCase2. This is documented under Testing and Instrumentation in the Android 2.2 Developer's Guide. I am using the ActivityInstrumentationTestCase2 as you suggest and calling getActivity() to start the Activity. I then do button.performClick() which causes 'finish()'. I am hoping to reliably test that the Activity has paused, stopped or whatever happens. I have refactored and now have a unit test which (via a state variable) does work, but not reliably - this may be another story :-) Thanks Ian Hunter -- You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send
[android-developers] Re: Unit Testing - Activity shutdown
Thanks for the response. In my test harness, I do 'button.performClick()', which itself calls activity.finish(). According to docs... If an activity is paused or stopped, the system can drop it from memory either by asking it to finish (calling its finish() method), or simply killing its process. So I would expect onDestroy(). I'm going to trace through (without the test harness) and see what actually happens. There still remains the question - how do I know onPause() was called? Ideally I need a callback, or a way of querying the activity for its state. Any help appreciated Ian Hunter On Nov 28, 9:41 pm, Frank Weiss fewe...@gmail.com wrote: Chances are what you mean by activity exits is not in line with the Android activity lifecycle. Why do you think that the onPause() callback is not sufficient in this case? -- You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en
[android-developers] Re: Unit Testing - Activity shutdown
OK. Just run up the same app, press exit button and I get a call to onStop(), then onDestroy(). That, I assume is what happens on the finish() method. Notice no call to onPause() :-\ So, it looks like the test harness has a different behaviour. A temporary, poor solution has been to create an interval variable which gets set on state transitions (onPause(), onCreate() etc.), and then query that variable in my test harness. Then I use 'assertTrue(state != RUNNING)'. Not good, but I can move on for now. Any better solutions, or insights appreciated. Thanks Ian Hunter On Nov 29, 8:20 am, Ian ian.fawcett.hun...@gmail.com wrote: Thanks for the response. In my test harness, I do 'button.performClick()', which itself calls activity.finish(). According to docs... If an activity is paused or stopped, the system can drop it from memory either by asking it to finish (calling its finish() method), or simply killing its process. So I would expect onDestroy(). I'm going to trace through (without the test harness) and see what actually happens. There still remains the question - how do I know onPause() was called? Ideally I need a callback, or a way of querying the activity for its state. Any help appreciated Ian Hunter On Nov 28, 9:41 pm, Frank Weiss fewe...@gmail.com wrote: Chances are what you mean by activity exits is not in line with the Android activity lifecycle. Why do you think that the onPause() callback is not sufficient in this case? -- You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en
[android-developers] Re: Unit Testing - Activity shutdown
Can I get clarification here? Does your application call finish() at some point? If so, at what point? The Android design guidelines strongly discourage the use of an exit button. You should see that most apps don't have one. The way to exit an application is to switch to another one (including a phone call) or go to the Launcher/Home. Whenever you switch, the onPause() method for the foreground Activity of your app should be called. Whenever you switch back, the onResume() method should be called. I acknowledge that sometimes you may want to start a child *Activity* and then kill it when you're done with it. To do this, use finishActivity() with a result code. You may also want to start a service when your app starts, but give the user the option to stop the service if it's not being used. That's OK too, but you shouldn't shut down the app itself. In short, the Android model is that you leave the application paused, and let Android destroy it to free up resources. If Android does this, it should always call the onPause() method of any Activities that are still running. Can you describe your test harness in more detail? To unit test an Activity, you shouldn't need anything more than InstrumentationTestRunner and ActivityInstrumentationTestCase2. This is documented under Testing and Instrumentation in the Android 2.2 Developer's Guide. On Nov 29, 1:33 am, Ian ian.fawcett.hun...@gmail.com wrote: OK. Just run up the same app, press exit button and I get a call to onStop(), then onDestroy(). That, I assume is what happens on the finish() method. Notice no call to onPause() :-\ So, it looks like the test harness has a different behaviour. A temporary, poor solution has been to create an interval variable which gets set on state transitions (onPause(), onCreate() etc.), and then query that variable in my test harness. Then I use 'assertTrue(state != RUNNING)'. Not good, but I can move on for now. Any better solutions, or insights appreciated. Thanks Ian Hunter On Nov 29, 8:20 am, Ian ian.fawcett.hun...@gmail.com wrote: Thanks for the response. In my test harness, I do 'button.performClick()', which itself calls activity.finish(). According to docs... If an activity is paused or stopped, the system can drop it from memory either by asking it to finish (calling its finish() method), or simply killing its process. So I would expect onDestroy(). I'm going to trace through (without the test harness) and see what actually happens. There still remains the question - how do I know onPause() was called? Ideally I need a callback, or a way of querying the activity for its state. Any help appreciated Ian Hunter On Nov 28, 9:41 pm, Frank Weiss fewe...@gmail.com wrote: Chances are what you mean by activity exits is not in line with the Android activity lifecycle. Why do you think that the onPause() callback is not sufficient in this case? -- You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en
[android-developers] Re: Unit Testing - Activity shutdown
Thanks for your response - I think this could be enlightening However, a few questions... On Nov 29, 7:30 pm, A. Elk lancaster.dambust...@gmail.com wrote: Can I get clarification here? Does your application call finish() at some point? If so, at what point? The Android design guidelines strongly discourage the use of an exit button. You should see that most apps don't have one. The way to exit an application is to switch to another one (including a phone call) or go to the Launcher/Home. Whenever you switch, the onPause() method for the foreground Activity of your app should be called. Whenever you switch back, the onResume() method should be called. Can you please point me at the guidelines you are referring to? I have seen many references to the finish() method, but nothing discouraging its use. In the API it states... void finish() - Call this when your activity is done and should be closed. In my scenario, the user rejects the Terms Conditions in a dialog - and this seems the ideal thing to do, No? I acknowledge that sometimes you may want to start a child *Activity* and then kill it when you're done with it. To do this, use finishActivity() with a result code. You may also want to start a service when your app starts, but give the user the option to stop the service if it's not being used. That's OK too, but you shouldn't shut down the app itself. In short, the Android model is that you leave the application paused, and let Android destroy it to free up resources. If Android does this, it should always call the onPause() method of any Activities that are still running. Can you describe your test harness in more detail? To unit test an Activity, you shouldn't need anything more than InstrumentationTestRunner and ActivityInstrumentationTestCase2. This is documented under Testing and Instrumentation in the Android 2.2 Developer's Guide. I am using the ActivityInstrumentationTestCase2 as you suggest and calling getActivity() to start the Activity. I then do button.performClick() which causes 'finish()'. I am hoping to reliably test that the Activity has paused, stopped or whatever happens. I have refactored and now have a unit test which (via a state variable) does work, but not reliably - this may be another story :-) Thanks Ian Hunter -- You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en