mobile apps development best practices. tdd, ci, cd

Post on 01-Nov-2014

1.792 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

Serhii Nezdolii about Mobile apps development (Android, iOS) best practices: Test Driven Development (unit/UI tests), Continuous Integration (Jenkins), Continuous Delivery (TestFlightApp) Сергій Нездолій про кращі практики розробки мобільних додатків Сергей Нездолий о лучших практиках разработки мобильных приложений

TRANSCRIPT

©2013 GlobalLogic Inc. CONFIDENTIAL

CONFIDENTIAL ©2013 GlobalLogic Inc.

Mobile Dev Guide:

TDD + CI + CD

TDD: Test Driven Development

CI: Continuous Integration

CD: Continuous Delivery

©2013 GlobalLogic Inc. CONFIDENTIAL

What is TDD? Why? How?

What is CI? Why? How?

What is CD? Why? How?

01

02

03

4 CONFIDENTIAL

Test Driven Development: Basics

5 CONFIDENTIAL

6 CONFIDENTIAL

TDD: Basics

− First understand the requirement

− Create test that tests this

requirement

− Run test and expect FAIL

− Provide basic implementation

− Run test and expect PASS

− Improve your implementation

− Run test after improvements to

test changes

7 CONFIDENTIAL

TDD: Example

− Requirement: validate email to match common email mask.

− username: [a-zA-Z0-9-_]+ (e.g. My_user-09)

− company: [a-zA-z0-9]+ (e.g. globallogic911)

− domain: [a-zA-Z]{2,} (e.g. com)

− E-mail structure: [username]@[company].[domain]

− Valid e-mail: test-user@domain.com

− Invalid e-mail: $uper~U$er123@ideal-company.z

8 CONFIDENTIAL

TDD: Example (cont.)

− Simple test:

public void testEmailValidationForValidEmail() {

//GIVEN

String validEmail = "sergiy-nezdoliy@globallogic.com";

//WHEN

bool result = SNUtilities.validateEmail(validEmail);

//THEN

assertTrue("Mail is valid: " + validEmail, result);

}

9 CONFIDENTIAL

TDD: Example (cont.)

− Simple implementation:

public static bool validateEmail(String intpuMail) {

return FALSE;

}

//Leads to test FAIL

//Refactor code to pass test

public static bool validateEmail(String intpuMail) {

boolean isValidEmail = false;

Pattern pattern = Pattern.compile("^[_A-Za-z0-9-]+@[A-Za-z0-9-]+((\\.[A-Za-z]{2,}){1}$)");

isValidEmail = pattern.matcher(inputMail).matches();

return isValidEmail;

}

//Run test and – voila, PASSED

10 CONFIDENTIAL

TDD: Example (cont.)

− Improve?

− Empty string

− Null value

− Extended mask for regexp (including dot support etc)

− Do not forget to test negative cases

11 CONFIDENTIAL

TDD: Example (cont.)

− As a result: //TESTS

public void testValidateNullEmail() {...}

public void testValidateEmptyValue() {...}

public void testValidateInvalidEmail() {...}

public void testValidateValidEmail() {...}

//IMPLEMENTATION

public static boolean validateEmail(String inputMail) {

boolean isValidEmail = false;

if (inputMail != null && inputMail.length() > 0) {

Pattern pattern = Pattern.compile

("^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*((\\.[A-Za-z]{2,}){1}$)");

isValidEmail = pattern.matcher(inputMail).matches();

}

return isValidEmail;

}

12 CONFIDENTIAL

Test Driven Development &

13 CONFIDENTIAL

TDD: Android

14 CONFIDENTIAL

TDD: Android tools

− Unit tests: − Junit,

− Instrumentation

− UI tests: − Instrumentation,

− Robotium, Robolectric,

− monkey, monkeyrunner

− Mocks: − android-mock:

15 CONFIDENTIAL

TDD: Android – What to test?

− Formatters

− Parsing, serializing, marshaling data from server

− Fields input validation (e.g. e-mail field)

− Any inner calculations

− Entities, models, DAO objects

− Database layer

− UI where possible (functional and integration testing)

− …

16 CONFIDENTIAL

TDD: Android Example

//IMPLEMENTATION

public static boolean validateEmail(String inputMail) {

boolean isValidEmail = false;

if (inputMail != null && inputMail.length() > 0) {

Pattern pattern = Pattern.compile

("^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*((\\.[A-Za-z]{2,}){1}$)");

isValidEmail = pattern.matcher(inputMail).matches();

}

return isValidEmail;

}

//TESTS

public void testValidateNullEmail() {...}

public void testValidateEmptyValue() {...}

public void testValidateInvalidEmail() {...}

public void testValidateValidEmail() {...}

17 CONFIDENTIAL

Test Driven Development &

18 CONFIDENTIAL

TDD: iOS tools

− Unit tests: − OCUnit, SenTestingKit (embedded into Xcode),

− GHUnit

− UI tests: − UI Automation,

− Frank, Appium … (no success )

− Mock: − OCMock

19 CONFIDENTIAL

