1. Are you ready for the Galaxy S20? Here is everything we know so far!

App testing questions

Discussion in 'Android Development' started by RhinoCan, Aug 6, 2018.

  1. RhinoCan

    RhinoCan Well-Known Member
    Thread Starter

    1. I'd like to make the app I'm writing as robust as I can so it seems to me that I need to handle conditions like the absence of a connection to the MySQL database I am using, which is on a remote server. How do I jigger my program so that it's failing to get an internet connection in a realistic way? I have my phone connected to the laptop for testing so initially, I just disconnected the laptop from the house WiFi. That made no difference and I was puzzled for a second, then realized it was the phone's WiFi connection that was being used. I turned off the phone WiFi and that still didn't make a difference: the phone just started using the nearest cell tower. I tried to figure out how to turn that off but it was set to "automatic" and I couldn't find an off setting. Short of building a Faraday cage, I'm not sure how best to turn off the internet to the phone.
    2. What is the accepted procedure for testing GUI apps on Android? I've seen mention of Espresso but know nothing about it beyond that it is some kind of testing tool. Is that the way to go? Is that enough to thoroughly test the app or will I need to do additional testing? If so, what? Perhaps someone can point me to documentation saying what the testing expectations are for professional quality apps?
     


  2. Best Answer:
    Post #2 by Deleted User, Aug 7, 2018 (1 points)
  3. Deleted User

    Deleted User Guest

    You've asked a huge question here. But I'll try to answer without writing an epic story. Your first question is easiest to deal with.

    1. It should be possible on your phone to switch off 4G. I thought all phones could do that. What are you using?

    2. There are a number of tools and techniques we can use to unit test our code. This whole area is huge and I could spend all day discussing it. There are different levels of testing, depending on what you want to test. You've mentioned Espresso, which is aimed at testing from the GUI point of view. Historically GUI testing has been difficult, because it's quite hard to mimic the actions of a user, and cope with the dynamic nature of a user interface. But what Espresso is giving you, is a way to automate what a user of your app is doing - button taps, navigation, input, etc.

    And we can also look at unit testing other parts of your code, which don't involve the UI. Such as the database, or utility classes. Here we can use techniques like stubbing and mocking. Say for example, I'm writing a utility class, which returns some information from the database. You're writing another part of the system, which will use this class. You may want to test your part of the system, but I haven't finished my stuff yet. You need a way of mimicking my code. This is where stubs come in. A stub is just a simple dummy method, standing in for the real code. It usually returns no data, or canned data. It's not the real code. A mock takes this a step further, because it mimics the behaviour of the code, and returns data usually dependant on the input provided, so it has a bit more logic inside, making decisions. But both these techniques are doing basically the same thing - providing a way of substituting real code with a simulation of it. The point is, you are aiming to test the code which calls the mock/stub, and allow it to continue, even though some of the real code isn't there.

    Another thing to consider is what part of your system you should be testing. Software systems usually have a lot of boiler plate code, or methods which you don't really need to test e.g. getter and setter methods. Things like this are trivial, and don't really need testing. Target those parts of your system which really need to be tested. People tend to look at what classes have been defined, and pick out certain crucial methods.

    Another testing strategy is to define user scenarios. Construct your test cases according to how users will interact with your app. This is another big area of testing called 'BDD' (Behaviour driven development). There are testing tools which allow you to express your test cases in plain English. This makes them very readable, even for non technical people. The descriptions are then mapped on to low level tests by the testing tool. An example of such a tool is 'Cucumber'. But I don't know what the equivalent is for Android.

    And before you even get to the activity of testing, there's a lot you can do to design your code in such a way that it can be tested easily. But I won't get into that, or I really would be here all day :)

    As I said, various tools exist to help us with unit testing. As a starting point, look at:-

    JUnit
    Mockito
    Espresso

    There some basic information on the subject here

    https://developer.android.com/training/testing/unit-testing/local-unit-tests

    Unit testing of code is a hugely neglected area of software development, even by professionals. So it's great that you're considering how to do it properly. It really is the only way to ensure high quality code. Ultimately you want to be developing a suite of automatic regression tests - so whenever you change something in the code, your tests will run, and give you high confidence that you haven't broken anything. Regression tests are really important in big software systems, which have a lot of features.

    There are a lot of web resources on the subject of unit testing, but hopefully this has given you some flavour of the things to consider.
     
  4. RhinoCan

    RhinoCan Well-Known Member
    Thread Starter

    A big (but belated) thanks for your reply!! You always come through when I ask a question and you've outdone yourself with this reply :)

    I managed to figure out how to turn off the internet in Android (Oreo 8.0.0). Go to the device's Settings/Connections and turn off WiFi (I also turned off BlueTooth but that was probably unnecessary). (That ensures that any internet access you get is through your cell towers). Then go down to Data Usage and click on it; on the Data Usage page, turn Mobile Data off. That seems to finally turn off all WiFi and network access altogether. In case anyone's wondering, I discovered that my attempts to access my remote MySQL database in that situation resulted in a java.net.UnknownHostException.

    As for the much bigger topic of testing, you've given me a lot to think about. I've already started looking at videos on Espresso and think I get the basic concept now; obviously, I'm going to have a lot of details to pick up!

    Luckily, not everything you mention is completely new to me. I've done plenty of unit testing back when I was a professional developer and also got a decent working knowledge of JUnit a few years back. I feel very rusty on JUnit but I feel like it will come back to me quickly. (Most things do.)

    Mockito is new to me, although I've been hearing about a lot of unfamiliar tools in the various Meetups I've started attending (Ruby, PHP, and, of course, Android) so it may have been mentioned there in the past few months. Learning techniques for mocking up beyond stubs (which I have done in the past) may be quite helpful as well.

    Mostly though, I want to learn how to write code that is easily testable and make the thorough testing of my code as natural as breathing. I expect it's going to take a while to get *that* fluent with testing :) But I want to try. I aspire to be a professional developer again so I'm motivated to do this. It's going to be hard convincing anyone to hire me if I don't know how to do the sort of testing you describe.

    I expect we'll talk again as I ask more specific questions about testing :)

    In the meantime, can you suggest any sort of checklist that would identify all the different testing that ought to be done for an Android app? In other words, if you were hiring an Android developer and an applicant presented one of their products to you in a portfolio, what are all the things you'd want to see besides the app code itself? What kind of tests/analyses should the person have done? What sort of documentation (test- and design-related) would you want to see?
     
  5. Deleted User

    Deleted User Guest

    Good code architecture, and ease of testing tend to go hand in hand. If you can write code which is modular, and relatively free from dependencies (loose coupling is the technical term), then that can assist in the testing. Some good concepts to be aware of, and try to use in your design are:-

    - Dependency injection. Usually achieved by using code annotations, and a DI framework. In the Android world, this seems to be used http://www.vogella.com/tutorials/Dagger/article.html
    Use of DI will reduce coupling in your code, and allow the flexibility to use test classes, if needed.

    - Program to the interface. I'm a big fan of interfaces, because it reduces dependencies on concrete classes, and allows you to vary the implementation of the interface at a future date. Combining interfaces with DI is a killer combination. For example, if I define this interface:


    Code (Text):
    1.  
    2. public interface DataRetriever {
    3.   public List getMyData();
    4. }
    5.  
    And I declare an object of type 'DataRetriever' in my calling code, I have the freedom to use any implementing class for that object.

    Code (Text):
    1.  
    2. public class Activity {
    3.   private DataRetriever myDataRetriever;
    4. }
    5.  
    So what do I do when I want to create an instance of DataRetriever? I could do this

    Code (Text):
    1.  
    2. myDataRetriever = new DataRetrieverImpl();
    3.  
    But this creates a fixed dependency on class DataRetrieverImpl. If I later want to change that, and use a different implementing class, I have to change my code.
    However, using dependency injection, I can say

    Code (Text):
    1.  
    2. public class Activity {
    3.   @Inject
    4.   private DataRetriever myDataRetriever;
    5. }
    6.  
    And I don't even need to create an instance of DataRetriever, because the DI framework will create it, and inject the object instance into my class at runtime (via a setter method). Point is, I've removed the dependency between the classes.
     
  6. RhinoCan

    RhinoCan Well-Known Member
    Thread Starter

    I think one of the members of the PHP meetup demonstrated that technique in a recent meetup.I can see the usefulness of it. I"m toying with the idea of being able to store the data from my app either on the remote database or locally in SQLite3 and that might make the switch transparent. Or maybe I'll switch from remote to local storage when I detect that the internet connection has been lost or the remote database is down. I still need to think over how I'd detect that there was local data which isn't at the remote database yet and copy it over.... Hmm. I wonder if you can replicate between an SQLIte3 in Android and a MySQL server?
     
Loading...
Similar Threads - App testing questions
  1. Steddars
    Replies:
    2
    Views:
    38
  2. anna678
    Replies:
    2
    Views:
    168
  3. SRT GmbH
    Replies:
    5
    Views:
    1,000
  4. pledgeX
    Replies:
    0
    Views:
    362
  5. Nickineisser
    Replies:
    1
    Views:
    374
  6. Kamal14042015
    Replies:
    3
    Views:
    640
  7. Aditya_GLP
    Replies:
    0
    Views:
    265
  8. GiorgioT
    Replies:
    0
    Views:
    2,133
  9. Dibakar Mistry
    Replies:
    1
    Views:
    1,394
  10. philippapi
    Replies:
    1
    Views:
    580

Share This Page

Loading...