Android JUnit4 testing - android

I want to run some JUnit4 tests. The code relies on some Android libraries(Android XML parser), but does not create any activites and so on. When I try to run tests I got that an Android class that I need was not found. Is there any way to run JUnit4 tests with Android code, not to test activity but to test code with some libraries.

I had the same problem and tried to adapt JUnit4 to Android's existing TestRunner - without success. Therefore I created a new project called JUnit4Android. It's a TestRunner application library for JUnit4 and JUnit3 tests and test suites. So you can run your existing JUnit4 tests with it. Please find more information on GitHub:
https://github.com/dthommes/JUnit4Android/wiki

There is no way (that I'm aware of) to use JUnit4 on Android. It does support JUnit3 though, if that's an option for you?
Alternatively, you could use Robolectric and run your tests on your development machine (where you'll be able to use whichever unit test framework you like). Whether this will work for you depends on exactly what you're testing, but it might be worth a go?

It might be little bit late, but there's finally an official update from Google about junit4:
based on Android-test-kit project and some other sources it's clear that:
The AndroidJUnitRunner is a new unbundled test runner for Android, which is part of the
Android Support Test Library and can be downloaded via the Android
Support Repository. The new runner contains all improvements of
GoogleInstrumentationTestRunner and adds more features:
- JUnit4 support
- Instrumentation Registry for accessing Instrumentation, Context and Bundle Arguments
- Test Filters #SdkSupress and #RequiresDevice
- Test timeouts
- Sharding of tests
- RunListener support to hook into the test run lifecycle
- Activity monitoring mechanism ActivityLifecycleMonitorRegistry
Actually, it's already presented in Support Repository. If You go to
%ANDROID_HOME%\extras\android\m2repository\com\android\support\test\testing-support-lib\
it's possible to find testing-support-lib in there (aar, jars etc.) which allows to use JUnit4. Even more, it contains espresso library same location which is handy for UI testing. Seems Android sites and support lib official references will be updated soon with that info.

Related

How to run a Junit5 test with Android dependencies and robolectric

I am trying to run a unit test like that:
#org.junit.jupiter.api.Test
void junit5codeCoverage() {
final int result = new Foo().junit5();
Assert.assertEquals(Looper.getMainLooper().getThread(), Thread.currentThread());
assertEquals(-1, result);
}
That is a Junit5 test with Android dependencies (i.e Looper.getMainLooper()) with Robolectric.
I am using the junit5 android plugin from mannodermaus that allows running junit5 within Android setups. But this does not work out of the box because it would not load robolectric. So I tried alixwar's branch that would tackle robolectric and junit5 test coverage, but still, would not use Android classes.
I furthermore started to investigate how to run a robolectric test on junit5, which would require understanding how the RobolectricTestRunner works and how to port the code to the JUnit5 platform. I have little understanding of the new junit5 platform, but I figured out that I could build on top of the org.junit.platform.runner.JUnitPlatform runner, to follow the test runner concept, which is part of the junit-platform-runner package. But this is so far away from the original Junit4 SandBoxTestRunner that I couldn't manage to complete the port.
So what would be the most feasible path to implement robolectric junit5 support, or is there any (obvious) concept I am missing?
I am trying to do this too, but it seems that at the time of this writing, Robolectric simply does not support junit5.
See the discussion here: https://github.com/robolectric/robolectric/issues/2996
Some workarounds are described in that discussion, but for now I am just going to stick to junit4.
You can use junit-vintage-engine to run test with runners from JUnit4.
Just add org.junit.vintage:junit-vintage-engine to your dependencies, thus you can org.junit.runner.RunWith annotation to your tests.

Kotlin REPL with Android Classes unStub!ed

I like the Kotlin REPL in Idea / Android-Studio - but as an Android Developer I often run into Stub! problems here. When writing unit-tests I am using unmock to work around this problem. Is there a way to use the same method used there for the Kotlin REPL plugin?
[
All android (and java.lang.*) classes are placeholders in an Android project. This is because android does not use standard java class files to store the compiled code and there is no way to directly run this code on a computer.
You simply can't use the REPL with android classes, they will only exist on an actual device or emulator.
If you do not care about correctness, then you can use Robolectric's implementation of Android by adding it as a dependency to the project.
To make sure it does not collide with the actual implementation you should probably do this with a separate module dedicated to the REPL.
Robolectic's dependency used by unmock is: org.robolectric:android-all:7.1.0_r7-robolectric-0
The problem is that the Kotlin REPL in IDEA is provided by the Kotlin IDEA plugin, which has no notion of Android per se, but only looks at what's in the classpath, which in this case is the android.jar containing the stubs that throw the exception you mentioned.
Using unmock or even the integrated Android support for removing exceptions from the stubs in tests (see here at the end of "Mock Android dependencies") won't work as that only affects your Gradle build.
The only solution I can think of is to either open an issue on the Kotlin tracker or dig through the source code of the REPL function in the Kotlin plugin and send a Pull Request.

Having both JUnit and Cucumber tests in a single Android project

I am looking to introduce Cucumber tests into my Android application. In order to do that, I need a custom test instrumentation runner that makes use of CucumberInstrumentationCore as described here.
However I already have Espresso tests that are driven by JUnit, and I therefore already have a custom test instrumentation runner that uses AndroidJUnitTestRunner.
It seems to me that a custom implementation cannot use both simultaneously, because the onStart() methods of each call finish() on the tested activity.
It seems that my options are:
Copy the source code of both CucumberInstrumentationCore and AndroidJUnitTestRunner and produce a new, combined test runner that performs the necessary parts of both
Or...
Have the JUnit tests in the androidTest folder, and create a new instrumentation test folder alongside androidTest which contains only the Cucumber tests. Is this even possible?
How can I proceed, and have I missed a more elegant way of doing this?
I ended up producing a combined instrumentationTestRunner which seems to work OK:
https://gist.github.com/dhoskins/98afa6976c87cb20328d42065c7292ee

How do I generate test reports from Espresso

I have a test project running successfully on Jenkins using Ant. I see the test results in the console output but how do I generate a report?
I use Jenkins and Espresso also. I use Spoon by Jake Wharton to generate my reports. Take a look! They are clean and very easy to use.
Without using Espresso this can be done easily by using the JUnitReportTestRunner from Zutubi. The report can then be digested e.g. via the Jenkins xUnit Plugin
Espresso though requires its own testrunner that has to be based on GoogleInstrumentation. Combining both the JUnitReportTestRunner and the GoogleInstrumentationTestRunner is quite hacky at the moment, because GoogleInstrumentationTestRunner does not expose a method to attach a test listener. This google groups post shows how to attach the listener from the Zutubi project anyway.

Trying to understand android testing

I'm a long time Java developer with many years of Java EE, Ant, Maven, unit testing, mocks, etc. I'm currently using gradle to build android apps and am looking at unit testing them. And it's got me tearing my hair out!
My reading indicates that to test an app, I have to create another app inside it in a test directory. But I'm not sure how this embedded app can see the main apps classes. I presume that google came up with this because of something to do with the manifests which are different. I'm not sure why.
Without doing this embedded app system, I've been able to get unit tests to run by including the test classes with the main classes in the APK, adding the instrumentation declarations to the manifest, deploying it and running the test runners. But I don't want to be compiling test classes with app classes and including all the dependencies so that's not really an option and I'm not really sure of the effects of the changes to the manifest as I cannot find any documentation about the effects.
None of this is understood by gradle which follows the maven system of building. Also note that the android way seems to be that the embedded sub-project (test) is dependant on the main parent project, something that is totally contray to gradle and maven.
Another option seems to be separate the test project so that it's completely outside the app project. But really, I'd like to use a similar convention to maven and simply have tests in a separate directory, along with the manifest in test resources.
Has anyone managed to get testing on the emulators running unit tests following a more maven like directory structure?
You can try Robotium. It provides lots of features for a better testcase. You can have a look at it here.
Do you have to run the unit tests in the emulator? Isn't that too slow? I've been using robolectric ( http://pivotal.github.com/robolectric/ ) which creates shadow objects that work similar to mocks. I use progaurd ( http://proguard.sourceforge.net/ ) to strip out the tests for the release build.

Categories

Resources