TDD: iOS– What to test? (TODO)

− Core Data layer

− Parsing, serializing, marshaling data from server

− Fields input validation (e.g. e-mail field)

− Any inner calculations

− Entities, models, DAO objects

− UI where possible (functional and integration testing)

− …

20 CONFIDENTIAL

TDD: iOS Example //IMPLEMENTATION

+ (BOOL) validateEmail:(NSString *)inputEmail{

BOOL isEmailValid = NO;

if (inputEmail) {

NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";

NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];

isEmailValid = [emailTest evaluateWithObject:inputEmail];

}

return isEmailValid;

}

//TESTS

- (void)testValidateEmailWithValidEmail{

//GIVEN

NSString *validEmail = @"test-user01@domain.com";

//WHEN

BOOL result = [DemoUtils validateEmail:validEmail];

//THEN

STAssertTrue(result, @"Valid with email: %@", validEmail);

}

21 CONFIDENTIAL

Continuous Integration: iOS and Android

22 CONFIDENTIAL

Continuous Integration: Why?

− Reduce risks: − Fixing bugs late costs more

− Lack of project visibility (metrics, changelogs)

− Lack of deployable software

− Reduce repetitive manual processes

− Generate deployable software any time at any place

− Test early and often

− No painful waits for next build

− Visible process of building your project

23 CONFIDENTIAL

Continuous Integration: Schema Version Control System Build servers

QA, clients, managers

Developers

CI Server

CI Feedback

1. Check In 2. Check Out

3. Indicate

Change

5. Set Status

4. Report

Results

6. Notify

24 CONFIDENTIAL

Continuous Integration:

− Cross-system (Windows, Linux, Mac OS)

− Extensible (plenty of plugins)

− Provides good visibility of builds

− Free

− Chuck Norris supports Jenkins!

25 CONFIDENTIAL

CI: Example of dashboard

26 CONFIDENTIAL

Continuous Integration &

27 CONFIDENTIAL

Continuous Integration: How?

− Xcode command line tools (with some hacks)

− Run tests from command line and fail in case if failed tests

− ocunit2junit + gcovr for code coverage

− keychain issues

− Provisioning profiles import

− Jenkins should run only on Mac

28 CONFIDENTIAL

Continuous Integration: iOS

CI: TDD & Code coverage?

− Using gcovr tool

− Configure project to generate .gcda data (Xcode 4.6.x): − Add to “Other C flags”: -lgcov, -ftest-coverage, -lprofile_rt

− Set “Generate Test Coverage Files” to YES

− Set “Generate Profiling Code” to YES

− run tests -> ocunit2junit to get tests results

− configure Jenkins job to handle test reports and code coverage

(Cobertura)

29 CONFIDENTIAL

Continuous Integration &

30 CONFIDENTIAL

Continuous Integration: How?

− Using ant

− Using Android build tools

− Using Jenkins plugin for Android

− Using bash

− Analyzing tests results? Hack for tests needed in build.xml

− Take a look at android-lint plugin: − scans your Android projects and reports on potential bugs, performance, security and

translation issues, plus more

31 CONFIDENTIAL

Continuous Integration: iOS

Continuous Integration: TDD?

− Add separate target to build.xml

− Analyze results

− Fail build in case if tests fail

32 CONFIDENTIAL

Continuous Delivery

33 CONFIDENTIAL

Continuous Delivery: Why?

− Allows to provide new builds to test continuously

− Automation of providing builds to QA and customers

− Painless releases, quick feedbacks

34 CONFIDENTIAL

Continuous Delivery &

35 CONFIDENTIAL

Continuous Delivery: How?

− Installation over the air

− Downloading build as artifact from Jenkins

− Uploading to share (Android only)

− Installation over Wi Fi (iOS – manual)

− Cloud services: AppBlade, Knappsack, HockeyApp … - not Free

− …

− TestFlightApp – ideal free solution to manage your app

36 CONFIDENTIAL

Continuous Delivery: TestFlight

37 CONFIDENTIAL

TestFlightApp: Why?

− Free

− Supports automatic uploading (can be part of Jenkins job)

− May be not embedded into app at all.

− Email notifications

− Easy to install on any allowed device (which is in Ad Hoc profile)

− Cross platform (iOS, Android)

− Provides additional services (crash reports, checkpoints etc) − You need to include TestFlight SDK into your project for this

38 CONFIDENTIAL

TestFlightApp: example of upload

curl http://testflightapp.com/api/builds.json \

-F file=@$IPA \

-F api_token=’<YOUR API TOKEN>' \

-F team_token=’<YOUR TEAM TOKEN>' \

-F notes="Uploaded on ${BUILD_ID} (Build#: '${BUILD_NUMBER}') (Build version#: '1.0').\nChanges: $git_notes" \

-F notify=True \

-F distribution_lists=”QA"

39 CONFIDENTIAL

Conclusion

CONFIDENTIAL ©2013 GlobalLogic Inc.

Skype: sergey.nezdoliy

Twitter: @sergey_nezdoliy

Mail: sergey.nezdoliy@gmail.com

Thank you

top related