Running test that was created by Android Studio - android

When creating a new project in Android Studio, I notice that it automatically creates an /androidTest directory under /src, where there is "ApplicationTest.java" class with the following code:
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}
I'm guessing this is what Google wants us to use, but after searching for hours, I couldn't figure out how to use this class that was generated for me. Google's official doc seems to only list how to run on Eclipse IDE (not Android Studio), and I couldn't find any code that would let me perform a simple test (say like assertEquals(1,2)). Can someone show me how to write a simple test code using the above default template, and steps on how to run it, preferably from the command line?
EDIT:
I was able to write a simple test that is intended to fail.
ApplicationTest.java in /androidTest/java/path/to/package/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
#Override
protected void setUp() throws Exception {
createApplication();
}
#SmallTest
public void testMultiply() {
assertEquals("This should not pass ", 50, 49);
}
}
I am able to run this from Android Studio, but I just cannot figure out how to run that from the command line. Any help?

As Jared already said, this is an example setup for an instrumentation test.
I guess, you've already taken a look on this: Testing Fundamentals
Simpliest way to run these tests in android studio is to right click the class and click run.
It is also possible to add tests in your run/debug configurations.
UPDATE:
To run the instrumentation tests on command line, use ./gradlew assembleAndroidTest. This command will run all tests in your src/androidTest (instrumentation test) folder.
As njzk2 mentioned, there also is a ./gradlew assembleTest command. This command is for running all unit tests (which should be placed in the src/test folder). For more information about unit testing in android take a look on this: Android Unit Testing Support
EXAMPLE:
Here an example for an instrumentaion test in android:
#Override
public void setUp() throws Exception {
super.setUp();
InputStream is = getContext().getAssets().open("test.xml");
XmlParser parser = new XmlParser(getContext());
parser.parse(is);
...
}
#MediumTest
public void testSomething() throws Exception {
// test some data your parser extracted from the xml file
...
}
As you can see, i need the context for creating the input stream, therefor i have to go for an instrumentation test. The #MediumTest signals e.g. i'm accessing files from storage (see Test Annotations).

Related

Android Tests does not recognize my test method

I am trying to add some unit tests to my android app. Following is what I tried.
Created a directory for my tests and created a package for test classes inside it.
Created following test class in added package
public class MyFirstTest extends TestCase {
#Override
protected void setUp() throws Exception {
super.setUp();
}
#SmallTest
public void basicTest() {
assertEquals("abc", "abc");
}
#Override
protected void tearDown() throws Exception {
super.tearDown();
}
}
Created a new Android Tests build configuration in Android Studio
Specified module in build configuration settings and choose to run test cases of my test class (specified class name MyFirstTest in build configuration settings)
But, when I run my build configuration, it says that no tests were found in MyFirstTest class.
junit.framework.AssertionFailedError: No tests found in my.package.tests.MyFirstTest
What should I do to make basicTest() method to get identified as a test case?
You must name your tests testSomething(), that is starting with test

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.

Android Unit Test Not Reporting Failing with fail()

I've written a unit test that simply extends TestCase and I have the following:
public class MetricParserTests extends TestCase {
#Override
protected void setUp() throws Exception {
super.setUp();
}
#Override
protected void tearDown() throws Exception {
super.tearDown();
}
public void testFailure() {
fail("This needs to fail");
}
}
When I run my tests using ant test or adb shell am instrument I get the following results:
... [exec] OK (1 tests) ...
I'd expect to see a failure on the command line.
I believe I know what the issue is. I was able to reproduce the issue and solve it. The command you use does not rebuild and re-install your test project onto a device. When you call ant test it will just execute the tests which are already installed on that device.
What you need to call is the three commands in your test project's directory:
ant debug
ant installd
ant test
Then all tests will be rebuild and re-installed and latest tests will be executed. If you don't call debug and installd, the changes you did to the tests do not get applied.
I haven't had recent experience in Android testing, but here is what I have found...
You can use normal JUnit tests if your code is totally decoupled from Android (see here
for an example). This would run on your JVM using the JUnit runner.
However, if you are trying to run these tests on an Android device (either via ant, or the command line tools) then you need to create a full android test project (See here).
To test "on device" your test cases need to extend one of the Android test classes like ActivityInstrumentationTestCase2<T>
and are run using the InstrumentationTestRunner in the Dalvik VM on the Android device.
Using an IDE or the command-line tools to create a test project should create a sample test for you to work from.
This blog post linked from the comments of the post above is a good source of information, as is the Android Testing Fundamentals doc.
The method testFailure() does not have a #Test annotation. Is that correct?

