problem of robotium - android

I just start to use robotium. The demo can be run without any problem, but when I wrote first test script by using EditText and Button, problems occured. My environment is android 2.1 and the script is quite simple, just input username and psw, then click sumbit button to login.
The script is as follows:
package com.tpc.test;
import com.tpc.login.Login;
import com.jayway.android.robotium.solo.Solo;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.Smoke;
public class LoginTest extends ActivityInstrumentationTestCase2<Login>{
private Solo solo;
public LoginTest() {
super("com.tpc", Login.class);
}
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
}
#Smoke
public void testApp() throws Exception {
String appName = solo.getCurrentActivity().getClass().getSimpleName();
System.out.println(appName);
solo.getButton(0).getClass().getSimpleName();
solo.assertCurrentActivity("Expected login activity", appName);
System.out.println(solo.getButton(0).getText());//can get the text of button
solo.enterText(0, "name"); //input name to the 1st EditText is OK
solo.enterText(1, "psw"); // Actually inout psw after name to the 1st EditText
solo.clickOnButton(0); //Expect click the 1st button.Actually click the 1st EditText
//assert of sample, not been modified
boolean expected = true;
boolean actual = solo.searchText("Note 1") && solo.searchText("Note 2");
assertEquals("Note 1 and/or Note 2 are not found", false, actual);
}
#Override
public void tearDown() throws Exception {
try {
solo.finalize();
} catch (Throwable e) {
e.printStackTrace();
}
getActivity().finish();
super.tearDown();
}
}
One problem is both name and psw is filled in the first EditText,the other is solo.clickOnButton(0); click the first EditText, NOT the first Button. I also tried to use the text name of the Button, but the result was the same. It seems all the operations been put to the first EditText. I wanna what's the problem. Any suggestion?thanks

I have had a look at the application that you want to test and the problem is that you do not state that it supports high density screens. That gives Robotium problems as you are using it on a high density emulator/device.
You need to add the following tag in the AndroidManifest.xml:
<supports-screens android:anyDensity="true"/>
If you add that tag to your AndroidManifest.xml then it will work.

Hope you are taking the enter text as a array.. 0 and 1..
But hope you didn't initialize the array
import java.util.Arraylist;
Hope it will work if you initialize the arraylist. Have a try.

You could try to add this tag to your AndroidManifest.xml:
<uses-sdk android:targetSdkVersion="7"/> where 7 means Android 2.1.
If that does not work then please post this on the robotium developers page and I will have a look at it.
http://groups.google.com/group/robotium-developers
Sincerely,
Renas

I also had this issue and i couldn’t find a solution with robotium. Then i move to the android instrumentation provided with the SDK. What i have done is mentioned below. This worked without any issues for me. Here it is ..
First define a private variable for the button as a member variable
private Button msButton;
Then get the button instance with in the setup method.
mButton = (Button) solo.getCurrentActivity().findViewById(
com.marakana.android.simple_intent.R.id.sendButton);
Then call the button click with in the UI thread in the test method as mentioned below.
//Test button method
public void testButtonClick() {
//Get the current activity and request to run onUI thread
solo.getCurrentActivity().runOnUiThread(new Runnable() {
public void run() {
//Request focus for the button
mButton.requestFocus();
}
});
//Send the button click event
this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
}
That’s it .. Now you can test your button with other Robotium features.

Related

two robotium test case, but the second hang there not responding(in JUnit View)

