Can't get JUnit tests to fail in Android Studio - android

I'm trying out Android development, but haven't come too far because I'm unable to get a test case to fail.
I have the following test case in the androidTest folder:
package com.example.aaronf.myapplication;
import android.test.*;
public class ToDoListTest extends AndroidTestCase {
private void newToDoListHasNoItems() {
assertEquals(new ToDoList().length, 0);
}
private void addingToDoGivesLengthOfOne() {
ToDoList toDoList = new ToDoList();
toDoList.add(new ToDo());
assertEquals(toDoList.length, 1);
}
public void runTests() {
newToDoListHasNoItems();
addingToDoGivesLengthOfOne();
}
public ToDoListTest() {
super();
runTests();
}
}
The ToDoList class looks like:
package com.example.aaronf.myapplication;
public class ToDoList {
public int length = 0;
public void add(ToDo toDo) {
}
}
It seems like it should fail on addingToDoGivesLengthOfOne(), but I get a green bar.
EDIT
I should add that adding #Test annotations to the methods generates a symbol not found error.
EDIT
I visited the suggested post My Junit test doesn't run. However, there is a difference with my problem. My methods used to have the test prefix, but this didn't affect the outcome. Also, the #Test annotation, as I mentioned before, is flagged with an error: "Cannot resolve symbol Test".

The problem was that my Test Artifact was set to Android Instrumentation Tests instead of Unit Tests. Since my unit tests were being added to the Android Instrumentation group, the unit testing stuff wasn't being recognized.

Related

Android - How to UnitTest a Logging class with mockito

I have written a class to manage logging within an android application project.
The LogManager is basically a wrapper for android.util.log
It handles logging to a file, if the application crashes, and standard debug logging.
I would like to unit test the class using JUnit.
I have tried the following but it does not seem to produce the results I would expect after reading the examples:
LogManager.class (This is a simplified version of the class I have used, for demonstration purposes)
public class LogManager implements ILogManager
{
public void log(String tag, String message)
{
Log.e(tag, message);
}
}
And here is my test class
#RunWith(RobolectricGradleTestRunner.class)
#Config(constants = BuildConfig.class, sdk = 21)
#PrepareForTest({Log.class, LogManager.class})
public class LogManagerUnitTest
{
#Test
public void testLogConsoleInfo()
{
PowerMockito.mockStatic(Log.class);
LogManager.getInstance().log(LogLevel.INFO, "test", "test");
PowerMockito.verifyStatic(Mockito.times(1));
Log.e(anyString(), anyString());
}
}
My problem is that this passes no matter what I put.
E.g: if I instead replace the last call with Log.wtf(...) it still passes. I would have assumed that it should fail since Log.wtf was not called in the static class Log?
So my question is, why isn't this approach working as expected and what would be the correct way to do it?
I started a fresh project and was able to get it to fail tests and succeed appropriately using the following, so I'm assuming the runwith was the culprit:
#RunWith(PowerMockRunner.class)
#PrepareForTest(android.util.Log.class)
public class LoggerUnitTest {
#Test
public void testLog() throws Exception
{
PowerMockito.mockStatic(Log.class); // when(Log.e(anyString(), anyString())).thenReturn(1);
Logger.log("test", "test");
PowerMockito.verifyStatic(times(1));
Log.e(anyString(), anyString());
} }
For the RobolectricGradleTestRunner, the following incantation would have exposed your logging:
ShadowLog.stream = System.out
Robolectric does not print the Android system logging by default.
It's also worth noting that the RobolectricGradleTestRunner has been deprecated in favor of the fully operational RobolectricTestRunner (The above assignment is still effective)

Android Espresso black-box testing

Does anyone try to do black-box testing with Android Espresso?
Could anyone provides me with some simple example?
I had tried some example before, but failed every time!
Example, I had tried this one:
public class ApplicationTest extends ActivityInstrumentationTestCase2
{
private static final String ACTIVITY_CLASSNAME = "com.example.kai_yu.blackboxtest";
private static Class launchActivityClass;
static
{
try
{
launchActivityClass = Class.forName(ACTIVITY_CLASSNAME);
}
catch (ClassNotFoundException e)
{
throw new RuntimeException(e);
}
}
public ApplicationTest()
{
super(launchActivityClass);
}
#Test
public void testClick()
{
}
}
But Android Studio said:
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.kai_yu.blackboxtest"
com.example.kai_yu.blackboxtest is applicationId which is another installed application on my phone
Thank you!
Espresso can only run as part of an instrumentation test.
Instrumentation tests can only act upon the app under test ( i.e. the target of the instrumentation ).
UIAutomator might be better for your use case.
https://developer.android.com/tools/testing-support-library/index.html#UIAutomator
In Espresso docs you would find this line:
While it can be used for black-box testing, Espresso's full power is unlocked by those who are familiar with the code base under test."
For that reason Espresso testing is called by gray-box testing.
If you're not familiar with programming in Java or Android, or you want just to write black-box testing in the clearest way as possible try to learn instead of Espresso this framework
Calabash-iOS and Calabash-Android are the underlying low-level libraries that empower the Cucumber tool to run automated functional tests on Android...
Website: https://calaba.sh/
GitHub: https://github.com/calabash
Here would you find how and why to start using this framework:
http://blog.teddyhyde.com/2013/11/04/a-better-way-to-test-android-applications-using-calabash/
#RunWith(AndroidJUnit4.class)
#LargeTest
public class EspressoTest1 extends ActivityInstrumentationTestCase2<MainActivity>{
public EspressoTest1() {
super(MainActivity.class);
}
#Before
public void setUp() throws Exception {
super.setUp();
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
}
#Test
public void test1ChatId() {
getActivity();
onView(withId(R.id.anuja)).check(matches(isDisplayed()));
}
#After public void tearDown() throws Exception {
super.tearDown();
}
}
There are two ways to write Espresso Test case one is as per shown above
The Examples are taken from this blog
http://qaautomated.blogspot.in/p/blog-page.html
Where you can find details of hot to run the espresso test case in detail.

