Showing posts with label test. Show all posts
Showing posts with label test. Show all posts

Wednesday, September 24, 2014

How to run junit tests inside the android project

Hi there!

Today i'm gonna show you how to create and run junit tests inside your android project without creating a separated test project. With those tests we will rapidly be able to automate and test the app's logic and some simple UI behaviors. The example below is very straightforward and much more intuitive than other approaches i saw out there.

Defining the TestInstrumentation 

First of all, define in your manifest file the following entries. IMPORTANT: While the definition of the test instrumentation will be placed outside your application tag, the test runner must be defined  inside your application tag.




< manifest >
...
< instrumentation 
  android:name="android.test.InstrumentationTestRunner"
  android:targetPackage="com.treslines.ponto" 
/ >
< / manifest >
< application >
...
< uses-library android:name="android.test.runner" / >
...
< / application >

Creating the test packages

Android works with some conventions while testing. So it is extremelly important to follow those conventions. Otherwise you'll get compile or run errors while trying to run it. One convention is that all tests for a specific class must be placed in the same package structure but with a futher sub-folder called test as you can see below. Because i want to test the activities in the package com.treslines.ponto.activity i must create a test package called com.treslines.ponto.activity.test



Creating the test itself

That's the cool part of it. Here you can write your junit tests as usual. Again android  gives us some conventions to follow. All test classes must have the same name as the class under test with the suffix Test on it. And all test methods must start with the prefix test on it. If you follow those conventions everything will work just fine.

// IMPORTANT: All test cases MUST have a suffix "Test" at the end
//
// THAN:
// Define this in your manifest outside your application tag:
//  < instrumentation 
//    android:name="android.test.InstrumentationTestRunner"
//    android:targetPackage="com.treslines.ponto" 
//  / >
//
// AND:
// Define this inside your application tag:
//  < uses-library android:name="android.test.runner" / >
//
// The activity you want to test will be the "T" type of ActivityInstrumentationTestCase2
public class AlertaActivityTest extends ActivityInstrumentationTestCase2 < AlertaActivity > {

 private AlertaActivity alertaActivity;
 private AlertaController alertaController;

 public AlertaActivityTest() {
  // create a default constructor and pass the activity class
  // you want to test to the super() constructor
  super(AlertaActivity.class);
 }

 @Override
 // here is the place to setup the var types you want to test
 protected void setUp() throws Exception {
  super.setUp();
  
  // because i want to test the UI in the method testAlertasOff()
  // i must set this attribute to true
  setActivityInitialTouchMode(true);

  // init variables
  alertaActivity = getActivity();
  alertaController = alertaActivity.getAlertaController();
 }

 // usually we test some pre-conditions. This method is provided
 // by the test framework and is called after setUp()
 public void testPreconditions() {
  assertNotNull("alertaActivity is null", alertaActivity);
  assertNotNull("alertaController is null", alertaController);
 }

 // test methods MUST start with the prefix "test"
 public void testVibrarSomAlertas() {
  assertEquals(true, alertaController.getView().getVibrar().isChecked());
  assertEquals(true, alertaController.getView().getSom().isChecked());
  assertEquals(true, alertaController.getView().getAlertas().isChecked());
 }

 // test methods MUST start with the prefix "test"
 public void testAlertasOff() {
  Switch alertas = alertaController.getView().getAlertas();
  // because i want to simulate a click on a view, i must use the TouchUtils
  TouchUtils.clickView(this, alertas);
  // wait a little (1.5sec) because the UI needs its time
  // to change the switch's state and than check new state of the switches
  new Handler().postDelayed(new Runnable() {
   @Override
   public void run() {
    assertEquals(false, alertaController.getView().getVibrar().isChecked());
    assertEquals(false, alertaController.getView().getSom().isChecked());
   }
  }, 1500);
 }
}

Running the JUnit tests

The only difference while running junit test in android is that you'll be calling Run As > Android JUnit Test instead of just JUnit Test like you are used to in java.


That's all! Hope you like it! :)

😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘‡

Be sure to read, it will change your life!
Show your work by Austin Kleonhttps://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practiceshttps://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘†

Saturday, April 27, 2013

Testing Android Apps with Junit (no more slow emulator)

Hi there, today i wanna share a very helpful way to test our Android Apps with fast Junit tests instead of using the "slow emulator". With Junit you'll speed up your development and ensure quality.

Requirements:
  • Your Project must use at a minimum platform 2.2 Google API level 8. (This is the most cases)
  • You must use Junit 4 Library and not Junit 3.
  • Download the newst jar file from here: robolectric-X.X.X-all.jar 
How to do it? 
  1. Create your Android project normally.
  2. select your project and add a new folder called test like the pic bellow.


