Agile mobile
-
Upload
godfrey-nolan -
Category
Internet
-
view
52 -
download
0
Transcript of Agile mobile
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 [email protected]
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 [email protected]