I'm new at JUnit tests, I'm trying to test database access through this code:
public class SeuticketTest extends ActivityInstrumentationTestCase2<Seuticket> {
private Seuticket mActivity;
public SeuticketTest(String name) {
super("br.com.code.seuticket.android.view",Seuticket.class);
setName(name);
}
#Override
protected void setUp() throws Exception {
super.setUp();
mActivity = this.getActivity();
}
public void testTicketInsertion() {
Ticket ticket = new Ticket("123453", "Vip", new Date(), "Vila Country");
PersistenceTicket persistence = new PersistenceTicket(mActivity);
persistence.addTicket(ticket);
assertEquals(persistence.fetchTicket(ticket.getTicketCode()).getTicketCode(),ticket.getTicketCode());
}
public void testUserInsertion() {
User user = new User();
user.setPin("1234");
user.setPhone("9241173");
PersistenceUser persistence = new PersistenceUser(mActivity);
persistence.addUser(user);
assertEquals(persistence.fetchUser().getPin(), user.getPin());
}
}
But my tests get stuck after complete the testTicketInsertion, the second test keep running forever, and sometimes before it run the tests this message shows at the console:
Test run failed: Process crashed.
Any ideas?
Hope to find an answer here.
Thanks people!
I am brand new to JUnit testing in Android and ran into the same problem. Make sure you have the tearDown method overridden and are making the call to super.
protected void tearDown() throws Exception {
super.tearDown();
}
Related
I've started learning android unit tests, but it looks very hard to find some good guides or information. Every example have a stupid example about 2+2 = 4
Say I write a little SDK which has few functions
MySdk.Init(Context context)
MySdk.CallTask()
I create an androidTest file
How should I call my SDK functions to check how they work? Somewhere required parameters like int/string/context. I just really don't understand, please help me.
This is what I've tried
public class AndroidTest {
private Activity context;
//default test
#Test
public void addition_correct() throws Exception {
assertEquals(4, 2 + 2);
}
#Test
public void checkContext() {
context = getActivity();
assertNotNull(context);
}
#Test
public void testInitPhase() {
MySdk.Init(context, new SdkInitializationListener() {
#Override
public void onInitializationSuccessful(String adv_id) {
assert (adv_id != null);
}
#Override
public void onInitializationError() {
}
});
}
}
For context i was tried context = new mockContext();. It's passed as context = null and my SDK failed with initialization.
Unit tests are mainly about testing an individual class in isolation, so that you can check if individual public methods of a class behave as you intend them to, and continue to do so if you change that class' code in the future. Let's say you have a class like this:
public class UtilityFunctions {
public int double(int value) {
return value * 2;
}
public String mirror(String value) {
if (value == null) return "";
return value + new StringBuilder(value).reverse().toString();
}
}
You want to test these two methods with:
valid input values, and check the output is as expected
invalid values, and check that errors are handled accordingly (and the correct exceptions thrown if necessary)
So a test class for the above class may look like this
#RunWith(JUnit4.class)
public class UtilityFunctionsTest {
private UtilityFunctions utility;
#Before
public void setUp() {
// Initialises any conditions before each test
utility = new UtilityFunctions();
}
#Test
public void testDoubleFunction() {
assertEquals(2, utility.double(1));
assertEquals(8, utility.double(4));
assertEquals(-12, utility.double(-6));
assertEquals(0, utility.double(0));
}
#Test
public void testMirror() {
assertEquals("", utility.mirror(null));
assertEquals("", utility.mirror(""));
assertEquals("aa", utility.mirror("a"));
assertEquals("MirrorrorriM", utility.mirror("Mirror"));
}
}
These standard Java unit tests are run from the test directory. However, you'll need to run tests in the androidTest directory whenever you're using Android-specific classes such as Context. If you're creating a MockContext, you're simply creating an empty Context whose methods don't do anything.
Without me knowing anything about what your MySDK does, I think you may need to pass a fully-functioning Context into your class for your tests. The Android JUnit runner does provide this with InstrumentationRegistry.getTargetContext(), so for your example, you may need to add this #Before method:
#Before
public void setUp() {
context = InstrumentationRegistry.getTargetContext();
}
You'll also need to remove the context = getActivity(); line from your first test.
I do not understand what exactly should I do in order to get a clean and a different db from the one that the app uses.
This is my test class:
public class SQLTest extends ProviderTestCase2{
private static String testDbPrefix = "unitTest_";
public SQLTest (){
super(MyContentProvider.class, MyContract.CONTENT_AUTHORITY);
}
#Override
#Before
public void setUp() throws Exception {
//setContext(InstrumentationRegistry.getTargetContext());
RenamingDelegatingContext context = new RenamingDelegatingContext(InstrumentationRegistry.getTargetContext(), testDbPrefix);
setContext(context);
super.setUp();
}
#Test
public void test1(){
//test logic
}
}
I noticed that it always runs on the db that the app uses, even though I'm using a both ProviderTestCase2 and RenamingDelegatingContext, which are supposed to ensure I'm running with a clean db.
Can anyone explain please what am I missing???
Thanks in advance!
I've tried everything already. The startActivity are not receiving the intent. Here's the code:
public class ColaboradorTeste extends ActivityUnitTestCase<ColaboradorMainActivity> {
private UserDAO userDAO;
private ColaboradorMainActivity activity;
public ColaboradorTeste() {
super(ColaboradorMainActivity.class);
}
#Override
protected void setUp() throws Exception{
super.setUp();
startActivity(new Intent(getInstrumentation().getTargetContext(), ColaboradorMainActivity.class), null, null);
activity = (ColaboradorMainActivity)getActivity().getApplicationContext();
userDAO = new UserDAO(activity);
}
public void testBase() throws Exception{
...
}
}
Here's the error:
java.lang.NullPointerException
at br.fsw.seatafmobile.ColaboradorTeste.setUp(ColaboradorTeste.java:23)
I know the problem is in the startActivity, but I really don't know how to solve it.
If anyone could help I'll really appreciate.
I finally found the solution!
My test is using a database created on the app. So I had to change the Build Variants from Unit Test to Android Instrumentation Tests.
I am learning to use android robotium and I am trying to make a simple test where it reads the first line of a file and it equals "car" but I am getting
Test failed to run to completion. Reason: 'Instrumentation run failed due to 'java.lang.NullPointerException''.
*The activity starts a fragment.
public class TestReadFromFile extends ActivityInstrumentationTestCase2<PagesActivity> {
private Solo solo;
PagesActivity mPagesActivity;
private Context mContext;
public TestReadFromFile() {
super(PagesActivity.class);
}
public void testReadLine() throws Exception {
assertEquals(ReadFromFile.readLine(0, mContext),
"car");
}
#Override
public void setUp() throws Exception {
super.setUp();
mPagesActivity = getActivity();
mContext = getInstrumentation().getTargetContext();
solo = new Solo(getInstrumentation(), getActivity());
}
#Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
}
The easy solution would be if your tearDown() method is not being called because your code happens to have a System.exit(0) somewhere.
#Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
Alternatively, I assume that your cached context is null.
You don't need to save your context in the setUp() method. You can access your activity/context easily during test cases with solo.getActivity()
Is there any way from which i can run a single test case multiple times with different data in robotium tesing of an android application.
Just like parameterized juint testing.
public class UserTest extends
ActivityInstrumentationTestCase2<MainActivity> {
public UserTest() {
super(TestActivity.class);
}
#Override
public void setUp() throws Exception {
// setUp() is run before a test case is started.
// This is where the solo object is created.
solo = new Solo(getInstrumentation(), getActivity());
}
public void testUserData1() throws Exception {
// UserBean
Bean bean = setUp.get(0);
dataTest(bean);
}
public void testUserData2() throws Exception {
// UserBean
Bean bean = setUp.get(1);
dataTest(bean);
}
public void dataTest(Bean bean) {
Log.e("testAddNote userbean", bean.toString());
// Login
solo.enterText(0, bean.getUserName());
solo.enterText(1, bean.getPassWord());
solo.clickOnButton(0);
}
this the way currently i am running test cases is there a way by which dataTest(Bean) can be executed multiple times with setUp elements as parameters.Means i have to call single method multiple times with different parameters.
I just notice that this only works if you are using https://code.google.com/p/zohhak/
In that case you can do:
#TestWith({
“2, true”,
“6, false”,
“19, true”
})
public void testPrimeNumberValidator(int number, boolean isPrime) {
assertThat(…
}