Creating a Junit Test Project
Create a simple Java-Project (attention not another Android-Project) with the same name as your Android project but with the suffix -Test at the end and click next. (Attenion: do not press finish)  
Ex: MyProject and MyProjectTest

Select the src-folder, right mouse click and select "remove source folder" from build path. (the src folder will change from source into normal folder. see picture bellow after point 4)


Select the src-folder, right mouse click and take "Link additional source" and browse the created test folder from your Android Project and then click finish. The result will be something like point 1 in the pic above.

Create a folder called lib in your test project like point 4 in the picture above and copy/paste the downloaded roboelectric-x.x.x-all.jar into it.

Now select your test project, right mouse click, select Build Path > Configure Build Path... > select tab libraries > add library > Junit > next > select Junit 4 > click finish but stay in this dialog.

Click add jars... > select your test project (in this example here: MyProjectTest) > lib > select roboelectric-x.x.x-jar > click ok but stay in this dialog. (see picture bellow point 1)

Click add external jars... > [browse the location from your android-sdk] > platforms > android 8 > select android.jar > click ok but stay in this dialog. (see picture bellow point 1)

Click add external jars... > [browse the location from your android-sdk] > add-ons> addons-google_apis-android-8 > libs > select maps.jar > click ok. (see picture bellow point 1)


Select the Tab Projects > add your test project to it like the picture bellow. After that press the refresh key (F5) and run a project clean. (Project > clean...) (see picture bellow)


Setup your test run configuration
Attention: This step is very important. It will not work, if you don't do it.

Select menu run > run configurations... > double click Junit > and follow the steps in the picture bellow:




Write your first test to validate all those steps
Go back to your test project (in this case here MyProjectTest) and create a simple class in the test folder called MyActivityTest and copy the next code lines into it.

package com.example;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;

import org.junit.Test;
import org.junit.runner.RunWith;

import com.example.myproject.MainActivity;
import com.example.myproject.R;
import com.xtremelabs.robolectric.RobolectricTestRunner;

@RunWith(RobolectricTestRunner.class)
public class MyActivityTest {

    @Test
    public void shouldHaveHappySmiles() throws Exception {
        String hello = new MainActivity().getResources().getString(R.string.hello_world);
        assertThat(hello, equalTo("Hello world!"));
    }
}

Run the test
Menu > Run > Run Configurations... > select Junit > select your created MyProjectTestConfiguration and run it. If everything went well, we should get something like this:



So bye bye slow emulator... ;-) happy coding!



😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘‡

Be sure to read, it will change your life!
Show your work by Austin Kleonhttps://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practiceshttps://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘†




Wednesday, October 17, 2012

How to eliminate switches and enums with simple polymorphism

Hi there! Today we will see, based on a real example, how we can banish ugly switch-cases and enums from the code with simple polymorphism. The example bellow has been written by my self a few months ago. At this time i was convinced that it was simple and good enough. Now i know it better and i'm convinced that it could be better, more flexible and maintainable with little effort but with huge effect. The following example handles states of buttons in a game field i'm programming.


UML




Interface EnableDisable



import java.util.List;

import javax.swing.JButton;

public interface EnableDisable {

    public void disableButtons(List<JButton> gameFieldButtons, int... indizes);

    public void disableButtons(JButton selectedButton, List<JButton> gameFieldButtons, int... steps);

    public void enableButtons(List<JButton> gameFieldButtons, int... indizes);

    public void enableButtons(JButton selectedButton, List<JButton> gameFieldButtons, int... steps);

}

Class EnableDisableUtil

import java.awt.Color;
import java.util.List;

import javax.swing.JButton;
import javax.swing.border.LineBorder;

public class EnableDisableUtil implements EnableDisable {

    public void disableButtons(List<JButton> gameFieldButtons, int... indizes) {
        disableOrEnable(Choice.DISABLE, gameFieldButtons, indizes);
    }

    public void disableButtons(JButton selectedButton, List<JButton> gameFieldButtons, int... steps) {
        disableOrEnable(Choice.DISABLE, selectedButton, gameFieldButtons, steps);
    }

    public void enableButtons(List<JButton> gameFieldButtons, int... indizes) {
        disableOrEnable(Choice.ENABLE, gameFieldButtons, indizes);
    }

    public void enableButtons(JButton selectedButton, List<JButton> gameFieldButtons, int... steps) {
        disableOrEnable(Choice.ENABLE, selectedButton, gameFieldButtons, steps);
    }

    private void disableOrEnable(Choice choice, List<JButton> gameFieldButtons, int... indizes) {
        switch (choice) {
        case ENABLE:
            for (int i = 0; i < indizes.length; i++) {
                enable(indizes[i], gameFieldButtons);
            }
            break;
        case DISABLE:
            for (int i = 0; i < indizes.length; i++) {
                disable(indizes[i], gameFieldButtons);
            }
            break;
        default:
            break;
        }

    }