Android - ActivityUnitTestCase - Tests Always Pass

I am using Android Studio to try and test my activity. Here is the basic code:
public class MyActivityTest extends ActivityUnitTestCase<MyActivity> {
public MyActivityTest() {
super(MyActivity.class);
}
#Override
protected void setUp() throws Exception {
super.setUp();
}
#SmallTest
public void testSomething() {
Assert.assertNotNull("something is null", null);
}
}
I would expect that this test case fails. Everything I try passes though. This seems like a strange question, but how can I make my test case fail? What am I doing wrong?
I managed to get this working, sort of. I found this on a bug report:
We are in the process of deprecating ActivityUnitTestCase. We recommend to move business logic to a separate class and unit test it with gradle unit test support (mockable android.jar).
So I extended ActivityInstrumentationTestCase2 instead and ran the test as an Instrumentation Test rather than a Unit Test. That worked. Here is basically what I have now:
public class MyActivityTest extends ActivityInstrumentationTestCase2<MyActivity> {
public MyActivityTest() {
super(MyActivity.class);
}
public void testSomething() throws Exception {
//test goes here
Assert.assertEquals(message, expectedObject, actualObject);
}
}
I'm still not sure why I was seeing the behavior I was earlier, but at least I can test now. Here is a screenshot of my Test Build Configuration:

Android and JUnit: How to add individual tests to test suite?

I've been struggling for a while with this. When creating a test suite in JUnit/Android, I can to the following:
Add all the tests (in all the classes) that exist in the same package as the suite
Add a specific class contatining testMethods
However, I'm completely unable to do the following:
Add a specific testMethod from a specific class to the test suite.
Now, I understand that this SHOULD be possible, as there are countless examples showing this.
This is how it's supposed to work:
The test class contatining the test methods:
import com.frank.android.lookup.SomeClass;
import android.test.AndroidTestCase;
public class ArithmeticsTests extends AndroidTestCase {
SomeClass sctest;
protected void setUp () throws Exception {
sctest = new SomeClass();
super.setUp();
}
public void testAddNumbers () {
assertEquals(9, sctest.addNumbers(3, 6));
}
public void testSubtractNumbers () {
assertEquals(2, sctest.subtractNumbers(6, 4));
}
protected void tearDown () throws Exception {
super.tearDown();
}
}
And here's the test suite class:
import junit.framework.TestSuite;
public class ProjectTestSuite_SomeTests extends TestSuite {
public static Test suite () {
TestSuite suite = new TestSuite("ArithmeticsTests");
suite.addTest(new ArithmeticsTests("testAddNumbers"));
suite.addTest(new ArithmeticsTests2("testSubtractNumbers"));
return suite;
}
}
Now, the two lines where I try adding the individual test methods result in this error:
The constructor ArithmeticsTests(String) is undefined
Now, I've looke around for a long time, and I cannot find any explanation for this. It seems that something is missing, since it doesn't understand what I'm trying to do. The "string" it complains about is in fact the name of the method - I'm not trying to pass a string to a constructor of the class - I'm trying to add the method of the class to the test suite.
I'm using the JUnit version that's included with the Android SDK here, and I haven't installed anything else related to that. Is there something missing? (Obviously there is, bit what?)
EDIT:
I added a construtor to the ArithmeticsTests class:
public ArithmeticsTests (String s) {}
Now the above error is gone.
However, when I run the test suite, I get this error:
testSuiteCreationFailed
....
Caused by: java.lang.NullPointerException: Method name must not be null.
I came up with the same problem and discovered that, while AndroidTestCase does not have a constructor taking a String parameter, it does have a setName(String name) method. By calling the setName method, you can add individual method to the test case.
Using the code in your example, your test suite may look like:
import junit.framework.TestSuite;
public class ProjectTestSuite_SomeTests extends TestSuite {
public static Test suite () {
TestSuite suite = new TestSuite("ArithmeticsTests");
ArithmeticsTests arithmeticsTests = new ArithmeticsTests();
arithmeticsTests.setName("testAddNumbers");
suite.addTest(arithmeticsTests);
ArithmeticsTests2 arithmeticsTest2 = new ArithmeticsTests2();
arithmeticsTest2.setName("testSubtractNumbers");
suite.addTest(arithmeticsTest2);
return suite;
}
}
This worked for me.
public static TestSuite suite() {
final TestSuite t = new TestSuite();
t.addTest(TestSuite.createTest(TestExampleClass1.class, "test1"));
t.addTest(TestSuite.createTest(TestExampleClass2.class, "test2"));
t.addTest(TestSuite.createTest(TestExampleClass3.class, "test2"));
return t;
}

android: a newby question about Android Unit Testing?

I've got the basic scenario: a test project, in it - one test class, nothing less, nothing more. The code of the test class is this:
public class SManagerTest extends AndroidTestCase {
private SManager sm;
public SManagerTest(){
sm = SManager.getInstance(getContext());
}
#Test
public void trainTest(){
sm.go();
}
}
What's wrong? because I get this:
Test run failed: Test run incomplete. Expected 1 tests, received 0
Thanks!
As pointed out earlier use "test" with a small t and don't forget to run it as an "Android JUnit Test"
Agree with Christopher - start the method name with 'test' even though you're adding the #Test decorator. Also, add this class in the same folder as your tests and it will run all your tests:
public class AllTests extends TestSuite
{
public static Test suite()
{
return new TestSuiteBuilder(AllTests.class).includeAllPackagesUnderHere().build();
}
}

Categories

Resources