ABOUT ME
busradeniz
busradeniz.com
Certified Scrum Master & Mobile Software Developer @Netaş
Co-Organizer @
Co-Organizer @
Master Student in SWE @Bogazici University
Co-Author of “Android Mutfağından Seçmeler”
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,
JUnit is a simple framework to write repeatable tests.AssertsSpecify the expected output and compare it with the output received
Test suitesUnit test cases are organized into test suites for better management
RulesExtend the functionality of JUnit by adding behaviors to tests
Exception testingTests and verifies whether an exception was thrown
Test setup and teardownSets up test data and tears down that data or context, before and after running the test
androidTestCompile ‘junit:junit:4.12’
Integration with build systemsIntegrates the most popular build systems for Java, including ANT, Maven, Gradle
Initial Test Case With Annotations
public class JUnitTestExamples {@Beforepublic 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
Assertionspublic 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).
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.
Mockito is a mocking framework that tastes really good. It lets you write beautiful tests with clean & simple API.
mock() / @Mockcreates mockoptionally specify how it should behave via Answer/ReturnValues/MockSettingswhen()/given() to specify how a mock should behave
spy() / @Spypartial mocking, real methods are invoked but still can be verified and stubbed
verify()checks methods were called with given arguments
@InjectMocksautomatically inject mocks/spies fields annotated with @Spy or @Mock
androidTestCompile ‘org.mockito:mockito-core:1.9.5’
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
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");
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.
@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’
Test CoverageJaCoCo is a free code coverage library for Java
it supports instruction, branch, line, method and class coverage
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.