Thursday, September 29, 2011

Get list of files in a directory using Java

While doing an automation I came up with a problem where I need to get a list of all files in a Directory.
So just though to share the same with you the program to do so. I had made used of recursion in the following programs to get the list of files. Following are the two programs one will give you a ArrayList of files with their absolute path where as another will give you an ArrayList of File object of respective files.
Following program will store the absolute path of all the files inside a directory to the fileList argument provided.
public void listDirectory(File f, ArrayList< String> fileList) {
		File[] listOfFiles = f.listFiles();

		for (int i = 0; i < listOfFiles.length; i++) {
			if (listOfFiles[i].isFile()) {
				fileList.add(listOfFiles[i].getAbsolutePath());
			} else if (listOfFiles[i].isDirectory()) {
				listDirectory(listOfFiles[i], fileList);
			}
		}
	}

Following  program will store the File object of the files that are found into the respective fileList Array provided as an argument to the function
public void listDirectory(File f, ArrayList< File> fileList) {
		File[] listOfFiles = f.listFiles();

		for (int i = 0; i < listOfFiles.length; i++) {
			if (listOfFiles[i].isFile() ) {
				fileList.add(listOfFiles[i]);
			} else if (listOfFiles[i].isDirectory() ) {
				listDirectory(listOfFiles[i], fileList);
			}
		}
	}

Friday, September 23, 2011

Automating a Native android app using Selenium and NativeDriver

As there are more and more development happening on the android front, automation of the developed applications has also become a necessity. Android within its API supports a testing framework which can be used for testing applications, but writing and developing cases using that API is not easy. We may need a framework that makes it easy to write and develop test cases for our applications.
One of such framework is "NativeDriver". It is built over the Selenium webdriver automation framework.
As you must be knowing that selenium is vastly used open-source functional automation tool. 
In this write-up I will tell you on how to automate an android application using NativeDriver
Following things are required before starting:
  • Android SDK 2.2 or later - download
  • Eclipse version 3.5 or later (Eclipse IDE for Java Developers recommended) - download
  • Android Development Toolkit (ADT) plug-in - Installing ADT
  • Ant - download
  • JDK 1.6 or later - download
Building the NativeDriver libraries:
  • Checkout the NativeDriver code:
  • svn checkout https://nativedriver.googlecode.com/svn/trunk nativedriver --username {Google account e-mail address}
  • Build the NativeDriver code:
  • $ cd nativedriver/android
    $ ant

The libraries are built and stored in the nativedriver/android/build directory:

  • server-standalone.jar - this should be linked to your Android application, and runs on the Android device (or emulator). This is the NativeDriver server, and listens for requests to automate the application, such as “start an activity” or “click a UI element”
  • client-standalone.jar - this should be linked to the test, which is the NativeDriver client. It implements a WebDriver API which communicates with the server.

Adding the NativeDriver jar to your application



  • Import your android application code into the eclipse by using the File -> Import functionality of eclipse.
  • Add the server-standalone.jar to the build-path of your android application by Right clicking on the Android application project -> Configure build path -> Add jars or Add external jars (browse to the server-standalone.jar file, select and add it).
  • To the application AndroidMainfest.xml file, add the following to the element.

 android:targetPackage="{app_package_name}"
   android:name="com.google.android.testing.nativedriver.server.ServerInstrumentation" />
   android:name="android.permission.INTERNET" />
   android:name="android.permission.WAKE_LOCK" />
   android:name="android.permission.DISABLE_KEYGUARD" />
           Here {app_package_name} needs to be replaced with the name of the package as specified in the mainfest element's package attribute.
  • Build the application and install it on the device.
  • Now go to the commandline and start the instrumentation using the following line:
adb shell am instrument {app_package_name}/com.google.android.testing.nativedriver.server.ServerInstrumentation
Here again the {app_package_name} needs to be replaced with the name of the package as specified in the mainfest element's package attribute.
  • Enable port forwarding by using the following command:
adb forward tcp:54129 tcp:54129

Writing your Test Cases
For writing your test cases you just have to create a new Java project and start writing code for it. I will explain this using a code example. The following code is done to automate an opensource K9 mail application on android:

package com.test;

import org.junit.*;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import junit.framework.TestCase;

import com.google.android.testing.nativedriver.client.AndroidNativeDriver;
import com.google.android.testing.nativedriver.client.AndroidNativeDriverBuilder;
import com.google.android.testing.nativedriver.client.AndroidNativeElement;
import com.google.android.testing.nativedriver.common.AndroidKeys;
import com.google.android.testing.nativedriver.common.AndroidNativeBy;

public class K9NativeTesting {

	private AndroidNativeDriver driver; //Defining the driver object of AndroidNativeDriver 

	@Before
	public void beforeTest() { // Before method that will get the driver object from getDriver()
		driver = getDriver();
	}

	@After
	public void afterTest() { //Runs after the test is run and shutdown the driver.
		driver.quit();
	}

	 // Build/start the Android driver and returns it.
protected AndroidNativeDriver getDriver() {
		return new AndroidNativeDriverBuilder().withDefaultServer().build(); 
	}
	
	  private void startK9Activity() {
		    driver.startActivity("com.fsck.k9." +
		        "activity.Accounts");
		  }
	 // starts the activity (application) mentioned. In this case it is com.fsck.k9 
	//	  also you can see the activity.Accounts this you can from the logs of adb logcat while starting the application
	  
	  @Test //Test method to configure a new mail account in K9
	  public void tesK9(){
		  startK9Activity();
		  driver.findElement(AndroidNativeBy.text("Next")).click();
		  driver.findElement(AndroidNativeBy.id("account_email")).sendKeys("test@test.com");

// Here I am using the By.Id("account_email") you can get the Ids of the UI elements from the R.java
// file genrated by the android api while building an application. 

		  WebElement ele=this.findAndClickElementById(driver, "account_password");
		  ele.sendKeys("password");
		  driver.findElement(AndroidNativeBy.text("Next")).click();
	  }
	  
	  @Test /*Test method to compose a new mail in K9*/
	  public void composeMail(){
		  WebElement ele;
		  startK9Activity();
		  driver.getKeyboard().sendKeys(AndroidKeys.MENU);
		  driver.findElement(AndroidNativeBy.text("Compose")).click();
		  ele=this.findAndClickElementById(driver, "to");
		  ele.sendKeys("send@test.com");
		  ele=this.findAndClickElementById(driver, "subject");
		  ele.sendKeys("Test Message");
		  ele=this.findAndClickElementById(driver, "message_content");
		  ele.sendKeys("This is a test message");
		  
		  driver.getKeyboard().sendKeys(AndroidKeys.MENU);
		  driver.findElement(AndroidNativeBy.text("Send")).click();
		  
	  }
	  
	  public WebElement findAndClickElementById(AndroidNativeDriver tempDriver, String id){
		  WebElement ele = tempDriver.findElementById(id);
		  ele.click();
		  return ele;
	  }

}

Important Notes:-

  • As there is no recording feature available, we need to write the code manually for automating our scenarios. 
  • For identifying the element id to interact on the UI, you can get the ID's of the elements from the R.java file generated inside your android application code.
  • Also as we are writing our cases in Java code we can use our own test framework and generate html reports for out automation execution.


Note: Most of the material in this blog has been taken from the original site of the NativeDriver. The credit for such material goes to the original author.
Following is the link to it. http://code.google.com/p/nativedriver