how to use Instrumentation under the uiautomator project? - android

I'm working on a uiautomator project recently and then the UiObject.getFromParent turn out a wrong element to me and I look into the source code of uiautomator and found out the answer is because by the UiSelector I used.
I found that the uiautomator is using the Instrumentation to get the UI element stuff just like :
getInstrumentation().getUiAutomation().getRootInActiveWindow();
I just want to get a AccessibilityNodeInfo node just like what uiautomator do but the uiautomator didn't exposed this.
I’m trying this way by a new class extends InstrumentationTestCase,by the getInstrumentation() always return a null to me.
i found an answer on
android instrumentation test case - getinstrumentation() returning null
that needs injectInstrumentation(InstrumentationRegistry.getInstrumentation());
and told InstrumentationRegistry is from the official Android testing-support-lib:0.1
I have download the Android Support Repository and import the testing-support-lib-0.1-source.jar into my project but I still can't see InstrumentationRegistry.
Anyone have any idea about my cast?

I'm using an extension of InstrumentationTestCase and it works just fine like this:
#Override
public void setUp() throws Exception{
super.setUp();
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
AccessibilityNodeInfo root = instrumentation.getUiAutomation().getRootInActiveWindow();
}
I imported
import android.test.InstrumentationTestCase;
import android.support.test.InstrumentationRegistry;
import android.view.accessibility.AccessibilityNodeInfo;
and installed
Android Support Repository (15)
Android Support Library (22.2)
Hope it helps.

well,this question has beep solved by
unpack testing-support-lib-0.1.aar and get the classes.jar instead of
testing-support-lib-0.1-source.jar
.and now the eclipse will not saying can't resolved anymore.By the way,u have to
add this lib to Ant's javac classpath by edit build.xml
or else u will get a lib not found while u trying ant build.
but now the NEW question has turns out
INSTRUMENTATION_STATUS: stack=java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/test/InstrumentationRegistry;
maybe it's another question so i am going to find out via google and i will update this if figure it out or i will post a new question.