I managed to write two test cases in my XXTest.java with robotium-solo-3.2.1.jar included, luckily in JUnit view it shows the first one is done, which the device exactly worked (on emulator too).
Then it proceed to the second one, but it just hanging there forever! sorry I can't attach screen shot with my account.
here are my code:
public class XXTest extends ActivityInstrumentationTestCase2<SignInActivity> {
private Solo solo;
private Activity mActivity;
private static final String account = "someone";
private static final String pwd = "123456";
#SuppressWarnings("deprecation")
public XXTest() {
super("com.acompany.android", SignInActivity.class);
}
protected void setUp() throws Exception {
super.setUp();
this.mActivity = getActivity();
solo = new Solo(getInstrumentation(), mActivity);
}
#Smoke
public void testLogIn() throws Exception {
EditText accountInput = (EditText) solo.getView(R.id.edit_account);
EditText pwdInput = (EditText) solo.getView(R.id.edit_password);
solo.clearEditText(accountInput);
solo.clearEditText(pwdInput);
solo.enterText(accountInput, account);
solo.enterText(pwdInput, pwd);
solo.clickOnButton(mActivity.getResources()
.getString(R.string.text_sign_in));
solo.waitForActivity("MainActivity");
solo.assertCurrentActivity("Expect MainActivity shown...", "MainActivity");
boolean expected = true;
boolean actual = solo.searchButton(mActivity.getResources().getString(
R.string.welcome_dialog_start));
assertEquals("find friend dialog not shown", expected, actual);
}
#Smoke
public void testOpenPref() throws Exception {
solo.goBack();
solo.clickOnMenuItem(mActivity.getResources().getString(
R.string.text_preferences));
solo.assertCurrentActivity("Expected PrefActivity..", "PrefActivity");
solo.goBackToActivity("MainActivity");
solo.assertCurrentActivity("Expected MainActivity..", "MainActivity");
}
protected void tearDown() throws Exception {
super.tearDown();
}
}
I've searched the sample of NotePadTest.java from Robotium tutorial, those 3 test cases in it are just work fine!
Please tell me where goes wrong?? Am I missing something somewhere? why the second test case not running?
btw. Can there be more than one class extends ActivityInstrumentationTestCase2 in a test project? curious!
You need to use solo.finishOpenedActivities() in your tearDown().
#Robert - this is the issue with Activity testing itself , not to robotium specific .
For the first test method:
the basic flow you is like below:
1>in the setUp() method load the main activity (say MainActivity) > do some ops in your testMethod1() - that results to land you in another activity ( say AnotherActivity) > and in tearDown() you kill the launched activity in setUp() method which is MainActivity
note: but AnotherActivity remains live
For the second test method:
the basic flow you is like below:
2>in the setUp() method try loading the main activity (say MainActivity) again ,although the previously launched AnotherActivity is not yet got killed, so it hangs there , It doesnt even enter the testMethod2() fr execution -
note: the eclipse graphical runner shows it hangs while the execution marker points to the testMethod2() , people thinks that it got stuck in testMethod2() - but the problem lies in setUp() for testMethod2() not in testMethod2() itself.
Solution:
1>Just keep a look on your cross activity navigation - at the end of each testMethod() use solo.goBack() to come back to the same main activity MainActivity from your current Activity ( you got landed in because of your actions)
results - at the end of testMethod1() only the main activity which was opened in setUP() remains. So it gets killed successfully .No Activity remains alive and for the testMethod2().The setUP() is able to load the MainActivity again without a hang - and testMethod2() gets executed .
hope it clarifies :)

Android: Call listener manually from java code

Is there any way to call a listener manually from code?
More background information: I use a Spinner and a DatePicker. With the Spinner you can choose a reason for staying at home (maybe your ill, maybe you have vacation) and with the DatePicker you can choose the date how long you will not be available. With these two pieces of information I build up a string for a TextView and show the same data in a compact way. The building process for the string is set by some listeners which recognize changes on one of the two controls and build and set up the new string.
If I start the program and read some data from a server the string will not be build (clearly because nothing changed and no listener will called).
The workaround is to build the string in my own onLoaddata() method. But I think it would be smoother way to call one listener to build the string for me. I also can "call" a listener if I just do some fake .updateDate but I don't think it’s a good idea to create useless calls...
Maybe someone of you have a good hint for me?
Use the following pattern:
public class YourActivity extends Activity implements OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
// Some initialization here
findViewById(R.id.some_button).setOnClickListener(this);
...
// Here you want to update your view
updateTextView();
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.some_button:
// Here you also want to update your view
updateTextView();
break;
...
}
}
private void updateTextView() {
// Here you update your view
...
}
}

Android (student cw) in need of direction