    private void disableOrEnable(Choice choice, JButton selectedButton, List<JButton> gameFieldButtons, int... steps) {
        for (int i = 0; i < steps.length; i++) {
            int valueFromSelectedButton = Integer.valueOf(selectedButton.getText());
            int valueFromButtonToBeDisabled = steps[i] + valueFromSelectedButton;
            int indexFromButtonToBeDisabled = valueFromButtonToBeDisabled - 1;// because gameFieldButtons starts by 0
            switch (choice) {
            case ENABLE:
                enable(indexFromButtonToBeDisabled, gameFieldButtons);
                break;
            case DISABLE:
                disable(indexFromButtonToBeDisabled, gameFieldButtons);
                break;
            default:
                break;
            }
        }
    }

    private void enable(int buttonIndex, List<JButton> gameFieldButtons) {
        JButton buttonToBeDisabled = gameFieldButtons.get(buttonIndex);
        buttonToBeDisabled.setEnabled(true);
        buttonToBeDisabled.setBorder(new LineBorder(Color.red, 1, false));
    }

    private void disable(int buttonIndex, List<JButton> gameFieldButtons) {
        JButton buttonToBeDisabled = gameFieldButtons.get(buttonIndex);
        buttonToBeDisabled.setEnabled(false);
        buttonToBeDisabled.setBorder(new LineBorder(Color.lightGray, 1, false));
    }

    private enum Choice {
        ENABLE, DISABLE;
    }

}

What are we doing in this example?

Well, here i'm disabling or enabling some gameFields from my application depending on the method i call. (public methods). Now my question: What's wrong with that? It seems to be pragmatic for this simple use case, right? Well although at first glance this use case seems plausible and functionally ok(it passes the unit test), this design has potential for improvement. Let's point out first what i did "wrong":
  • The name of my interface is not smart. It implies more then one responsabilities.
  • I repeat myself in the signature of the methods of EnableDisable. Only the parameters are different
  • The enum and switches signals fix states to me. So it would be better to handle it over polymorphie.

Let's do the changes. First i wanna rename my interface from EnableDisable to Switchable and let's also eliminate 2 methods. In the sequence let's declare 2 classes called SwitchOn and SwitchOff.


Nice! Thats a lot more interesting. But let's take a look at the concrete classes SwitchOn and SwitchOff to be able to decide if it is good this way or not.

import java.util.List;
import javax.swing.JButton;

public interface Switchable {

    public void toSwitch(List<JButton> gameFieldButtons, int... indizes);

    public void toSwitch(JButton selectedButton, List<JButton> gameFieldButtons, int... steps);

} 


import java.awt.Color;
import java.util.List;
import javax.swing.JButton;
import javax.swing.border.LineBorder;

public class SwitchOn implements Switchable {

    @Override
    public void toSwitch(List<JButton> gameFieldButtons, int... indizes) {
        switchOn(gameFieldButtons, indizes);
    }

    @Override
    public void toSwitch(JButton selectedButton, List<JButton> gameFieldButtons, int... steps) {
        switchOn(selectedButton, gameFieldButtons, steps);
    }

    private void switchOn(JButton selectedButton, List<JButton> gameFieldButtons, int... steps) {
        for (int i = 0; i < steps.length; i++) {
            int valueFromSelectedButton = Integer.valueOf(selectedButton.getText());
            int valueFromButtonToBeDisabled = steps[i] + valueFromSelectedButton;
            int indexFromButtonToBeDisabled = valueFromButtonToBeDisabled - 1;// because gameFieldButtons starts by 0
            enable(indexFromButtonToBeDisabled, gameFieldButtons);
        }
    }

    private void switchOn(List<JButton> gameFieldButtons, int... indizes) {
        for (int i = 0; i < indizes.length; i++) {
            enable(indizes[i], gameFieldButtons);
        }
    }

    private void enable(int buttonIndex, List<JButton> gameFieldButtons) {
        JButton buttonToBeDisabled = gameFieldButtons.get(buttonIndex);
        buttonToBeDisabled.setEnabled(true);
        buttonToBeDisabled.setBorder(new LineBorder(Color.red, 1, false));
    }
} 


import java.awt.Color;
import java.util.List;
import javax.swing.JButton;
import javax.swing.border.LineBorder;

public class SwitchOff implements Switchable {

    @Override
    public void toSwitch(List<JButton> gameFieldButtons, int... indizes) {
        switchOff(gameFieldButtons, indizes);
    }

    @Override
    public void toSwitch(JButton selectedButton, List<JButton> gameFieldButtons, int... steps) {
        switchOff(selectedButton, gameFieldButtons, steps);
    }

