Testing Android devices: how to make the class more testable?

I developed applications for Android, but did not write any unit tests. I recently started to find out about this and tried to use JUnit to test Android applications.

I found that most of the time I get errors in API calls, but I still can’t figure out how to write unit tests for them (and to make the source code testable).

Let me explain the following function:

I run a call to the setOffenceList () function. There are several actions inside a function.

i) Download RestClient and pass the URL.

ii) RestClient talks to the JSON api and gets a response

ii) I grab the response inside the response function onSuccess (String)

iii) Parse JSON data and store it inside an array

iv) If success I show the data in the list view (still show the error message)

This is the code:

public class OffenceFrag extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.frag_offence, container, false); //run API call setOffenceList(); return view; } private void setOffenceList() { String url = Paths.SITE_URL ; RestClient.get(url, null, new AsyncHttpResponseHandler() { @Override public void onStart() { Toast.makeText(getActivity(), "Loading offences...", Toast.LENGTH_SHORT).show(); } @Override public void onSuccess(String response) { //Parse JSON JSONArray jsonArray; try { JSONObject jsonObj = new JSONObject(response); if(jsonObj.getString("status").equalsIgnoreCase("Success")){ jsonArray = new JSONArray(jsonObj.getString("data")); if(jsonArray.length() > 0){ for (int i = 0; i < jsonArray.length(); i++) { JSONObject row = jsonArray.getJSONObject(i); OffenceORM off = new OffenceORM(); off.setOffenceId(row.getString("offence_id")); off.setPhoto(row.getString("photo")); off.setSubmittedBy(row.getString("submitted_by")); offenceList.add(off); } } //Success: Show the list view setOffenceAdapter(); Toast.makeText(getActivity(), "Successfully Loaded", Toast.LENGTH_LONG).show(); } else { //Failed: show error message Toast.makeText(getActivity(), "There are no offences submitted under project", Toast.LENGTH_LONG).show(); } } catch (Exception e) { Log.e("exception", e.getMessage()); } } @Override public void onFailure(Throwable error, String content) { Log.e("failed", error.getMessage()); } @Override public void onFinish() { } }); } }//end 

I can't figure out how to write a test function for something like the code above.

Can you show me how to break this code into test fragments and write unit test functions to them?

Thanks a lot!

+6
source share
3 answers

Only and only good design can help you simplify unit testing. This is why Test Driven Development exists. So you cannot go with the wrong design.

When you unit test, you just check the code you wrote and use the mock objects provided by Android to test your Api calls for Android.

As far as other Api have problems than Api developer problem, not yours. You can use the mock framework, such as Mockito, to test the functionality of your code when it calls another API code. Check the API code separately if you are developing your own API.

Design principles must be followed for good design, e.g.

  • S - single responsibility principle
  • O - principle of open closure
  • L - Liskov substitution principle
  • i am the principle of interface segregation
  • D - dependency inversion principle

Important points:

  • one method method call in case of unit test
  • Do not modify classes for testing purposes only.
  • Using Interfaces
  • Do not put too many operators or functions in one method.
  • Do not make classes too large.
  • Use TDD ....... Many others

Unit testing of bad development code is a complete loss. Because the test will be interrupted every time you make some changes to the classes. On Android, this will happen even more. Since you stick with the Android lifecycle methods.

Thoroughly abstract functions that you want to test in your classes.

This will make the application code more reliable, simple and understandable.

+4
source

You do too many things in the Fragment, it is difficult to verify and give support.

I use the MVP template in my projects, which allows me to separate the presentation layer from the logic, avoiding putting all the code in a fragment / activity.

Check out this article: http://antonioleiva.com/mvp-android/

And the corresponding sample code on GitHub: https://github.com/antoniolg/androidmvp

+1
source

The Rohit Khatkar tip for using TDD is definitely worth considering the following code that you are developing. But now that this code exists, and you ask β€œhow to break this code into test parts”: you could first ignore the test possibilities and just try to break this code into smaller parts: Exline class definitions and separation methods, as well as for optimization readability in general. You will already find some redundancy (if around the for loop).

As an effect, each of the methods obtained is likely to have less dependence on other classes. Then you can focus on reducing these dependencies. Check out Michael Per's book on working with legacy code for a range of dependency breaking approaches. EDIT: someone pulled out a list of addiction violation methods (high-level descriptions only): http://rubyexperiences.blogspot.de/2005/12/dependency-breaking-techniques-from.html

+1
source

All Articles