public class Menu extends Activity {
/** Called when the activity is first created. */
public void onCreate(Bundle icicle) {
//myIntent.setClassName("hello.World", "hello.World.mybuttonclick");
// myIntent.putExtra("com.android.samples.SpecialValue", "Hello, Joe!"); // key/value pair, where key needs current package prefix.
//startActivity(myIntent);
//Button myButton = (Button) findViewById(R.id.my_button);
super.onCreate(icicle);
setContentView(R.layout.main);
}
public void updateLayout(){
Intent myIntent = new Intent(Menu.this, mybuttonclick.class);
startActivity(myIntent);
// TextView sayHello = (TextView) findViewById(R.id.Hello);
}
}
Hey guys, I am a new android java student and we have to develop a simple hello world app.. I am finding some difficulty getting my onClick() activity to work, using android:Onclick in xml.. what i am trying to do is change the content view do display a simply a different layout and saying hello.. i am using setContentLayout to do this, every time i click said button tho the android app crashes out.. am i doing something wrong?
regards,
Stefan
When you set a click listener in xml you must have the method defined inside the activity you are clicking in. Lets say you set the onClick in xml to be "buttonClicked", you must create a method looking exactly like the one below.
public void buttonClicked(View view)
{
//Your code here
}
The thing to notice is that the method is a public void with only a single parameter of type View. XML defined click listeners must be like this to work. The view object in the example above is the view that was clicked.
You update layout function needs to read
public void updateLayout(View view)
In response to your question, there are a number of things that are issues causing the complication that you described. Let it first be said, that you don't have to do anything any particular way, provided that you make concessions for certain things. Android is a very flexible platform and Java, as an OOP language allows you to do things that many non OOP languages do not.
Whenever you create a "clickable" item, like a Button, if you want to have your program respond, you must have something "listen" to it. This is known as a Listener. In your case, you are looking for an OnClickListener. The OnClickListener does not have to be a part of the Activity necessarily. It just has to be a class that implements View.OnClickListener. Then, you have tell the setOnClickListener() method of the Button who its listener is. The following example shows what is necessary without your declaration in XML (but it is important).
class Menu extends Activity implements View.OnClickListener
{
public void onCreate(Bundle icicle)
{ setContentView(R.layout.main);
Button btn = (Button)findViewById(R.id.BUTTON_ID_AS_DEFINED_BY_YOUR_XML);
btn.setOnClickListener(this);
}
public void onClick(View view)
{ int id = view.getId();
if (id == R.id.BUTTON_ID_AS_DEFINED_BY_YOUR_XML)
updateLayout()//Do your Click event here
}
public void updateLayout()
{ //updateLayout code...
}
}
Something that needs to be noted is the OnClick() above. Every OnClickListener must use the same signature as theOnClick() That means itmust have the same return and same arguments even if it has a different name. For what you are trying to do (in XML), you have set your android:OnClick to updateLayout. This means that `updateLayout() must be declared as follows:
public void updateLayout(View view)
Now, getting the update method to actually work: While you provide your code, we don't actually know what errors you are getting. It is always much easier to solve a problem if we have a copy of the Logcat output that includes the error you are receiving. Once, we have that we can target your error specifically and I can edit my answer to include what you may additionally need.
FuzzicalLogic

Beginner Android Dev question navigating through intents, getting errors not sure how to fix it. I've tried rearranging and everything even tabbing

I created this Sign-In page. I start by declaring variables for username/password & buttons. If user enters "test" as username & "test" as password and hits the login button, its supposed to go to the DrinksTwitter.class activity, else throw error message I created. To me the code and login makes perfect sense. I'm not sure why it wont go to the next activity I want it to go to
package com.android.drinksonme;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class Screen2 extends Activity {
// Declare our Views, so we can access them later
private EditText etUsername;
private EditText etPassword;
private Button btnLogin;
private Button btnSignUp;
private TextView lblResult;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Get the EditText and Button References
etUsername = (EditText)findViewById(R.id.username);
etPassword = (EditText)findViewById(R.id.password);
btnLogin = (Button)findViewById(R.id.login_button);
btnSignUp = (Button)findViewById(R.id.signup_button);
lblResult = (TextView)findViewById(R.id.result);
// Check Login
String username = etUsername.getText().toString();
String password = etPassword.getText().toString();
if(username.equals("test") && password.equals("test")){
final Intent i = new Intent(Screen2.this, DrinksTwitter.class);
btnLogin.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
startActivity(i);
}
// lblResult.setText("Login successful.");
else { /* ERROR- Syntax error on token "else", { expected */
lblResult.setText("Invalid username or password.");
}
}
});
final Intent k = new Intent(Screen2.this, SignUp.class);
btnSignUp.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
startActivity(k);
}
}); /* ERROR- Syntax error, insert "}" to complete Statement*/
}
}
I only briefly looked at your code, but I don't understand what you're doing (in that order).
You're checking the password & username on the OnCreate method, which, barring any autofilling, the textboxes will be blank.
Then you declare your onClickListeners.
Try restructuring it to be something like this (pseudo-code):
OnCreate
user = usertextbox
pass = passtextbox
login.setOnClick
if user == validUsername && pass == validPass
Intent i = new Intent(blah.this, blah.class)
startActivity(i)
else
Intent i = new Intent(blah.this, login.class)
startActivity(i)
This is how I have my app's login screen.
In short, you have to make the check occur in the OnClickListener of the action button, not in the OnCreate method of the activity. The way it is now, the form is created, and the textboxes are blank. Then immediately afterwards, they're compared against some values. That call will always fail to execute, so all of the code in your If statement scope will be ignored indefinitely.
Also, the reason Eclipse is giving you that error is because you're trying to place an else statement inside of a class definition.
When you declare a new OnClickListener() { }, you're essentially declaring a class. So you're in the class scope, not the if scope.
That would be like trying to do:
class test {
else {
doStuff();
}
}
I'm almost positive your problem is in setting an onClick() call instead of just starting the activity. It seems a bit complex of a call, and I think you're already checking the conditions in the appropriate place. Why do you need another onClick() call?
You should indent your code correctly. That syntax error is because you don't have a closing brace around the btnLogin.setOnClickListener. You then miss at least a couple more closing brackets.
Also, as others have posted, you check the edittext value before the onCreate() method even gives up control to the UI.
You set the button's click listener only if the strings match.
To me the code and login makes perfect
sense
You should slow down and take a look more carefully. It can't possibly make perfect is sense if there's syntax errors.

How is clickView used properly?

I'm trying to write a simple test app to run in JUnit. I've been having trouble getting clickView to click on the proper view. Below is some sample code that can be used on SkeletonActivity sample app that comes with the SDK.
public class SkeletonInstrumentation extends ActivityInstrumentationTestCase2<Activity>{
private Activity act;
private Button bClear;
private Button bBack;
private EditText eMain;
public SkeletonInstrumentation(){
super("com.example.android.skeletonapp", Activity.class);
}
public void setUp() {
String app = this.getInstrumentation().getTargetContext().getPackageName();
this.setActivityInitialTouchMode(true);
act = this.launchActivity(app, SkeletonActivity.class, Bundle.EMPTY);
bClear = (Button) act.findViewById(R.id.clear);
bBack = (Button) act.findViewById(R.id.back);
eMain = (EditText) act.findViewById(R.id.editor);
}
public void testClick()
{
TouchUtils.clickView(this, bClear);
}
public void testSendKeys()
{
act.runOnUiThread(
new Runnable(){
public void run(){
bClear.clearFocus();
eMain.requestFocus();
}
}
);
this.sendKeys("A B C D E F G ENTER");
}
}
testClick runs, but clicks on the main EditText view that has focus when the Activity starts and ends up bringing up the on-screen keyboard. I want it to click on the 'Clear' button below the EditText. Can someone tell me what's wrong here?
Adding the min and max target SDK in the AndroidManifest.xml worked for me; I got the idea from this answer. In the project that is being tested (not the test project) I added the following line to AndroidManifest.xml:
<uses-sdk android:targetSdkVersion="17" android:minSdkVersion="17"/>
and all of my uses of TouchUtils started behaving consistently again.
I had the same problem in this question and while I was able to find a workaround but it became really cumbersome so I spent more hours getting to the bottom of it.
The use of clickView here is correct. The problem was in the AndroidManifest.xml. Min and Target SDK must be set for it to work properly.

Categories

Resources