5. WHY TEST YOUR CODE ?
UN
Useful
document
Reduce
testing
time
Bug fix
early
Refine
Design
Unit
Test
Unit testing finds problems
early in the development cycle.
This includes both bugs in the
programmer's implementation
and flaws or missing parts of
the specification for the unit.
Unit testing provides a sort of living
documentation of the system.
Developers looking to learn what
functionality is provided by a unit,
and how to use it, can look at the
unit tests to gain a basic
understanding of the unit's interface
UT always forces you software parts
that can tests easily. While you are
writing unit tests for existing code,
you will realize that it is not too easy.
Your code should be proper in order
to isolate out parts of your SUT. By
this way, you need to refactor and
refine your code so as to write
successful unit tests.
Unit test covers the basic cases
of your software so the next
cycle of software testing can
include more complex scenarios.
For example, checking null
parameters can be handled in
unit tests so in the next cycle,
7. JUnit is a simple framework to write repeatable tests.
Asserts
Specify the expected output and compare
it with the output received
Test suites
Unit test cases are organized into test
suites for better management
Rules
Extend the functionality of JUnit by adding
behaviors to tests
Exception testing
Tests and verifies whether an exception
was thrown
Test setup and teardown
Sets up test data and tears down that data
or context, before and after running the
test
androidTestCompile ‘junit:junit:4.12’
Integration with build systems
Integrates the most popular build systems
for Java, including ANT, Maven, Gradle
8. Initial Test Case With Annotations
public class JUnitTestExamples {
@Before
public void setUp() {
//sets up test data, runs before test case
}
@Test
public void testAssertEquals() {
// test method
}
@After
public void tearDown() {
//tears down test data, runs after test case
}
}
JUnit annotations
@Test
@Before
@After
@BeforeClass
@AfterClass
@Ignore
9. Assertions
public class AssertTests {
@Test
public void testAssertArrayEquals() {
byte[] expected = "trial".getBytes();
byte[] actual = "trial".getBytes();
org.junit.Assert.assertArrayEquals("failure - byte arrays not same", expected, actual);
}
@Test
public void testAssertEquals() {
org.junit.Assert.assertEquals("failure - strings are not equal", "text", "text");
}
@Test
public void testAssertFalse() {
org.junit.Assert.assertFalse("failure - should be false", true);
}
@Test
public void testAssertNotNull() {
org.junit.Assert.assertNotNull("should not be null", new Object());
}
}
JUnit provides
overloaded assertion
methods for all
primitive types and
Objects and arrays
(of primitives or
Objects).
10. Test Suites
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
TestFeatureLogin.class,
TestFeatureLogout.class,
TestFeatureNavigate.class,
TestFeatureUpdate.class
})
public class FeatureTestSuite {
// the class remains empty,
// used only as a holder for the above annotations
}
Using “Suite” as a
runner allows you to
manually build a
suite containing tests
from many classes.
11. Mockito is a mocking framework that tastes really good. It lets you
write beautiful tests with clean & simple API.
mock() / @Mock
creates mock
optionally specify how it should behave via
Answer/ReturnValues/MockSettings
when()/given() to specify how a mock
should behave
spy() / @Spy
partial mocking, real methods are invoked
but still can be verified and stubbed
verify()
checks methods were called with given
arguments
@InjectMocks
automatically inject mocks/spies fields
annotated with @Spy or @Mock
androidTestCompile ‘org.mockito:mockito-core:1.9.5’
12. import static org.mockito.Mockito.*;
//mock creation
List mockedList = mock(List.class);
//using mock object
mockedList.add("one");
mockedList.clear();
//verification
verify(mockedList).add("one");
verify(mockedList).clear();
Once created, mock will remember all interactions.Then you can selectively verify whatever
interaction you are interested in.
mock()
public class ArticleManagerTest {
@Mock private ArticleCalculator calculator;
@Mock private ArticleDatabase database;
@Mock private UserProvider userProvider;
private ArticleManager manager;
@Before public void setup() {
MockitoAnnotations.initMocks(this);
}
}
@Mock
13. List list = new LinkedList();
List spy = spy(list);
//optionally, you can stub out some methods:
when(spy.size()).thenReturn(100);
//using the spy calls real methods
spy.add("one");
spy.add("two");
//prints "one" - the first element of a list
System.out.println(spy.get(0));
//size() method was stubbed - 100 is printed
System.out.println(spy.size());
//optionally, you can verify
verify(spy).add("one");
verify(spy).add("two");
spy() @Spy
@Spy Foo spyOnFoo = new Foo();
//optionally, you can stub out some methods:
when(spy.size()).thenReturn(100);
//using the spy calls real methods
spy.add("one");
spy.add("two");
//prints "one" - the first element of a list
System.out.println(spy.get(0));
//size() method was stubbed - 100 is printed
System.out.println(spy.size());
//optionally, you can verify
verify(spy).add("one");
verify(spy).add("two");
14.
Running tests is too slow because JUnit tests need an Android
emulator or device
java.lang.RuntimeException: Stub!
Robolectric lets you run your tests on your workstation, or on your
Continuous Integration environment in a regular JVM, without an
emulator.
15. @RunWith(RobolectricTestRunner.class)
public class WelcomeActivityTest {
@Test
public void clickingLogin_shouldStartLoginActivity() {
WelcomeActivity activity = Robolectric.setupActivity(WelcomeActivity.class);
activity.findViewById(R.id.login).performClick();
Intent expectedIntent = new Intent(activity, WelcomeActivity.class);
assertThat(shadowOf(activity).getNextStartedActivity()).isEqualTo(expectedIntent);
}
}
Robolectric supports
resource handling,
e.g., inflation of
views. You can also
use the
findViewById() to
search in a view.
androidTestCompile ‘org:robolectric:robolectric:2.4’
16. Test Coverage
JaCoCo is a free code coverage library for Java
it supports instruction, branch, line, method and class coverage
17. Test Coverage
The green lines represent
parts of the code which were
fully covered by tests.
The yellow line means that
given branch was not fully
covered because its
condition never evaluated to
true.
The red line was never
executed by our tests.