    private void switchOff(JButton selectedButton, List<JButton> gameFieldButtons, int... steps) {
        for (int i = 0; i < steps.length; i++) {
            int valueFromSelectedButton = Integer.valueOf(selectedButton.getText());
            int valueFromButtonToBeDisabled = steps[i] + valueFromSelectedButton;
            int indexFromButtonToBeDisabled = valueFromButtonToBeDisabled - 1;// because gameFieldButtons starts by 0
            disable(indexFromButtonToBeDisabled, gameFieldButtons);
        }
    }

    private void switchOff(List<JButton> gameFieldButtons, int... indizes) {
        for (int i = 0; i < indizes.length; i++) {
            disable(indizes[i], gameFieldButtons);
        }
    }

    private void disable(int buttonIndex, List<JButton> gameFieldButtons) {
        JButton buttonToBeDisabled = gameFieldButtons.get(buttonIndex);
        buttonToBeDisabled.setEnabled(false);
        buttonToBeDisabled.setBorder(new LineBorder(Color.lightGray, 1, false));
    }
} 


Don't Repeat Yourself (DRY)

Well as we can see this is a lot better but we can still see a lot of dupplicated code inside of it. The only difference in the implementation from SwitchOn or SwitchOff is the setEnable(true) or setEnable(false) in the methods enable(...) or disable(...) and the LineBorder of both. Let's do one more elegant change to it like this:


import java.util.List;
import javax.swing.JButton;
import javax.swing.border.LineBorder;

public abstract class SwitchAbstract implements Switchable {
 @Override
 public void toSwitch(List<JButton> gameFieldButtons, int... indizes) {
  switchWithIndex(gameFieldButtons, indizes);
 }
 @Override
 public void toSwitch(JButton selectedButton, List<JButton> gameFieldButtons, int... steps) {
  switchWithSteps(selectedButton, gameFieldButtons, steps);
 }
 private void switchWithIndex(List<JButton> gameFieldButtons, int... indizes) {
  for (int i = 0; i < indizes.length; i++) {
   turnSwitchTo(indizes[i], gameFieldButtons);
  }
 }
 private void switchWithSteps(JButton selectedButton, List<JButton> gameFieldButtons, int... steps) {
  for (int i = 0; i < steps.length; i++) {
   int valueFromSelectedButton = Integer.valueOf(selectedButton.getText());
   int valueFromButtonToBeSwitched = steps[i] + valueFromSelectedButton;
   int indexFromButtonToBeSwitched = valueFromButtonToBeSwitched - 1;// because gameFieldButtons starts by 0
   turnSwitchTo(indexFromButtonToBeSwitched, gameFieldButtons);
  }
 }
 private void turnSwitchTo(int buttonIndex, List<JButton> gameFieldButtons) {
  JButton buttonToSwitch = gameFieldButtons.get(buttonIndex);
  buttonToSwitch.setEnabled(switchTo());
  buttonToSwitch.setBorder(howShallLineBorderLooksLike());
 }
 protected abstract boolean switchTo();
 protected abstract LineBorder howShallLineBorderLooksLike();
} 


public class SwitchOn extends SwitchAbstract {
 @Override
 protected boolean switchTo() {
  return Boolean.TRUE;
 }
 @Override
 protected LineBorder howShallLineBorderLooksLike() {
  return new LineBorder(Color.red, 1, false);
 }
} 


public class SwitchOff extends SwitchAbstract {
 @Override
 protected boolean switchTo() {
  return Boolean.FALSE;
 }
 @Override
 protected LineBorder howShallLineBorderLooksLike() {
  return new LineBorder(Color.lightGray, 1, false);
 }
} 

Why did i name the class SwitchAbstract and not AbstractSwitch?

Well maybe you did not noticed or it is not so obvious at first sight, but i has a good reason. the reason is in the way i'm able to search in my IDE. Naming my classes this way alls "Switch..." classes will be presented as a list in a very nice way while looking for the keyword "switch" in Eclipse. 



Results in facts:

When talking about clean code i ofen hear the argumet: It makes my code a lot more complex and generate a lot of useless code. Well let's see if this is true. I have more classes. For this case it must be automatically more complex and of course it must be have generated more lines of code right? 

Old version: Lines of code:  96 Lines of code 
New version: Lines of code: 73 Lines of code

Old class and interface names: Naming was not that simple understandable.
New class and interface names: Clear, does not implies more then one responsabilities

Old class implementation: Costs a lot and had ugly switch-cases and enums in it.
New class implemention: No effort, no enums, no ungly switche-cases  

😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘‡

Be sure to read, it will change your life!
Show your work by Austin Kleonhttps://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practiceshttps://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘†