![Page 1: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/1.jpg)
©2013 GlobalLogic Inc. CONFIDENTIAL
![Page 2: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/2.jpg)
CONFIDENTIAL ©2013 GlobalLogic Inc.
Mobile Dev Guide:
TDD + CI + CD
TDD: Test Driven Development
CI: Continuous Integration
CD: Continuous Delivery
![Page 3: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/3.jpg)
©2013 GlobalLogic Inc. CONFIDENTIAL
What is TDD? Why? How?
What is CI? Why? How?
What is CD? Why? How?
01
02
03
![Page 4: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/4.jpg)
4 CONFIDENTIAL
Test Driven Development: Basics
![Page 5: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/5.jpg)
5 CONFIDENTIAL
![Page 6: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/6.jpg)
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
![Page 7: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/7.jpg)
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: [email protected]
− Invalid e-mail: [email protected]
![Page 8: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/8.jpg)
8 CONFIDENTIAL
TDD: Example (cont.)
− Simple test:
public void testEmailValidationForValidEmail() {
//GIVEN
String validEmail = "[email protected]";
//WHEN
bool result = SNUtilities.validateEmail(validEmail);
//THEN
assertTrue("Mail is valid: " + validEmail, result);
}
![Page 9: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/9.jpg)
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
![Page 10: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/10.jpg)
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
![Page 11: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/11.jpg)
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;
}
![Page 12: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/12.jpg)
12 CONFIDENTIAL
Test Driven Development &
![Page 13: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/13.jpg)
13 CONFIDENTIAL
TDD: Android
![Page 14: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/14.jpg)
14 CONFIDENTIAL
TDD: Android tools
− Unit tests: − Junit,
− Instrumentation
− UI tests: − Instrumentation,
− Robotium, Robolectric,
− monkey, monkeyrunner
− Mocks: − android-mock:
![Page 15: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/15.jpg)
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)
− …
![Page 16: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/16.jpg)
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() {...}
![Page 17: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/17.jpg)
17 CONFIDENTIAL
Test Driven Development &
![Page 18: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/18.jpg)
18 CONFIDENTIAL
TDD: iOS tools
− Unit tests: − OCUnit, SenTestingKit (embedded into Xcode),
− GHUnit
− UI tests: − UI Automation,
− Frank, Appium … (no success )
− Mock: − OCMock
![Page 19: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/19.jpg)
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)
− …
![Page 20: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/20.jpg)
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 = @"[email protected]";
//WHEN
BOOL result = [DemoUtils validateEmail:validEmail];
//THEN
STAssertTrue(result, @"Valid with email: %@", validEmail);
}
![Page 21: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/21.jpg)
21 CONFIDENTIAL
Continuous Integration: iOS and Android
![Page 22: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/22.jpg)
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
![Page 23: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/23.jpg)
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
![Page 24: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/24.jpg)
24 CONFIDENTIAL
Continuous Integration:
− Cross-system (Windows, Linux, Mac OS)
− Extensible (plenty of plugins)
− Provides good visibility of builds
− Free
− Chuck Norris supports Jenkins!
![Page 25: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/25.jpg)
25 CONFIDENTIAL
CI: Example of dashboard
![Page 26: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/26.jpg)
26 CONFIDENTIAL
Continuous Integration &
![Page 27: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/27.jpg)
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
![Page 28: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/28.jpg)
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)
![Page 29: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/29.jpg)
29 CONFIDENTIAL
Continuous Integration &
![Page 30: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/30.jpg)
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
![Page 31: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/31.jpg)
31 CONFIDENTIAL
Continuous Integration: iOS
Continuous Integration: TDD?
− Add separate target to build.xml
− Analyze results
− Fail build in case if tests fail
![Page 32: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/32.jpg)
32 CONFIDENTIAL
Continuous Delivery
![Page 33: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/33.jpg)
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
![Page 34: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/34.jpg)
34 CONFIDENTIAL
Continuous Delivery &
![Page 35: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/35.jpg)
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
![Page 36: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/36.jpg)
36 CONFIDENTIAL
Continuous Delivery: TestFlight
![Page 37: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/37.jpg)
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
![Page 38: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/38.jpg)
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"
![Page 39: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/39.jpg)
39 CONFIDENTIAL
Conclusion
![Page 40: Mobile Apps development best practices. TDD, CI, CD](https://reader034.vdocuments.mx/reader034/viewer/2022051311/54568ccdb1af9f33608b4b58/html5/thumbnails/40.jpg)
CONFIDENTIAL ©2013 GlobalLogic Inc.
Skype: sergey.nezdoliy
Twitter: @sergey_nezdoliy
Mail: [email protected]
Thank you