When writing android espresso UI test, is it possible to write parameterized test which accepts data from two different json files to add list of items inside the app?
I have seen parameterized tests that take two files and run same test code for junit test but couldn't find any references for android espresso UI test
You can do something like:
#RunWith(Parameterized.class)
public class LoginTest {
#Parameterized.Parameter
public String mUserName;
#Parameterized.Parameter(value = 1)
public String mPassword;
#Parameterized.Parameters
public static Collection<Object[]> initParameters() {
return Arrays.asList(new Object[][]{
{"validUsername", "validPassword"},
{"invalidUsername", "invalidPassword"},
// or other initialization like json file input
});
}
// Tests using mUserName and mPassword
}
Then every Test will run with each element of you parameters array.
Please take a look at the library https://github.com/google/TestParameterInjector , it is very convenient and the next evolution step of JUnit4 Parameterized.
Related
I'm implementing tests on my Android app and I want to do unit tests on a model. The problem is that I do not have setters as the model is created with Realm or by parsing a CSV file (witch univocity csv parser).
So, how could I create a mocked object with valid values? I have something like that:
public class Content {
private String title;
private String description;
...
}
How could I generate a mocked Content object with a title and description data?
Thanks in advance
Use code below in your test class:
Field field = Content.class.getDeclaredField("str");
field.setAccessible(true);
field.set(yourObject, "some value");
yourObject is a instance of Content that you use in your test class.
But you shouldn't fill mock object - you should just define method result for mock object.
A word of warning: reflection has a lot of disadvantages; for example a simple name change for your fields will go unnoticed; and not lead to compiler errors but to failing unit tests later on.
This I suggest a different solution - providing a package-private or protected constructor that you can use to initialize your fields. Then you do not to use reflection; and at the same time, your "public" interface of that class doesn't change either, like:
public class Content {
// unit testing only
Content(String title, ... ) { ...
But of course, you have to do balancing - either you add that constructor that isn't required for production; or you go with not so robust reflection code!
The follows was the code which I want to test.
public class Demo {
private static final List<Pair<String, String>> mList;
static {
mList = new ArrayList<>();
mList.add(new Pair<>("F0", "T1"));
mList.add(new Pair<>("F1", "T2"));
mList.add(new Pair<>("F2", "T3"));
}
public String getStr(int pos) {
return mList.get(pos).first;
}
}
I was an android developer. I have get some trouble in test and mock the code.I have use mockito.
I have try some code to test it,but the result was not my expect.
1.First try
#Test
public void test(){
Demo demo=new Demo();
assertEquals(demo.getStr(0),"F0");
/**
* java.lang.AssertionError:
* Expected :null
* Actual :F0
*/
}
2.Second try
#Test
public void test() {
Demo demo = mock(Demo.class);
doCallRealMethod().when(demo).getStr(0);
assertEquals(demo.getStr(0), "F0");
/**
* java.lang.AssertionError:
* Expected :null
* Actual :F0
*/
}
Anyone tell me how can I resolve this problem to make demo.getStr(0) == "F0" by call the real method? Thanks!
===========================
Another question relate to it
I have try an another test to test android.util.Pair class, and the result is that "pair.first" was null,.(There are androidTest and test directory,I put it into test package.Did it impact the result?)
import android.util.Pair;
import org.junit.Test;
import org.mockito.Mockito;
import static org.junit.Assert.assertEquals;
public class DemoTest {
#Test
public void test1(){
Pair<String,String> pair=new Pair("First","Second");
assertEquals("First",pair.first);
//pair.first was null,why?
}
#Test
public void test2(){
Pair<String,String> pair= Mockito.spy(Pair.class);
assertEquals("First",pair.first);
//pair.first was null also,why?
}
}
Why the simple code is correct in real android environment,but failure in test?
I had the same problem too. month ago I have problem with TextUtils class too.
I report this to jUnit but they told me the problem is with android package because in unit test environment you don't have access to platform specific classes
for that pair case you can use this package. this works for me
import android.support.v4.util.Pair;
The problem in your first try is, that the public field "first" is actually null.
Is the Pair class the one from the "javafx.util" package or a custom implementation?
Did you forget "this.first = first" or something similar in the constructor of the "Pair" class?
I would also recommend to change the following line:
assertEquals(demo.getStr(0),"F0");
to
assertEquals("F0", demo.getStr(0));
so that the error is printed correctly.
Your second try does not make any sense. What is the point in mocking the class you want to test?
I think the second example has the same problem as the first one. Pair.first is never set. If you fix that, it should also work (untested).
From Google's Android tools website:
"Method ... not mocked."
The android.jar file that is used to run unit tests does not contain any actual code - that is provided by the Android system image on real devices. Instead, all methods throw exceptions (by default). This is to make sure your unit tests only test your code and do not depend on any particular behaviour of the Android platform (that you have not explicitly mocked e.g. using Mockito).
So how can we solve this?
In other words. If you need a default android class to work properly you either have to include it from a separate repository, or implement it yourself.
In the case of Android's Pair class. You can use android.support.v4.util.Pair instead.
To get access to this class, you can include com.android.support:support-compat:27.0.0 in your build.gradle or dependencies file.
If you are not using Gradle, you can copy the implementation of this file and use it in place of the official one. Or you can try and download the .jar file from this older version https://mvnrepository.com/artifact/com.google.android/support-v4/r7 (I have not tested whether it works)
Another approach (based on this) is to create the class in app/src/test/java/android/util/Pair.java and copy the code from the Android implementation.
This way you don't need extra dependencies. (There may be issues related to the implementation changing after you make the copy, but the dependencies may become stale as well.)
I have moved from the implementation stage of my application to the testing phase. I am trying to write some unit tests but struggling with the concept. I have been able to set up and run the sample unit test in android studio, which passed.
It is a simple test that the result of 2+2 is equal to 4. This I understand, the issue is how do I write a unit test to test a more complex method of my application?
Take for example the method below which is used to register a user to a database using JSON. Obviously this method isnt as easy as 2+2, so how would one write a unit test for this?
I am also having issues with a simple test case that checks if an email is valid or not, the error I am getting is cannot resolve method 'is(boolean)'
valid email test
public class UnitTest {
#Test
public void validEmailTest() throws Exception {
assertThat(RegisterActivity.isValidEmail("rory#gmail.com"), is(true));
}
}
Unit test Class
import com.example.test.Activities.RegisterActivity;
import org.junit.Test;
import static org.junit.Assert.*;
public class UnitTest {
#Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
#Test
public void validEmailTest() throws Exception {
assertThat(RegisterActivity.isValidEmail("rory#gmail.com"), is(true));
}
}
Take a look at Getting Started with Testing.
You should pay special attention to Instrumented tests, which are tests that run on an Android device or emulator and thus they have access to internal information of the application under test. Instrumented tests can be used for unit, user interface (UI), or app component integration testing.
You can find examples at https://github.com/googlesamples/android-testing
I have writing an Android JUnit test for an activity in my application. The Activity is modal, and can be configured via the launching intent.
I would like to write test methods to test the different modes. This would involve a setActivityIntent call in the setup method, configuring the Activity based on the test case we are running.
My question is, how can I determine which test case is about to be run from the setup method?
It turns out the answer to this question is very easy. junit.framework.TestCase has a getName method that returns the name of the current test case. Perfect.
In Junit 4.X, you can do the samething with TestName class:
public class MyTest {
#Rule public TestName name = new TestName();
#Before
public void before() {
System.out.println("running...", name.getMethodName());
}
}
I am working on an android app and I have created a new test project for unit tests. Where's recommended to store the test fixtures (like xml files and the like) and what's the proper way to access it ?
It depends if you really mean unit test or instrumented tests (like using espresso and stuff)...
Unit tests:
Put your fixtures in src/test/resources (so e.g. src/test/resources/fixture.json)
Access them from your test classes e.g. using:
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("fixture.json")
Instrumented tests:
Put your fixtures in src/androidTest/assets/ (so e.g. src/androidTest/assets/fixture.json)
Access them from your test classes e.g. using:
InputStream is = InstrumentationRegistry.getContext().getResources().getAssets().open("fixture.json")
Here are some examples of how you can convert InputStream to String.
Here's a pretty good post describing different cases.
P.S. I know this question is 6+ years old... answering for any future searches.
After some searching I found there is no one proper way to store fixtures in Android (also not so much in java either).
Fixtures are a way to provide easy and consistent data to be passed into test cases. Creating .java classes with static methods that return objects is one way to go.
Example:
public class Pojos {
public static List<TaskListItem> taskListItems() {
return Arrays.asList(
new TaskListItem("one"),
new TaskListItem("two"),
new TaskListItem("three")
);
}
}
You can configure Gradle to read resources from a shared folder, you will be able to share code and resources either in unit test or instrumented test by doing the following.
android {
// ...
sourceSets {
final String sharedJavaDir = 'src/sharedTest/java'
final String sharedResourcesDir = 'src/sharedTest/resources'
test.java.srcDirs += sharedJavaDir
test.resources.srcDirs += [sharedResourcesDir]
androidTest.java.srcDirs += sharedJavaDir
androidTest.resources.srcDirs += [sharedResourcesDir]
// ....
}
// ...
}
Let's imagine that I setup a shared test resource in
/app/src/sharedTest/resources/test_fixture_file.txt
Kotlin code
In a UnitTest or Instrumented test you can use.
val resource: InputStream? = this.javaClass.getResourceAsStream("/test_fixture_file.txt")