Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Failed to use Appium + Android Studio 3.0 + Java 8

I am trying to use appium java client for my Android UI test. However, I Cannot make it run. Here is my build.gradle and my error message.

apply plugin: 'com.android.application'

android {
compileSdkVersion 26
defaultConfig {
    applicationId "com.example.wpjtest2"
    minSdkVersion 26
    targetSdkVersion 26
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}
}

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.uiautomator:uiautomator-v18:2.1.3'
androidTestImplementation 'io.appium:java-client:5.0.4'
}

error:

Information:Gradle tasks [:app:assembleDebug, :app:assembleDebugAndroidTest]
Error:java.lang.IllegalAccessException: no such method:     org.springframework.core.io.buffer.DataBufferUtils.lambda$read$0(ReadableByteChannel)ReadableByteChannel/invokeStatic
Error:java.lang.NoClassDefFoundError: org/reactivestreams/Publisher
Error:java.lang.ClassNotFoundException: Class org.reactivestreams.Publisher not found
Error:java.nio.file.DirectoryNotEmptyException: C:\Users\zil\AppData\Local\Temp\lambdas5516872364251960030\org\springframework\core\io
Error:java.lang.IllegalAccessException: no such method: org.springframework.beans.factory.config.YamlMapFactoryBean.lambda$createMap$0(Map,Properties,Map)void/invokeSpecial
Error:java.lang.NoClassDefFoundError: org/yaml/snakeyaml/reader/UnicodeReader
Error:java.lang.ClassNotFoundException: Class org.yaml.snakeyaml.reader.UnicodeReader not found
Error:Execution failed for task     ':app:transformClassesWithDesugarForDebugAndroidTest'.
> com.android.build.api.transform.TransformException: java.lang.RuntimeException: java.lang.RuntimeException: com.android.ide.common.process.ProcessException: Error while executing java process with main class com.google.devtools.build.android.desugar.Desugar with arguments {@C:\Users\xxx\project\WPJTest2\app\build\intermediates\tmp\desugar_args221997254795871866}
Information:BUILD FAILED in 15s
Error:java.lang.ClassNotFoundException: Class javax.validation.Validator not found
Information:9 errors
Information:0 warnings
Information:See complete output in console

Can anyone check for me to see whether I have correct and sufficient dependencies? There are so many tutorials for adding Appium but none of them works for me.

On the other hand, if I can use Java 7 to integrate with Appium, how should I do instead?

like image 854
James Liu Avatar asked Feb 11 '18 06:02

James Liu


1 Answers

Although Appium is well documented and versatile, the working combination for Android Studio took me a working day. In my case it was a substitution for Espresso, because it doesn't currently support multi-feature testing for Instant Apps. Also Appium gives wider possiblities to test app integration, like Firebase messaging, using other apps etc.

  1. Install Appium Server as UI.
  2. Setup Appium Server for your localhost:
    • Host: 127.0.0.1 Port: 4723
    • Edit Configurations -> Set ANDROID_HOME and JAVA_HOME paths.
    • Start server. You'll see a console, leave this window open. Start Appium Server
  3. Run Android Emulator from Android Studio.
  4. Start Appium Session for your Emulator in Appium UI (File -> New Session Window): Start Appium Session
  5. If everything goes fine and console shows no log errors, then Appium Inspector window will open. Also your app will be run in the Emulator. In Inspector find elements by clicking on a screenshot. Record your actins with buttons atop and get autogenerated code: enter image description here
  6. Add libraries to your project app or my_feature gradle file. Appium and Selenium versions should watch to avoid "No such method error" - see an answer:

    dependencies {
      androidTestImplementation 'junit:junit:4.12'
      androidTestImplementation 'io.appium:java-client:5.0.1'
      androidTestImplementation 'org.seleniumhq.selenium:selenium-java:3.4.0'
    }
    
  7. Create a JUnit functional test class in your Android project .../src/androidTest/java/ folder. You can use simple JUnit test wrapper as well. For testing needs you could have created a separate Java project or Java class with main method inside your Android project, but it is more convenient to integrate Appium tests into Android Studio testing features. Also check that you don't import other testing libraries and don't use it as a mix in your code (e.g. @Test is available for TestNG as well as for JUnit). Use autogenerated code from Appium Inspector inside your methods like:

        package com.example.my_project;
    
        import org.junit.After;
        import org.junit.Before;
        import org.junit.Test;
        import org.openqa.selenium.remote.DesiredCapabilities;
    
        import java.net.MalformedURLException;
        import java.net.URL;
    
        import io.appium.java_client.MobileElement;
        import io.appium.java_client.android.AndroidDriver;
    
        public class SampleTest {
    
          private AndroidDriver<MobileElement> driver;
    
          @Test
          public void testPlan()
            throws MalformedURLException {
    
            setUp();
    
            testWorkUnit_WithCertainState_ShouldDoSomething();
    
            abotherTestWorkUnit_WithCertainState_ShouldDoSomething();
    
            tearDown();
    
          }
    
          public void setUp()
            throws MalformedURLException {
    
            DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
            URL remoteUrl = new URL("http://localhost:4723/wd/hub");
    
            desiredCapabilities.setCapability(
              "platformName",
              "Android");
    
            desiredCapabilities.setCapability(
              "deviceName",
              "Android Emulator");
    
            desiredCapabilities.setCapability(
              "appPackage",
              "com.example.my_project");
    
            desiredCapabilities.setCapability(
              "appActivity",
              "com.example.my_project.MyActivity");
    
            driver =
              new AndroidDriver<>(
                remoteUrl,
                desiredCapabilities);
          }
    
          public void testWorkUnit_WithCertainState_ShouldDoSomething() {
    
            MobileElement el1 = 
             driver.findElementById(
               "com.example.my_project:id/urlField");
    
            el1.sendKeys("example.com");
          }
    
          public void tearDown() {
    
            driver.quit();
          }
        }
    

As for annotations in code: @Before and @After are used before and after each test case in your class (@BeforeClass and @AfterClass requires static and is not handlful). Therefore it restarts the app every time as a result and its not convenient for chaining tests. So it's better to have one method annotated with @Test, which will call other unannotated methods for setting up, doing test case in required order and finishing.

like image 63
Zon Avatar answered Oct 21 '22 09:10

Zon