Why do you need to have an emulator or device plugged in for the testing to take place? Why can't I just generate coverage for my tests without the use of these?
It all depends on your Unit-Test.
If you're testing classes that dont use at all the Android Framework, and only the standard Java classes, then you could run the Unit test and get a code coverage (althouhg I don't have a step by step procedure to give you).
But if you're using any part of the Android Framework (that is, any class in an android.* or com.android.* package), then you'll need to run in a DalvikVM, meaning an Android emulator.
Related
I will want to run a functional tests on firebase on various devices. Does firebase support functional testing in android?
Their testlab has three types of tests:
Robo test
Instrumentation test
Gameloop
Robo test is ruled out as it is just a stress test and a load test like a money runner
When it comes to instrumentation test, first thing I want to be clear on whether it is a functional test written in expresso, UIautomator and ranorex?
If yes, I see that I have to upload two .apk's in there, one is AppApk and TestApk. I would like to know if AppApk is the application under test and TestApk is the apk that is created to test the application?
If yes, I found uiautomator tests are bundled inside the src folder and is a java file. I also found that, there is a python wrapper for uiautomator that can be coded to write tests for android.
Now there is kivy.org to bundle python file into an .apk since android studio does not support python.
Now, How do i run Android uiautomator tests in python? Is there a way, to run python scripts inside the android studio?
And How to run functional tests in firebase? Do they support?
I tried to look around about how to launch an automated test in multiple devices, but I couldn't really find what I was looking for.
I have like 5 tests per class and I want to execute just one test in all my connected devices, like a End to End test to login.
I tried to use connected device but it doesn't launch only the test I want...
I'm using Espresso, UIAutomator, Gradle and AndroidStudio.
How can I run that single test in my devices using these tools?
Use gradle connectedCheck command
You can find an example app here from google
https://github.com/googlesamples/android-testing-templates/tree/master/AndroidTestingBlueprint
There you can also read how to run the example tests on multiple devices from the command line / terminal, or from within Android Studio
You can also take a look at Spoon if you want to use an external tool plugin:
https://github.com/square/spoon
good luck
I have created a cordova plugin which has an android implementation. This Java code has calls into an SDK that interfaces with specific hardware that the mobile device is connected to. I would like to write unit tests for my Java code and mock all the calls into the SDK so that I can run the tests during CI.
When looking into this, I found the cordova-plugin-test-framework, but from what I can tell, this is for tests that you would write against the javascript code, not the actual platform implementations. I'm sure I could use it and write some tests, but it would require the mobile device to be connected to the hardware, and I don't want to have actual calls into the SDK. In other words, I don't have a way of mocking the SDK calls using this.
I thought maybe I could just run JUnit from the command line with my Java code, but then I was getting errors because it couldn't find org.apache.cordova.CallbackContext. I tried faking my own object, but as I continued, I found more dependencies that my code in isolation just doesn't know about.
Next I figured it would be best to test it within the android project under /platforms in my ionic mobile app, since all the dependencies would be visible at that point. I'm able to run ./gradlew test (https://developer.android.com/studio/test/command-line.html) from here, but I can't figure out how to implement the test cases so that this call will pick them up. Is there some kind of config I can add so it knows where to look for tests? I'd be fine if there was just a certain place I had to put them.
I'm open to any options with this. I just want to be able to run JUnit test as part of our CI process.
I have some plain old Java classes and simple JUnit tests in my Android Studio project. They currently live inside my Android Module. If I run them as Android tests they pass fine, but they're really slow as it requires launching or connecting to the emulator.
If I try to run one as a JUnit test, I hit the !!! JUnit version 3.8 or later expected JUnit version problem. This answer explains how to workaround that issue. Unfortunately, I then hit the java.lang.NoClassDefFoundError: junit/textui/ResultPrinter, which I can't figure out how to fix.
I then tried to move my JUnit tests into a separate Java module that depends on the Android Module. Everything compiles fine. I added a new configuration to launch the JUnit tests (:MyJUnitTests:test), but the tests fail with package com.myproject.util does not exist. It looks like maybe the classpath isn't including the classes from the dependent Android Module.
Does anybody know how to fix this classpath issue? I've looked at lots of related answers and none of them seem to work for me. Or is it a just a bad idea to try and keep my JUnit tests in their own Module?
I can get the JUnit tests to run fast and pass if I move my plain Java classes and their JUnit tests into a completely separate Module (e.g. here), and reverse the dependency so the Android Module depends on the Java Module. Is that the preferred solution?
The basic problem is that Android Framework classes don't work well outside the context of Android OS, so any code that has dependencies on Framework classes doesn't run in a regular JUnit environment, as you've found.
Your solution of trying to move the JUnit tests into a separate module won't work because you can't have a plain Java module depend on an Android module. Android Gradle modules don't act like Java modules, because Android builds are much more complex, and because the end result of an Android module build will be an APK or an AAR, which other module types won't understand.
If you can move your plain Java classes and unit tests into a plain Java module and have the Android modules depend on that, it will be the best approach that will get the most support from official features in the IDE. It will also have an architectural benefit in that it will keep those classes free from Android abstractions, making it more portable, and enforcing a separation of business logic from UI or storage or other things more device-specific.
If that's difficult for you to do, then a lot of developers in your shoes go with Robolectric, which is a test harness allowing code depending on many parts of the Android Framework to run in a JUnit environment without an emulator or device. It's not officially supported by Google, but Google is aware that it's widely used and tries hard to not wantonly break it.
I have a Robolectric test project setup, but I'd like to also run these tests on my device to check that I don't get bit by JVM vs Dalvik implementation differences.
Unlike robolectric tests, I won't run these tests frequently. My concern is that there's little effort to maintain the test suite and that they verify actual device functionality.
What's the best way to do that?
What I've currently got:
My robolectric test project as a test case TestPackage. I created an Android Test project with a test case TestRoboOnAndroid. It creates a TestPackage and has a test for each test in TestPackage.
Right now, every time I add a test to my robolectric suite, I need to manually add it to my device suite. Is there some way to do that automatically with reflection?
Also, Robolectric uses JUnit 4 (by default) and Android uses JUnit 3. So I have to write all of my Robolectric tests using JUnit 3 style (importing from junit.framework instead of org.junit).
The whole point of Robolectric is NOT to run it on the device and the design is based on that. If you want to run something on the device look at the default instrumentation tests from the SDK or Robotium.
It is totally feasible to run your Robolectric tests on the JVM and in addition create Robotium tests that rely on device specific interaction (e.g. creating screenshots, hardware differences...) and run on devices and emulators all combined into one build.
The easiest way to do that is to use the Android Maven Plugin.
I use a tiered system, where I prefer earlier tiers where possible:
Pure unit tests. I try to make as much code as possible fully independent of Android APIs, and then use "pure" unit tests which can run on any JVM. These tests are the fastest, and it helps keep code that has no need to be Android-specific portable.
Robolectric-supported unit tests. Where my code has only small dependencies on Android APIs, that can be satisfied by Robolectric shadows, I test it with Robolectric. There is a little more setup time for Robolectric compared to pure tests, but it's still faster than starting/running on an emulator.
Android framework tests. Where Robolectric doesn't cut it - either because the shadows don't exist, or because I'm heavily using Android APIs (and therefore want to test against the Real Thing) - I write test that run on the emulator/device with the default framework.
The point of the tiers is to keep things as simple as possible, which keeps the full suite faster and helps promote cleaner code.
We use Robolectric for unit testing against the JVM and Calabash-Android for system testing against Dalvik. Both can be integrated into our Jenkins CI build and between the two tools I feel that we cover all the bases.