agile mobile

Post on 21-Jan-2018

52 Views

Category:

Internet

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

MOBILE AGILEGodfrey Nolan

AGENDAAndroid (am)iOS (pm)

ANDROID AGENDAWhy??Unit, UI and API testing 101Calculator ExampleMore Tools - FIRSTETA DetroitjUnit Testing EspressoPostman / NewmanJenkins

IOS AGENDAWhy??Unit, UI and API testing 101Calculator ExampleNo really why?? (FIRST)ETA DetroitXCTest XCUI Postman / NewmanJenkins

FOLLOW ALONGgit clone http://github.com/godfreynolan/CodeCraftsman

WHYCatch more mistakesConfidently make more changesBuilt in regression testingExtend the life of your codebase

UNIT TESTING INTROpublic double add(double firstOperand, double secondOperand) { return firstOperand + secondOperand;}

@Test public void calculator_CorrectAdd_ReturnsTrue() { assertEquals(7, add(3,4); }

@Test public void calculator_CorrectAdd_ReturnsTrue() { assertEquals("Addition is broken", 7, add(3,4); }

dependencies { // Unit testing dependencies. testCompile 'junit:junit:4.12'}

UNIT TESTING 101Command lineSetup and TeardownAssertionsParametersCode Coverage

C:\Users\godfrey\AndroidStudioProjects\BasicSample>gradlew test --continueDownloading https://services.gradle.org/distributions/gradle-2.2.1-all.zip..................................................................................................................................Unzipping C:\Users\godfrey\.gradle\wrapper\dists\gradle-2.2.1-all\6dibv5rcnnqlfbq9klf8imrndn\gradleDownload https://jcenter.bintray.com/com/google/guava/guava/17.0/guava-17.0.jarDownload https://jcenter.bintray.com/com/android/tools/lint/lint-api/24.2.3/lint-api-24.2.3.jarDownload https://jcenter.bintray.com/org/ow2/asm/asm-analysis/5.0.3/asm-analysis-5.0.3.jarDownload https://jcenter.bintray.com/com/android/tools/external/lombok/lombok-ast/0.2.3/lombok-ast-0.2.3.jar:app:preBuild UP-TO-DATE:app:preDebugBuild UP-TO-DATE:app:checkDebugManifest:app:prepareDebugDependencies:app:compileDebugAidl:app:compileDebugRenderscript...:app:compileReleaseUnitTestSources:app:assembleReleaseUnitTest:app:testRelease:app:test

BUILD SUCCESSFUL

Total time: 3 mins 57.013 secs

public class CalculatorTest {

private Calculator mCalculator;

@Before public void setUp() { mCalculator = new Calculator(); }

@Test public void calculator_CorrectAdd_ReturnsTrue() { double resultAdd = mCalculator.add(3, 4); assertEquals(7, resultAdd,0); }

@After public void tearDown() { mCalculator = null; }}

UNIT TESTING 101assertEqualsassertTrueassertFalseassertNullassertNotNullassertSameassertNotSameassertThatfail

@RunWith(Parameterized.class)public class CalculatorParamTest {

private int mOperandOne, mOperandTwo, mExpectedResult; private Calculator mCalculator;

@Parameters public static Collection<Object[]> data() { return Arrays.asList(new Object[][] { {3, 4, 7}, {4, 3, 7}, {8, 2, 10}, {-1, 4, 3}, {3256, 4, 3260} }); }

public CalculatorParamTest(int mOperandOne, int mOperandTwo, int mExpectedResult) { this.mOperandOne = mOperandOne; this.mOperandTwo = mOperandTwo; this.mExpectedResult = mExpectedResult; }

@Before public void setUp() { mCalculator = new Calculator(); }

@Test public void testAdd_TwoNumbers() { int resultAdd = mCalculator.add(mOperandOne, mOperandTwo); assertEquals(mExpectedResult, resultAdd, 0); }}

ESPRESSOGUI TestingOnViewOnDatagradlew connectedCheck

@RunWith(AndroidJUnit4.class)@LargeTestpublic class MainActivityTest { @Rule public ActivityTestRule<MainActivity> activityTestRule = new ActivityTestRule<> (MainActivity.class); @Test public void helloWorldTest() { onView(withId(R.id.hello_world)) .check(matches(withText(R.string.hello_world))); }}

@Testpublic void helloWorldButtonTest(){ onView(withId(R.id.button)) .perform(click()) .check(matches(isEnabled())); }

MORE TOOLS - BUT WHY??F(ast)I(solated)R(epeatable)S(elf-verifying)T(imely) i.e. TDD not TAD

MOCKITO TEMPLATE @Test public void test() throws Exception {

// Arrange, prepare behavior Helper aMock = mock(Helper.class); when(aMock.isCalled()).thenReturn(true);

// Act testee.doSomething(aMock);

// Assert - verify interactions verify(aMock).isCalled(); }

when(methodIsCalled).thenReturn(aValue);

TROUBLE SHOOTINGrun gradlew build from the command lineAdd sdk.dir to local.propertiessdk.dir=/home/godfrey/android/sdk

TEST DRIVEN DEVELOPMENT (TDD)Unit testing vs TDDWhy TDDSample appLessons learned

TEST DRIVEN DEVELOPMENT Write test first See it fail Write simplest possible solutionto get test to pass Refactor Wash, Rinse, Repeat

TEST DRIVEN DEVELOPMENT Built in regression testingLonger life for your codebase YAGNI feature developmentRed/Green/Refactor helpskill procrastination

TDDYou can't TDD w/o unit testing

TDD means writing the testsbefore the code

TDD is more painless thanclassic unit testing

UNIT TESTINGYou can unit test w/o TDD

Unit tests don't mandate whenyou write the tests

Unit tests are often written atthe end of a coding cycle

STEPSIntroduce Continuous Integration to build codeConfigure android projects for TDDAdd minimal unit tests based on existing tests, add to CIShow team how to create unit testsAdd testing code coverage metrics to CI, expect 5-10%Add Espresso testsUnit test new features or sprouts, mock existing objectsWrap or ring fence existing code, remove unused codeRefactor wrapped code to get code coverage to 60-70%(New refactoring in Android Studio)

CONTACT INFOgodfrey@riis.com

IOS AGENDAWhy??Unit, UI and API testing 101Calculator ExampleNo really why?? (FIRST)ETA DetroitXCTest XCUI Postman / NewmanJenkins

WHYCatch more mistakesConfidently make more changesBuilt in regression testingExtend the life of your codebase

FOLLOW ALONGgit clone http://github.com/godfreynolan/CodeCraftsman

MORE TOOLS - BUT WHY??F(ast)I(solated)R(epeatable)S(elf-verifying)T(imely) i.e. TDD not TAD

TOOLS OF THE TRADEXCTest

Cuckoo (Mocking)

XCUI

Postman

Jenkins

CUCKOOAdd Cuckoo to the test target in Podfile

Pod install

Add Run Script to build phases

Add GeneratedMocks.swift file to tests

# Define output file; change "${PROJECT_NAME}Tests" to your test's root source folder, if it's not the default nameOUTPUT_FILE="./${PROJECT_NAME}Tests/GeneratedMocks.swift"echo "Generated Mocks File = ${OUTPUT_FILE}"

# Define input directory; change "${PROJECT_NAME}" to your project's root source folder, if it's not the default nameINPUT_DIR="./${PROJECT_NAME}"echo "Mocks Input Directory = ${INPUT_DIR}"

# Generate mock files; include as many input files as you'd like to create mocks for${PODS_ROOT}/Cuckoo/run generate --testable "${PROJECT_NAME}" \--output "${OUTPUT_FILE}" \"${INPUT_DIR}/JSONFetcher.swift"

# ... and so forth

# After running once, locate `GeneratedMocks.swift` and drag it into your Xcode test target group

XCUIUser Interface testing

Two options

▪Recorded tests

▪Roll your own

XCUI HAS 3 COMPONENTSXCUIApplication

Launch the app

XCUIElementQuery

Find the XCUI Element to test

XCUIElement

Perform Test

CONTACT INFOgodfrey@riis.com

top related