Can I use Robolectric to unit test static library jars?

I'm trying to test a method in a jar library, and was hoping to use Robolectric to do my unit testing, rather than running the tests in the Android emulator. I'm running into a problem though, where Robolectric needs an androidmanifest.xml file that doesn't exist, since I'm building a library...
Is there any way to run Robolectric tests without an app?
Here's what my test case and code under test look like:
public class ObjectUnderTest {
methodUnderTest(View v) {
...
}
}
#RunWith(RobolectricTestRunner.class)
public class Tests {
#Test
public void methodUnderTest_Test() {
...
}
}
When I run the test suite I get a FileNotFoundException from Robolectric looking for androidmanifest.xml. I've tried using the JUnit4 test runner instead, but then I get the "Stub!" exception when I create a View for the argument to methodUnderTest().
Is there a way to do this besides creating a stub application just for the unit tests? Thanks!
It depends which Robolectric you're using.
If you use 2.0 you could try to annotate your test class with #Config(manifest=Config.NONE).
If you use 1.x I think it's doable but will require more effort:
You should folder create structure similar to Android project and create dummy AndroidManiifest.xml inside
You should extend RobolectricTestRunner and pass through constructor path to this fake Android project

Parameterized JUnit tests in Android test project

When I create parameterized test cases in JUnit 3.x, I usually create a TestSuite with something like
public static Test suite() {
TestSuite s = new TestSuite();
for (int i = MIN; i < MAX; ++i) {
s.addTest(new MyTest(i));
}
}
This suite() method is called correctly when running JUnit from a desktop command-line. When I tried this with my Android test project, the tests don't run. How do I get my tests to run on the emulator? Or is there a different way to create parameterized tests for Android?
More thoughts:
Typically I run my tests with the command line:
adb shell am instrument -w [-e class <fully qualified test class name>[#<test method name>()]] <Android package name>/android.test.InstrumentationTestRunner
This allows me to select which tests to run from my test suite. Ideally, I want to run the the parameterized tests in this way as well. The link in the comment from #Appu describes building a separate app that runs JUnit tests. As part of that, this app has a custom TestRunner. I can very likely borrow these ideas to create a TestRunner which I can use in place of android.test.InstrumentationTestRunner. This seems like a lot of work for a not uncommon task. I prefer not to reinvent the wheel if there is already a similar solution in the Android API. Does anyone know of such a thing? Also, other alternative solutions will be helpful.
Nevermind, it looks like #dtmilano already posted this as an answer...
You can implement a test runner to be able to pass parameters to Android tests.
See the example at how to pass an argument to a android junit test (Parameterized tests).
Or is there a different way to create parameterized tests for Android?
We (Square) wrote a library called Burst for this purpose. If you add enum parameters in your test constructor, Burst's test runner will generate a test for each combination of enum values. For example:
public class ParameterizedTest extends TestCase {
enum Drink { COKE, PEPSI, RC_COLA }
private final Drink drink;
// Nullary constructor required by Android test framework
public ConstructorTest() {
this(null);
}
public ConstructorTest(Drink drink) {
this.drink = drink;
}
public void testSomething() {
assertNotNull(drink);
}
}
Quite a while after originally writing this question, I discovered that I can directly run a test class which contains a static suite() method:
adb shell am instrument -w -e class <fully qualified test class name> <Android package name>/android.test.InstrumentationTestRunner
However, the test suite doesn't run when I try to run all the tests in a given package.
Of course, this has been a while. Now I am using Android Studio instead of the command-line. I can still run the test class individually, but it still doesn't run when I select a package or try to run all of my tests.
A potential alternative is to write a master test class with a suite() method which adds all the tests to the returned TestCase. Unfortunately, this requires some manually editing every time I add a new test class to my suite.

Categories

Resources