Frist tried:
i have noticed that the point of this question is the uiautomator didn't expose the api i want,and when i look into the source and found the UiDevice.dumpWindowHierarchy that has these code:
AccessibilityNodeInfo root =getAutomatorBridge().getQueryController().getAccessibilityRootNode();
the getAutomatorBridge was implemented by UiDevice:
UiAutomatorBridge getAutomatorBridge() {
if (mUiAutomationBridge == null) {
throw new RuntimeException("UiDevice not initialized");
}
return mUiAutomationBridge;
}
the point is there is no modifier on it,so what i have done is modified it's modifier to public ,modified the byte code of
/system/framework/uiautomator.jar
and the other one in sdk(sorry i don't,ya it worked!i can use it like this.
AccessibilityNodeInfo root =getUidevice().getAutomatorBridge().getQueryController().getAccessibilityRootNode();
but there is a compatibility issue isn't it?
Second tried:
Let's think about the default modifier of java,we can access it under the same package,so why don't we just implement a class has the same Package name ?then we can call it without any unnomal patch.
that's what i have done and it really works well:
package com.android.uiautomator.core;
import android.view.Display;
import android.view.accessibility.AccessibilityNodeInfo;
public class AutomationUltilites
{
public AutomationUltilites()
{
}
public static AccessibilityNodeInfo getRootNode()
{
return UiDevice.getInstance().getAutomatorBridge().getRootInActiveWindow();
}
public static Display getDisplay()
{
return UiDevice.getInstance().getAutomatorBridge().getDefaultDisplay();
}
}
Hope it helps.

Related

Use SQLiteNetextensions with Xamarin for Android-App

I've read some threads about SQLite for Xamarin but I'm still not able to set up SQLiteNetExtensions in a proper way. I'm currently developing an android app with Target Framework Android 7.1(API Level 25 - Nougat).
Can anybody tell me what I'm doing wrong?
I installed nuget packages:
Install-Package SQLiteNetExtensions -Version 2.0.0-alpha2 -Pre
Install-Package SQLite.Net-PCL -Version 3.1.1
According to: https://bitbucket.org/twincoders/sqlite-net-extensions
Then I set up my code.
using SQLite.Net.Attributes;
using SQLiteNetExtensions.Attributes;
using System;
namespace AppName.Resources.Model
{
public class Entry
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[ForeignKey(typeof(Stock))]
public int StockId { get; set; }
public DateTime Date { get; set; }
public double Amount { get; set; }
}
}
using SQLite.Net.Attributes;
using SQLiteNetExtensions.Attributes;
using System;
using System.Collections.Generic;
namespace AppName.Resources.Model
{
public class Stock
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
public DateTime LastUpdated { get; set; }
[OneToMany(CascadeOperations = CascadeOperation.All)]
public List<Entry> Entrys { get; set; }
}
}
using Android.Util;
using AppName.Resources.Model;
using SQLite.Net;
using SQLite.Net.Platform.XamarinAndroid;
using SQLiteNetExtensions.Extensions;
using System.Collections.Generic;
using System.IO;
namespace AppName.Resources.DataHelper
{
public class DataBase
{
string folder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
public bool CreateDataBase()
{
try
{
using (var stocksDBConnection = new SQLiteConnection(new SQLitePlatformAndroid(), Path.Combine(folder, "Stock.db")))
{
stocksDBConnection.CreateTable<Entry>();
stocksDBConnection.CreateTable<Stock>();
return true;
}
}
catch (SQLiteException ex)
{
Log.Info("SQLiteEx", ex.Message);
return false;
}
}
public bool InsertIntoTableStock(object stock)
{
try
{
using (var stocksDBConnection = new SQLiteConnection(new SQLitePlatformAndroid(), Path.Combine(folder, "Stock.db")))
{
stocksDBConnection.InsertWithChildren(stock);
return true;
}
}
catch (SQLiteException ex)
{
Log.Info("SQLiteEx", ex.Message);
return false;
}
}
...
These References were added by nuget:
SQLite-net
SQLite.Net
SQLite.Net.Platform.XamarinAndroid
SQLiteNetExtensions
SQLitePCLRaw.Batteries_green
SQLitePCLRaw.Core
SQLitePCLRaw.lib.e_sqlite3
SQLitePCLRaw.provider.e_sqlite3
Occuring error:
'SQLiteConnection' does not contain a definition for 'InsertWithChildren' and the best extension method overload 'WriteOperations.InsertWithChildren(SQLiteConnection, object, bool)' requires a receiver of type 'SQLiteConnection'
'SQLiteConnection' does not contain a definition for 'GetAllWithChildren' and the best extension method overload 'ReadOperations.GetAllWithChildren(SQLiteConnection, Expression>, bool)' requires a receiver of type 'SQLiteConnection'
Well that's how far I get. Anybody out there who knows what to do? Maybe remove conflicting references?
Ok I'm sure that its just a version problem because I just tried your code and it works fine for me. Try installing SQliteNetExtensions v 1.3.0 package from the NuGet package manager window in Visual Studio and nothing else. It will install all its dependencies.
Here is what I did - Try to do the same and see if this helps :
I Created a new Android Single View App Project in Visual Studio
(I'm using community 2017 - but it should not matter ) and created
the Stock , Entry and Database Classes and pasted your given
code respectively.
I installed only the SQliteNetExtensions v 1.3.0 package from the NuGet Package Manager
It installed the following dependencies along with it, I didn't installed these myself.
SQLite.Net-PCL v3.0.5
NewtonSoft.Json v6.0.8
Here is what I got after installing just SQliteNetExtensions v 1.3.0 package.
As you can see its showing an update for SQLite.Net-PCL v3.0.5 to v3.1.1 I tired also with the updated one and it still works fine , so its up to you to update or not.
Here a bit proof that its working fine. I also compiled and run the app on emulator and it works all fine.
Ok after a bit of searching , I came to know that the creator of this extension used a pattern called MvvmCross while developing it. So unless you are using that pattern model you will get this error.
For non-MvvmCross users they have to rebuild the source files and reference it in their project and not use the pre-compiled one, the one you are using.
Go to the fourth post on the following link
https://forums.xamarin.com/discussion/20117/sqlite-net-extensions-and-sqliteconnection here he tells how to rebuild from source in his post in a very brief manner.
Hope you will understand it but if not wait till I install Visual Studio and Xamarin and try it out myself so I can give you accurate steps.
It will take a while so till then , Kudos!
Here is the link to source files https://bitbucket.org/twincoders/sqlite-net-extensions/downloads/
Click on download repository
After some research I found out that:
Install-Package SQLiteNetExtensions -Version 2.0.0-alpha2 -Pre
depends on
Install-Package sqlite-net-pcl
instead of
Install-Package SQLite.Net-PCL -Version 3.1.1
But after removing all references, cleaning the solution and reinstalling the two needed packages there is no SQLite.net available anymore.
When trying to use SQLite instead:
'SQLiteConnection' does not contain a definition for 'InsertWithChildren' and the best extension method overload 'WriteOperations.InsertWithChildren(SQLiteConnection, object, bool)' requires a receiver of type 'SQLiteConnection'
I'm curious if it's even possible to develop Android-Apps with VS seamlessly. Since everything takes years to set up.
EDIT:
Well, after some days of pain in the a** the solution was to use the even newer pre release (alpha3) which wasn't even referenced to on the official pages. Currently I'm satisfied. :)
Install-Package SQLiteNetExtensions-netstandard -Version 2.0.0-alpha3 -Pre
Hope anybody may need this.
I just solved this after doing a whole load of updates. Hit the same issues.
Uninstall ALL SQLite plugins. See attached pic/link below.
Reinstall SQLiteNetExtensions and this installs all dependencies too, actually all files in that list except SQLite.Net-PCL.
SQLiteNetExtensions installs SQLite-net-pcl but you need the other one too so, install SQLite.Net-PCL as well.
Restart Visual Studio as it doesn't always pickup all newly installed packages, the reopen your solution.
That worked for me so hopefully it'll help someone else here too.

Android studio says "Empty Test Suite" for AndroidTestCase [duplicate]

This question already has answers here:
Why is the Android test runner reporting "Empty test suite"?
(31 answers)
Closed 6 years ago.
I have created an example test case that extends AndroidTestCase. When I run the test case,
it errors out by saying
Running tests
Test running startedTest running failed:
Instrumentation run failed due to 'java.lang.RuntimeException'
Empty test suite.
The test case
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import static org.junit.Assert.assertEquals;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.lang.Exception;
import java.lang.Override;
public class DateFormatTest extends AndroidTestCase{
#Override
protected void setUp() throws Exception {
super.setUp();
}
#Override
protected void tearDown() throws Exception {
super.tearDown();
}
public DateFormatTest(){
super(DateFormatTest.class);
}
#SmallTest
public void testMultiply() {
assertEquals("10 x 5 must be 50", 50, 10*5);
}
}
Since nobody else mentions it: methods in AndroidTestCase subclasses need to be public and have names starting with "test"!
The OP and the answers all got this right but I missed it and got the exact same error.
I got this error when running tests from Android Studio. Turned out I had placed my test cases in the wrong folder. When running Gradle/Android Studio, all Android tests should be in the folder src/instrumentTest/java.
Edit: In Gradle plugin version 0.9 or later the correct name of the folder is androidTest. (http://tools.android.com/tech-docs/new-build-system/migrating_to_09)
I understand that this question is old, and the development tools have changed significantly since this question has been asked.
However, I had a similar issue (in AndroidStudio 2.1.1) and it turned out that it was just the error message that was quite misleading. For me it said:
Test running started
Test running failed: Instrumentation run failed due to 'java.lang.IllegalStateException'
Empty test suite.
(Note: The difference to the original question is in IllegalStateException vs. RuntimeException)
It turned out that this IllegalStateException was actually thrown in the initialization of the application context as can be seen by inspecting the logcat output. As a result, no test-methods were run, and Android Studio writes this somewhat misleading "Empty test suite" error.
I.e. "Empty test suite" can mean what it actually says (you don't have any test methods declared, e.g. because you forgot to annotate them with #Test), but it can also mean that something (like a runtime exception thrown in your application initialization code) prevents the test-runner from reaching any test methods (which seems to be your case).
Check adb-logcat and search for RuntimeExceptions. This will probably find you the root-cause of your problem.
I got this error because one of my test methods didn't include "throws exception" after the method signature. might help somebody
I got the same issue. I was having testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
in my defaultConfig {...}. I have just removed that line, and now it's working fine (The IDE is picking the right runner config on build time).
I hope this will help someone.
My problem was I had default constructor generated by android studio, looked like this
public class SomeTest extends ActivityUnitTestCase<ActivityYouWantToTest>{
public SomeTest(Class<NewsActivity> activityClass) {
super(activityClass);
}
}
and I had to change it to this to get rid of the problem
public class SomeTest extends ActivityUnitTestCase<ActivityYouWantToTest>{
public SomeTest() {
super(ActivityYouWantToTest.class);
}
}
We use the AndroidTestCase class to define that we are testing components which are specific to Android. The main benefit of AndroidTestCase is that it gives us access to the application's Resources such as strings and layouts, etc.
The AndroidTestCase does not require you to overwrite the default constructor as it does not provide a particular Activity as the Context, but rather provides you a general one so you can still call getContext().
In your example, you are not using any Android components, so for you, the following would make sense:
import android.test.suitebuilder.annotation.SmallTest;
import junit.framework.TestCase;
public class DateFormatTest2 extends TestCase {
#SmallTest
public void testMultiply() {
assertEquals("10 x 5 must be 50", 50, 10 * 5);
}
}
Notice the use of TestCase rather than AndroidTestCase.
For AndroidTestCase to be applicable, a test that requires resources would be necessary:
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
public class DateFormatTest extends AndroidTestCase {
#SmallTest
public void testAppTitle() {
assertEquals("MyApp", getContext().getResources().getString(R.string.app_name));
}
}
Here we use the AndroidTestCase because we need to access the application's resources.
This guide might help -
http://www.slideshare.net/tobiaspreuss/how-to-setup-unit-testing-in-android-studio
On the latest gradle (0.9+) the test should be under androidTest dir
Also in your gradle.build:
dependencies {
androidTestCompile 'junit:junit:4.+'
}
also add those under defaultConfig {
testPackageName "test.java.foo"
testInstrumentationRunner "android.test.InstrumentationTestRunner"
}
Did you configure your testRunner in your gradleConfig?
We use different TestRunners for different tests (to speed things up. My config looks like this
android {
// Some stuff
defaultConfig {
// Some other stuff
//junit test
testInstrumentationRunner "de.qabel.qabelbox.QblJUnitRunner"
//ui tests
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
}
If i disable one of this lines the corresponding test will also report "Empty Test Suite".
I just started learning about testing Android applications and I've been struggling with the same problem. You need to provide default constructor for your test class, for example:
package nilzor.myapp.tests;
public class NilzorSomeTest extends ActivityUnitTestCase<ActivityYouWantToTest>{
public NilzorSomeTest(){
super(ActivityYouWantToTest.class);
}
#SmallTest
public void testBlah(){
assertEquals(1,1);
}
}
I already have a default constructor in my test case but still it was giving me error "Empty test suite" and was stuck at "Instantiating tests...".
Tried creating new workspace, resetting Android Studio, but that didn't work.
Finally, close Android SDK and emulator.
Go to your android-sdks/platform-tools.
Clear all Android temp files with these commands:
a. rm -rf ~/Library/Application Support/AndroidStudio
b. rm -rf ~/Library/Caches/AndroidStudio
c. rm -rf ~/Library/Application Support/AndroidStudio
d. rm -rf ~/Library/Preferences/AndroidStudio
Run:
./adb kill-server
./adb start-server
Start Android and run test case.

Simple Java class test with Android SDK

I would like to know how to test a simple Java class in an Android project which do not use any android SDK code, using the (JUnit based) test framework included with the android sdk.
Or if I would have to use an external (JUnit) test library?
Regards.
Thanks All, I get a clue with this link https://marakana.com/tutorials/android/junit-test-example.html, but i had to tweak it a little bit to fit my needs.
So if one want to write tests for a simple class in an android project, using the android test framework, let's say a Calculator class.
package com.example.application;
public class Calculator {
public static int add(int a, int b){
return a+b;
}
public static int sub(int a, int b){
return a-b;
}
}
You will have to create the following test class in your test project:
package com.example.application.tests;
import android.test.AndroidTestCase;
import com.example.application.Calculator;
public class CalculatorTest{
public void testAdd() throws Throwable{
assertEquals(3, Calculator.add(1,2);
}
public void testSub() throws Throwable{
assertEquals(-1, Calculator.add(1,2);
}
}
And with the command line, after compiling and installing both the main project and the test project, on the emulator (for instance), you can use the following command to test the class:
adb shell am instrument -w -e class com.example.appplication.tests.CalculatorTest com.example.application.tests/android.test.InstrumentationTestRunner
You can also use Eclipse to run the tests.
Hope this will help someone.
Use the test framework from your android sdk.
That way you can test your android code too if you want to do that later.
Testing Android

AndroidWebDriver class missing in Selenium-Java library

I tried a example provided in the, Android app testing through Selenium, i have included the selenium-java library and android-webdriver apk also installed in emulator, but when try with the sample code provide in the forum i got error in AnroidWebDriver import, in selenium library only AndroidDriver class is available, so where could i get the AdroidWebDriver jar. Plz assit.
Note: Selenium library is very latest one.
import android.test.ActivityInstrumentationTestCase2;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.android.AndroidWebDriver;
import simple.app.SimpleAppActivity;
public class SimpleGoogleTest extends ActivityInstrumentationTestCase2<SimpleAppActivity> {
private WebDriver driver;
private WebDriver googledriver;
public SimpleGoogleTest() {
super("simple.app", SimpleAppActivity.class);
}
#Override
protected void setUp() throws Exception {
driver = new AndroidWebDriver(getActivity());
}
........................,,,,,
}
There are two variations of the Android Driver:
AndroidDriver() which you use on your Personal Computer e.g. your
laptop, workstation, etc. which provides the richest and most
complete set of capabilities for your tests.
AndroidWebDriver() which runs on your Android device, this wraps a WebView component to provide the basic core functionality.
The example code that comes with the Android SDK and the optional support for Selenium/WebDriver runs some basic tests on the device. The tests are compiled as an Android program which extend ActivityInstrumentationTestCase2. AndroidWebDriver() is contained in sdk/extras/google/webdriver/android_webdriver_library.jar (and the Javadocs are in sdk/extras/google/webdriver/android_webdriver_library-srcs.jar
So, if you want to run your tests on your Android device, then you need to include android-webdriver-library.jar in your project. Perhaps the simplest way is to copy this jar into your test project's libs folder.
However, if you would like to run your tests on your Personal Computer you can modify the example code to use AndroidDriver instead of AndroidWebDriver. You also need to change your base class e.g. to use Junit 3 or Junit 4. I have posted a sample test as an answer to another question on Stack Overflow here Having difficulty in finding Elements using Xpath and CSS in Selenium Android Webdriver Testing

Unable to run Bitmap sample code for Android

I am trying to run the sample from :
http://developer.android.com/training/displaying-bitmaps/display-bitmap.html
However I encountered lots of errors like:
Description Resource Path Location Type
BuildConfig cannot be resolved to a variable ImageGridFragment.java /ImageGridActivity/src/com/example/android/bitmapfun/ui line 124 Java Problem
Description Resource Path Location Type
SuppressLint cannot be resolved to a type Utils.java /ImageGridActivity/src/com/example/android/bitmapfun/util line 99 Java Problem
I ran thru Google but could get nothing. Adjusted the android build target to 4.0.3 (15) but still no clue. Anyone ran this sample successfully?
Thanks.
Here is my solution:
1.Create a new class:
package com.example.android.bitmapfun;
public class BuildConfig {
public static final boolean DEBUG = true;
}
2.Comment the lines that contain "SuppressLint":
//import android.annotation.SuppressLint;
// #SuppressLint("NewApi")
Android developer tools r17 brings a feature to Eclipse where a class is auto built at build-time, called BuildConfig, which contains a constant that can be used by the app developer to sense whether the build is a dev build or a production build. This feature appears to be in the Eclipse integration support, so when using IntelliJ, this useful feature is not available
In gen folder with R.java there should be BuildConfig.java if your program compiled successfully.
/** Automatically generated file. DO NOT MODIFY */
package com.example.android.bitmapfun;
public final class BuildConfig {
public final static boolean DEBUG = true;
}
Clean your project and try to launch it again.
It worked for me.
For me also it is not running directly import to eclipse. Just i put comments which lines is showing errors then it is working fine for me. May be it is not a right answer but we can see the application functionality by running the code so i did like that.

Categories

Resources