SlideShare a Scribd company logo
Daniel Gallego Vico - Android Lead
daniel.gallego@bq.com
@thanos_malkav
The Pragmatic
Android Programmer
from hype to reality
Motivation of this talk
Previously on Android…
Motivation of this talk
CLEAN
SOLID
ReactiveX
MVP
MVVM
Hexagonal
Testing
CI
TDD
BDDDependency Injection
Flux
CD
Automation
Now on Android…
Kotlin
Motivation of this talk
My goal here: understand why before how
• Do not apply concepts you do not understand/need
• I will explain why during 2015 we decided to apply
most of the previous concepts and how we did it:
1. Pragmatic CLEAN architecture
2. Pragmatic testing
3. Pragmatic continuous Development/Testing/Integration/
Delivery
Pragmatic CLEAN
Architecture
Why
• Several projects in one year
• All of them from scratch
• We need maintainable/testable/decoupled/
easy to evolve projects
• Small team (6 developers)
• Impossible to work only in one project
• MUST change between projects smoothly
How: pragmatic clean architecture
View
View
Interface
Presenter
Presenter
Interface
Interactor
Interface
Interactor
ControllerWireframe
Wireframe
Interface
Controller
Interface
Android
Java
How: package structure
shared (pure Java module) Apps (Android module)
Trick: bind Views & Wireframes to Presenters
public interface BasePresenter<V, W> {



/** Called when the bound view is created. getView() will return a valid, active view from this point,
* point, so it is safe to start subscriptions or any other code depending on getView() */ 

void onCreateView();



/** Called when the bound view is about to be destroyed and unbound.

* getView() will return null from this point, so every subscription

* or any other code depending on getView() should be unsubscribed/managed. */

void onDestroyView();



/**

* Needed to create the relation between View-Presenter-Wireframe.

* @param view an active view of the needed type.

* @param wireframe an initialized wireframe of the needed type.

*/

void bindViewAndWireframe(V view, W wireframe);



/** Called after onDestroyView. Should perform clean-up of variables pointing to the view. */

void unBindViewAndWireframe();



/** @return the bound view. May be null if the view was unbound. */

V getView();



/** @return the bound Wireframe. */

W getWireframe();



/** Attach the subscription to the view lifecycle, and unsubscribe when it goes out of scope. /*

void track(Subscription subscription);



/** Unsubscribe all tracked subscriptions. */

void cancelSubscriptions();

}
Trick: bind Views & Wireframes to Presenters
public abstract class BaseCleanActivity<T extends BasePresenter<?, ?>> extends BaseActivity {

private T presenter;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// Retrieve presenter instance

this.presenter = resolvePresenter();

}



@Override

protected void onPostCreate(Bundle savedInstanceState) {

super.onPostCreate(savedInstanceState);

this.presenter.onCreateView();

}



protected abstract T resolvePresenter();



@Override

protected void onDestroy() {

super.onDestroy();

getPresenter().onDestroyView();

getPresenter().unBindViewAndWireframe();

}



protected T getPresenter() {

if (presenter.getView() != this) throw new IllegalArgumentException("Not bound!");

return presenter;

}

}
Trick: solving orientation changes
• Views use onSaveInstanceState
• Stateless Presenters are recreated
• State is recovered from network cache + database
• Single data retrieving flow
• High simplification of code vs Resource consumption
How: dependency injection
• Homemade solution
• Dagger 1 was too complicated (still no Dagger 2 release)
• The team needed to understand the benefits and how to use it
• Easier than expected
• Implementation:
• Shared: DependencyInjector + DependencyCache
• App: AndroidDependencyInjector
How: dependency injection
public abstract class DependencyInjector {
...
public abstract Scheduler provideUiScheduler();
public CalibrationPresenter provideCalibrationPresenter() {

return new CalibrationPresenterImpl(

provideConnectToZowiInteractor(),

provideMeasureZowiBatteryLevelInteractor(),

provideCheckInstalledZowiAppInteractor(),

provideSendAppToZowiInteractor(),
provideSendCommandToZowiInteractor(),

provideFactoryFirmwarePath(),

provideUiScheduler());

}
public MeasureZowiBatteryLevelInteractor provideMeasureZowiBatteryLevelInteractor() {

return new MeasureZowiBatteryLevelInteractorImpl(
provideSendCommandToZowiInteractor(),

provideZowiDataController());
}
public abstract BTConnectionController provideBTConnectionController();
...

}
How: dependency injection
public class AndroidDependencyInjector extends DependencyInjector {
...
@Override

public Scheduler provideUiScheduler() {

return AndroidSchedulers.mainThread();

}
@Override

public BTConnectionController provideBTConnectionController() {

return getCache().get(BTConnectionControllerImpl.class,
new DependencyCache.Provider<BTConnectionControllerImpl>() {

@NotNull

@Override

public BTConnectionControllerImpl get() {

return new BTConnectionControllerImpl(
application.getApplicationContext(),

BluetoothAdapter.getDefaultAdapter(),
provideSessionController(),
provideUiScheduler());

}

});

}
...
}
Why: Rx Java
• Easy to manage complex communications
• Great for projects involving HW
• Make thread management easier
• Beware of concurrency problems: they do not disappear!
• Improve team development speed…
• … once the initial learning curve is overcome
• RxAndroid only for AndroidSchedulers.mainThread();
How: Rx Java + CLEAN
View
View
Interface
Presenter
Presenter
Interface
Interactor
Interface
Interactor
ControllerWireframe
Wireframe
Interface
Controller
Interface
Android
Java
Future steps
• Package structure refactoring
• Order by feature, not CLEAN layer (avoid useless classes/interfaces)
• Improves maintainability and decouple features
• Shared (pure Java) module will disappear
• But will remain in every feature-package
• Dagger 2
• Too much boilerplate to maintain a homemade solution nowadays
• Improves visibility: we do not need everything public
• Helps testing
Pragmatic Testing
Why
• Small QA team:
• With a great functional framework
• But still very dependent of manual testing
• Unit and integration tests were needed to:
• Automate everything that can be automatically tested
• Spend QA team time in engineering tasks -> mental health
• Ensure quality before testing the app as a user will do
• Avoid the “Great certification” phenomenon (aka Ping-Pong)
• Keep crash rate under 1%

How: use case
• For “device storage is full” feature, we will show
• What is tested
• How it is done
• In every CLEAN layer
Click on
book
cover
Manage
click to
download
book
Tries to
download
or return
typed error
Computes
available
space
against file
size
Asks
system
about
storage
available
View Presenter Interactor
Storage
Controller
Device
Controller
How we tested this before
• QA people fill a device storage using adb
• Create a user with suitable context properties
• Able to download a book
• With a heavy book in the library
• Etc.
• Try to download the book manually
• Check that “No space message” error is shown
How: unit tests
• Interactor:
• Tests method in charge of returning NO_SPACE error when the device
does not have enough space for download
• Mocking controllers
• Controller:
• Tests method in charge of deciding whether or not the device has
enough space to download a file
• Mocking system
• Using JUnit & Mockito
How: integration tests
• Controller
• Tests usage of Android APIs responsible of informing about
device free storage in bytes
• Using Robolectric
• Shadow storage API
How: view tests
• View + Presenter
• Tests that a Dialog is shown to the user in case the device
does not have enough space to download a file
• Validates the interaction between view and presenter
• Do not test them separately!
• Using Mockito & Espresso
• Mocking interactors
How: smoke tests
• Backend API
• Tests request that informs the app about the file size to be
downloaded
• Using JUnit & Robolectric
• Working with Interactors/Controllers
• Useful for quick reporting of backend errors &
breaking changes
Future steps
• Improve current testing frameworks
• E.g. Analytics -> tests screen tracking
• Saves 2 hours of manually testing per certification
• Increase coverage
• Apply robot pattern
• To encode high level actions that takes place on a view in
order to use them in many tests
Pragmatic Continuous
Development/Testing/Integration/Delivery
• The repository must be a sanctuary
• Git-flow to avoid errors and allow hooks
• Everything is automated
• The less human intervention, the better
• Ensure that every pull-request passes the tests
• Otherwise, fail fast
• Easy daily distribution of APKs
• Real-time awareness of project state
Why
KEEP CALM
AND
AUTOMATE
How: automatic localization
• POeditor Android Gradle Plugin
• Allows single multi-platform string definition
• Download all strings files (every available lang) from PoEditor
• Process incoming strings to fix some PoEditor
incompatibilities with Android strings system
• Create strings.xml files to /values-<lang>
• or /values in case of the default lang
• Available on GitHub!
How: automatic localization flow
/values/strings.xml
/values-sw600dp/strings.xml
/values-es/strings.xml
/values-es-sw600dp/strings.xml
UX
multi-platform
strings
POeditor Android
Gradle Plugin
Marketing
Translation team
How: assets automation
• Automatic graphic resources integration
• Designers push resources to a suitable branch
• The branch is merged periodically
• Forget about Dropbox, Drive…
How: automate version code & name
/**

* Gets the version name from the latest Git tag. E.g. tag v.3.0.1.2 -> versionName 3.0.1.2

*/

def computeVersionName() {

def stdout = new ByteArrayOutputStream()

exec {

commandLine 'git', 'describe', '--abbrev=0', '--tags'

standardOutput = stdout

}

return stdout.toString().trim().replaceAll('v', '')

}



/**

* Gets the commit number from the current Git commit. E.g. 538

*/

def computeVersionCode() {

def stdout = new ByteArrayOutputStream()

exec {

commandLine 'git', 'rev-list', '--count', 'HEAD'

standardOutput = stdout

}

return stdout.toString().trim().toInteger()

}
defaultConfig {
versionName computeVersionName()

versionCode computeVersionCode()
...
}
Uses tag-flow
Increases snapshot version
only when HEAD is not tagged
How: pull-request workflow
pull-request to develop
Build
Test
Report
See
Stash pull request build plugin
Polling
Comment
result
Ninjas, ninjas everywhere…
But sometimes a ninja commit could be necessary/useful
How: daily snapshot workflow
tag-flow
assemble
git clone /develop
importGraphicResources
importPoEditorStrings
computeVersionCode
computeVersionName
build minified + sign
test
APK publication (maven-publish)
test results publication
Notify release: +
How: app delivery
• Daily snapshots of all necessary product flavors
• Homemade RepoApp allows coworkers to download the latest
version with one click
• Maven repository is hidden to make things easier
• Weekly delivery to Google Play alpha users
• Provides real feedback from real users = free manual testing
• Don’t worry about crashes!
• Google Play beta used to test RCs
• A promote to production!
How: project dashboard
• By monitoring Jenkins reports we know when
• A test has failed
• A build is broken
• And enjoy the pleasure of blaming
How: project dashboard
izan.moreno
How: project dashboard
• By monitoring Jira we know projects status
• Stories, improvements, tasks & bugs
• To do, in progress & blocked
How: project dashboard
How: project dashboard
• By monitoring Bugsnag we know the existing
problems:
• Errors
• Warnings
• Infos
How: project dashboard
How: project dashboard
• By monitoring Google Play we know
• Latest user reviews and ratings
• Average apps rating
• [4, 5]
• [3, 4)
• [1, 3)
How: project dashboard
Future steps
• SonarQube for static code analysis
• Performance analysis
• Update ticket status with build number after
successful pull requests
• Ready for QA
• Google Play REST API to automate publication
Final thoughts
Common sense
• Do not be afraid of improving when your context and
necessities demands it
• But please, do not be reckless when more people are
affected by your decisions
• And remember: hype is the enemy of reality
BQ Open Source
• https://github.com/bq/poeditor-android-gradle-plugin/
• https://github.com/bq/tag-flow
• Dashboard widgets based on Dashing.io
• Bugsnag Error: http://bit.ly/29LnMw2
• Google Play Reviews: http://bit.ly/2a0wNmG
• Google Play Rating: http://bit.ly/29z8aJO
The key to success is a great team
Daniel Gallego Vico - Android Lead
daniel.gallego@bq.com
@thanos_malkav
Namaste!

More Related Content

What's hot

Continuous delivery applied
Continuous delivery appliedContinuous delivery applied
Continuous delivery applied
Mike McGarr
 
How to Upgrade to the Newest Shiniest Django Version
How to Upgrade to the Newest Shiniest Django VersionHow to Upgrade to the Newest Shiniest Django Version
How to Upgrade to the Newest Shiniest Django Version
Susan Tan
 
AgileDC15 I'm Using Chef So I'm DevOps Right?
AgileDC15 I'm Using Chef So I'm DevOps Right?AgileDC15 I'm Using Chef So I'm DevOps Right?
AgileDC15 I'm Using Chef So I'm DevOps Right?
Rob Brown
 
DevOps Unicorns
DevOps UnicornsDevOps Unicorns
DevOps Unicorns
Matt O'Keefe
 
Критика "библиотечного" подхода в разработке под Android. UA Mobile 2016.
Критика "библиотечного" подхода в разработке под Android. UA Mobile 2016.Критика "библиотечного" подхода в разработке под Android. UA Mobile 2016.
Критика "библиотечного" подхода в разработке под Android. UA Mobile 2016.
UA Mobile
 
Creative Branching Models for Multiple Release Streams
Creative Branching Models for Multiple Release StreamsCreative Branching Models for Multiple Release Streams
Creative Branching Models for Multiple Release Streams
Atlassian
 
Continuous Integration using Cruise Control
Continuous Integration using Cruise ControlContinuous Integration using Cruise Control
Continuous Integration using Cruise Control
elliando dias
 
Blazing Fast Feedback Loops in the Java Universe
Blazing Fast Feedback Loops in the Java UniverseBlazing Fast Feedback Loops in the Java Universe
Blazing Fast Feedback Loops in the Java Universe
Michał Kordas
 
Continuous integration
Continuous integrationContinuous integration
Continuous integration
amscanne
 
The devops approach to monitoring, Open Source and Infrastructure as Code Style
The devops approach to monitoring, Open Source and Infrastructure as Code StyleThe devops approach to monitoring, Open Source and Infrastructure as Code Style
The devops approach to monitoring, Open Source and Infrastructure as Code Style
Julien Pivotto
 
Continuous Integration for Spark Apps by Sean McIntyre
Continuous Integration for Spark Apps by Sean McIntyreContinuous Integration for Spark Apps by Sean McIntyre
Continuous Integration for Spark Apps by Sean McIntyre
Spark Summit
 
Monitoring 改造計畫:流程觀點
Monitoring 改造計畫:流程觀點Monitoring 改造計畫:流程觀點
Monitoring 改造計畫:流程觀點
William Yeh
 
Continuous Integration, Build Pipelines and Continuous Deployment
Continuous Integration, Build Pipelines and Continuous DeploymentContinuous Integration, Build Pipelines and Continuous Deployment
Continuous Integration, Build Pipelines and Continuous Deployment
Christopher Read
 
ContainerCon - Test Driven Infrastructure
ContainerCon - Test Driven InfrastructureContainerCon - Test Driven Infrastructure
ContainerCon - Test Driven Infrastructure
Yury Tsarev
 
Testing API's: Tools & Tips & Tricks (Oh My!)
Testing API's: Tools & Tips & Tricks (Oh My!)Testing API's: Tools & Tips & Tricks (Oh My!)
Testing API's: Tools & Tips & Tricks (Oh My!)
Ford Prior
 
How to Build and Maintain Quality Drupal Sites with Automated Testing
How to Build and Maintain Quality Drupal Sites with Automated TestingHow to Build and Maintain Quality Drupal Sites with Automated Testing
How to Build and Maintain Quality Drupal Sites with Automated Testing
Acquia
 
CI back to basis
CI back to basisCI back to basis
CI back to basis
Sergio Navarro Pino
 
Back to basic: continuous integration (Madrid DevOps)
Back to basic: continuous integration (Madrid DevOps)Back to basic: continuous integration (Madrid DevOps)
Back to basic: continuous integration (Madrid DevOps)
Sergio Navarro Pino
 
Mobile Apps development best practices. TDD, CI, CD
Mobile Apps development best practices. TDD, CI, CDMobile Apps development best practices. TDD, CI, CD
Mobile Apps development best practices. TDD, CI, CD
GlobalLogic Ukraine
 
Continuous Delivery: The Dirty Details
Continuous Delivery: The Dirty DetailsContinuous Delivery: The Dirty Details
Continuous Delivery: The Dirty Details
Mike Brittain
 

What's hot (20)

Continuous delivery applied
Continuous delivery appliedContinuous delivery applied
Continuous delivery applied
 
How to Upgrade to the Newest Shiniest Django Version
How to Upgrade to the Newest Shiniest Django VersionHow to Upgrade to the Newest Shiniest Django Version
How to Upgrade to the Newest Shiniest Django Version
 
AgileDC15 I'm Using Chef So I'm DevOps Right?
AgileDC15 I'm Using Chef So I'm DevOps Right?AgileDC15 I'm Using Chef So I'm DevOps Right?
AgileDC15 I'm Using Chef So I'm DevOps Right?
 
DevOps Unicorns
DevOps UnicornsDevOps Unicorns
DevOps Unicorns
 
Критика "библиотечного" подхода в разработке под Android. UA Mobile 2016.
Критика "библиотечного" подхода в разработке под Android. UA Mobile 2016.Критика "библиотечного" подхода в разработке под Android. UA Mobile 2016.
Критика "библиотечного" подхода в разработке под Android. UA Mobile 2016.
 
Creative Branching Models for Multiple Release Streams
Creative Branching Models for Multiple Release StreamsCreative Branching Models for Multiple Release Streams
Creative Branching Models for Multiple Release Streams
 
Continuous Integration using Cruise Control
Continuous Integration using Cruise ControlContinuous Integration using Cruise Control
Continuous Integration using Cruise Control
 
Blazing Fast Feedback Loops in the Java Universe
Blazing Fast Feedback Loops in the Java UniverseBlazing Fast Feedback Loops in the Java Universe
Blazing Fast Feedback Loops in the Java Universe
 
Continuous integration
Continuous integrationContinuous integration
Continuous integration
 
The devops approach to monitoring, Open Source and Infrastructure as Code Style
The devops approach to monitoring, Open Source and Infrastructure as Code StyleThe devops approach to monitoring, Open Source and Infrastructure as Code Style
The devops approach to monitoring, Open Source and Infrastructure as Code Style
 
Continuous Integration for Spark Apps by Sean McIntyre
Continuous Integration for Spark Apps by Sean McIntyreContinuous Integration for Spark Apps by Sean McIntyre
Continuous Integration for Spark Apps by Sean McIntyre
 
Monitoring 改造計畫:流程觀點
Monitoring 改造計畫:流程觀點Monitoring 改造計畫:流程觀點
Monitoring 改造計畫:流程觀點
 
Continuous Integration, Build Pipelines and Continuous Deployment
Continuous Integration, Build Pipelines and Continuous DeploymentContinuous Integration, Build Pipelines and Continuous Deployment
Continuous Integration, Build Pipelines and Continuous Deployment
 
ContainerCon - Test Driven Infrastructure
ContainerCon - Test Driven InfrastructureContainerCon - Test Driven Infrastructure
ContainerCon - Test Driven Infrastructure
 
Testing API's: Tools & Tips & Tricks (Oh My!)
Testing API's: Tools & Tips & Tricks (Oh My!)Testing API's: Tools & Tips & Tricks (Oh My!)
Testing API's: Tools & Tips & Tricks (Oh My!)
 
How to Build and Maintain Quality Drupal Sites with Automated Testing
How to Build and Maintain Quality Drupal Sites with Automated TestingHow to Build and Maintain Quality Drupal Sites with Automated Testing
How to Build and Maintain Quality Drupal Sites with Automated Testing
 
CI back to basis
CI back to basisCI back to basis
CI back to basis
 
Back to basic: continuous integration (Madrid DevOps)
Back to basic: continuous integration (Madrid DevOps)Back to basic: continuous integration (Madrid DevOps)
Back to basic: continuous integration (Madrid DevOps)
 
Mobile Apps development best practices. TDD, CI, CD
Mobile Apps development best practices. TDD, CI, CDMobile Apps development best practices. TDD, CI, CD
Mobile Apps development best practices. TDD, CI, CD
 
Continuous Delivery: The Dirty Details
Continuous Delivery: The Dirty DetailsContinuous Delivery: The Dirty Details
Continuous Delivery: The Dirty Details
 

Similar to Droidcon Spain 2016 - The Pragmatic Android Programmer: from hype to reality

Cerberus : Framework for Manual and Automated Testing (Web Application)
Cerberus : Framework for Manual and Automated Testing (Web Application)Cerberus : Framework for Manual and Automated Testing (Web Application)
Cerberus : Framework for Manual and Automated Testing (Web Application)
CIVEL Benoit
 
Cerberus_Presentation1
Cerberus_Presentation1Cerberus_Presentation1
Cerberus_Presentation1
CIVEL Benoit
 
All about that reactive ui
All about that reactive uiAll about that reactive ui
All about that reactive ui
Paul van Zyl
 
Agile Secure Cloud Application Development Management
Agile Secure Cloud Application Development ManagementAgile Secure Cloud Application Development Management
Agile Secure Cloud Application Development Management
Adam Getchell
 
From 0 to DevOps in 80 Days [Webinar Replay]
From 0 to DevOps in 80 Days [Webinar Replay]From 0 to DevOps in 80 Days [Webinar Replay]
From 0 to DevOps in 80 Days [Webinar Replay]
Dynatrace
 
Test Driven Development & CI/CD
Test Driven Development & CI/CDTest Driven Development & CI/CD
Test Driven Development & CI/CD
Shanmuga S Muthu
 
STAQ Development Manual (Redacted)
STAQ Development Manual (Redacted)STAQ Development Manual (Redacted)
STAQ Development Manual (Redacted)
Mike Subelsky
 
Unlocking the Power of ChatGPT and AI in Testing - NextSteps, presented by Ap...
Unlocking the Power of ChatGPT and AI in Testing - NextSteps, presented by Ap...Unlocking the Power of ChatGPT and AI in Testing - NextSteps, presented by Ap...
Unlocking the Power of ChatGPT and AI in Testing - NextSteps, presented by Ap...
Applitools
 
Mobile App Quality Roadmap for DevTest Teams
Mobile App Quality Roadmap for DevTest TeamsMobile App Quality Roadmap for DevTest Teams
Mobile App Quality Roadmap for DevTest Teams
Perfecto by Perforce
 
Testing for Logic App Solutions | Integration Monday
Testing for Logic App Solutions | Integration MondayTesting for Logic App Solutions | Integration Monday
Testing for Logic App Solutions | Integration Monday
BizTalk360
 
PAC 2019 virtual Bruno Audoux
PAC 2019 virtual Bruno Audoux PAC 2019 virtual Bruno Audoux
PAC 2019 virtual Bruno Audoux
Neotys
 
Level Up Your Integration Testing With Testcontainers
Level Up Your Integration Testing With TestcontainersLevel Up Your Integration Testing With Testcontainers
Level Up Your Integration Testing With Testcontainers
VMware Tanzu
 
Continuous delivery is more than dev ops
Continuous delivery is more than dev opsContinuous delivery is more than dev ops
Continuous delivery is more than dev ops
Agile Montréal
 
Infrastructure as Code for Network
Infrastructure as Code for NetworkInfrastructure as Code for Network
Infrastructure as Code for Network
Damien Garros
 
Test automation proposal
Test automation proposalTest automation proposal
Test automation proposal
Mihai-Cristian Fratila
 
Pragmatic Monolith-First, easy to decompose, clean architecture
Pragmatic Monolith-First, easy to decompose, clean architecturePragmatic Monolith-First, easy to decompose, clean architecture
Pragmatic Monolith-First, easy to decompose, clean architecture
Piotr Pelczar
 
Встреча "QA: в каких направлениях может найти себя тестировщик?"
Встреча "QA: в каких направлениях может найти себя тестировщик?"Встреча "QA: в каких направлениях может найти себя тестировщик?"
Встреча "QA: в каких направлениях может найти себя тестировщик?"
GoIT
 
DevOps Fest 2020. Kohsuke Kawaguchi. GitOps, Jenkins X & the Future of CI/CD
DevOps Fest 2020. Kohsuke Kawaguchi. GitOps, Jenkins X & the Future of CI/CDDevOps Fest 2020. Kohsuke Kawaguchi. GitOps, Jenkins X & the Future of CI/CD
DevOps Fest 2020. Kohsuke Kawaguchi. GitOps, Jenkins X & the Future of CI/CD
DevOps_Fest
 
O365 Developer Bootcamp NJ 2018 - Material
O365 Developer Bootcamp NJ 2018 - MaterialO365 Developer Bootcamp NJ 2018 - Material
O365 Developer Bootcamp NJ 2018 - Material
Thomas Daly
 
5 Steps to Jump Start Your Test Automation
5 Steps to Jump Start Your Test Automation5 Steps to Jump Start Your Test Automation
5 Steps to Jump Start Your Test Automation
Sauce Labs
 

Similar to Droidcon Spain 2016 - The Pragmatic Android Programmer: from hype to reality (20)

Cerberus : Framework for Manual and Automated Testing (Web Application)
Cerberus : Framework for Manual and Automated Testing (Web Application)Cerberus : Framework for Manual and Automated Testing (Web Application)
Cerberus : Framework for Manual and Automated Testing (Web Application)
 
Cerberus_Presentation1
Cerberus_Presentation1Cerberus_Presentation1
Cerberus_Presentation1
 
All about that reactive ui
All about that reactive uiAll about that reactive ui
All about that reactive ui
 
Agile Secure Cloud Application Development Management
Agile Secure Cloud Application Development ManagementAgile Secure Cloud Application Development Management
Agile Secure Cloud Application Development Management
 
From 0 to DevOps in 80 Days [Webinar Replay]
From 0 to DevOps in 80 Days [Webinar Replay]From 0 to DevOps in 80 Days [Webinar Replay]
From 0 to DevOps in 80 Days [Webinar Replay]
 
Test Driven Development & CI/CD
Test Driven Development & CI/CDTest Driven Development & CI/CD
Test Driven Development & CI/CD
 
STAQ Development Manual (Redacted)
STAQ Development Manual (Redacted)STAQ Development Manual (Redacted)
STAQ Development Manual (Redacted)
 
Unlocking the Power of ChatGPT and AI in Testing - NextSteps, presented by Ap...
Unlocking the Power of ChatGPT and AI in Testing - NextSteps, presented by Ap...Unlocking the Power of ChatGPT and AI in Testing - NextSteps, presented by Ap...
Unlocking the Power of ChatGPT and AI in Testing - NextSteps, presented by Ap...
 
Mobile App Quality Roadmap for DevTest Teams
Mobile App Quality Roadmap for DevTest TeamsMobile App Quality Roadmap for DevTest Teams
Mobile App Quality Roadmap for DevTest Teams
 
Testing for Logic App Solutions | Integration Monday
Testing for Logic App Solutions | Integration MondayTesting for Logic App Solutions | Integration Monday
Testing for Logic App Solutions | Integration Monday
 
PAC 2019 virtual Bruno Audoux
PAC 2019 virtual Bruno Audoux PAC 2019 virtual Bruno Audoux
PAC 2019 virtual Bruno Audoux
 
Level Up Your Integration Testing With Testcontainers
Level Up Your Integration Testing With TestcontainersLevel Up Your Integration Testing With Testcontainers
Level Up Your Integration Testing With Testcontainers
 
Continuous delivery is more than dev ops
Continuous delivery is more than dev opsContinuous delivery is more than dev ops
Continuous delivery is more than dev ops
 
Infrastructure as Code for Network
Infrastructure as Code for NetworkInfrastructure as Code for Network
Infrastructure as Code for Network
 
Test automation proposal
Test automation proposalTest automation proposal
Test automation proposal
 
Pragmatic Monolith-First, easy to decompose, clean architecture
Pragmatic Monolith-First, easy to decompose, clean architecturePragmatic Monolith-First, easy to decompose, clean architecture
Pragmatic Monolith-First, easy to decompose, clean architecture
 
Встреча "QA: в каких направлениях может найти себя тестировщик?"
Встреча "QA: в каких направлениях может найти себя тестировщик?"Встреча "QA: в каких направлениях может найти себя тестировщик?"
Встреча "QA: в каких направлениях может найти себя тестировщик?"
 
DevOps Fest 2020. Kohsuke Kawaguchi. GitOps, Jenkins X & the Future of CI/CD
DevOps Fest 2020. Kohsuke Kawaguchi. GitOps, Jenkins X & the Future of CI/CDDevOps Fest 2020. Kohsuke Kawaguchi. GitOps, Jenkins X & the Future of CI/CD
DevOps Fest 2020. Kohsuke Kawaguchi. GitOps, Jenkins X & the Future of CI/CD
 
O365 Developer Bootcamp NJ 2018 - Material
O365 Developer Bootcamp NJ 2018 - MaterialO365 Developer Bootcamp NJ 2018 - Material
O365 Developer Bootcamp NJ 2018 - Material
 
5 Steps to Jump Start Your Test Automation
5 Steps to Jump Start Your Test Automation5 Steps to Jump Start Your Test Automation
5 Steps to Jump Start Your Test Automation
 

Recently uploaded

Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
SOCRadar
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
Green Software Development
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
Oracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptxOracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptx
Remote DBA Services
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
SMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API ServiceSMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API Service
Yara Milbes
 
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
mz5nrf0n
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
ICS
 
What is Master Data Management by PiLog Group
What is Master Data Management by PiLog GroupWhat is Master Data Management by PiLog Group
What is Master Data Management by PiLog Group
aymanquadri279
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
Rakesh Kumar R
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
Hornet Dynamics
 

Recently uploaded (20)

Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
Oracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptxOracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptx
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
SMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API ServiceSMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API Service
 
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
 
What is Master Data Management by PiLog Group
What is Master Data Management by PiLog GroupWhat is Master Data Management by PiLog Group
What is Master Data Management by PiLog Group
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
E-commerce Application Development Company.pdf
E-commerce Application Development Company.pdfE-commerce Application Development Company.pdf
E-commerce Application Development Company.pdf
 

Droidcon Spain 2016 - The Pragmatic Android Programmer: from hype to reality

  • 1. Daniel Gallego Vico - Android Lead daniel.gallego@bq.com @thanos_malkav The Pragmatic Android Programmer from hype to reality
  • 2. Motivation of this talk Previously on Android…
  • 3. Motivation of this talk CLEAN SOLID ReactiveX MVP MVVM Hexagonal Testing CI TDD BDDDependency Injection Flux CD Automation Now on Android… Kotlin
  • 5. My goal here: understand why before how • Do not apply concepts you do not understand/need • I will explain why during 2015 we decided to apply most of the previous concepts and how we did it: 1. Pragmatic CLEAN architecture 2. Pragmatic testing 3. Pragmatic continuous Development/Testing/Integration/ Delivery
  • 7. Why • Several projects in one year • All of them from scratch • We need maintainable/testable/decoupled/ easy to evolve projects • Small team (6 developers) • Impossible to work only in one project • MUST change between projects smoothly
  • 8. How: pragmatic clean architecture View View Interface Presenter Presenter Interface Interactor Interface Interactor ControllerWireframe Wireframe Interface Controller Interface Android Java
  • 9. How: package structure shared (pure Java module) Apps (Android module)
  • 10. Trick: bind Views & Wireframes to Presenters public interface BasePresenter<V, W> {
 
 /** Called when the bound view is created. getView() will return a valid, active view from this point, * point, so it is safe to start subscriptions or any other code depending on getView() */ 
 void onCreateView();
 
 /** Called when the bound view is about to be destroyed and unbound.
 * getView() will return null from this point, so every subscription
 * or any other code depending on getView() should be unsubscribed/managed. */
 void onDestroyView();
 
 /**
 * Needed to create the relation between View-Presenter-Wireframe.
 * @param view an active view of the needed type.
 * @param wireframe an initialized wireframe of the needed type.
 */
 void bindViewAndWireframe(V view, W wireframe);
 
 /** Called after onDestroyView. Should perform clean-up of variables pointing to the view. */
 void unBindViewAndWireframe();
 
 /** @return the bound view. May be null if the view was unbound. */
 V getView();
 
 /** @return the bound Wireframe. */
 W getWireframe();
 
 /** Attach the subscription to the view lifecycle, and unsubscribe when it goes out of scope. /*
 void track(Subscription subscription);
 
 /** Unsubscribe all tracked subscriptions. */
 void cancelSubscriptions();
 }
  • 11. Trick: bind Views & Wireframes to Presenters public abstract class BaseCleanActivity<T extends BasePresenter<?, ?>> extends BaseActivity {
 private T presenter;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 // Retrieve presenter instance
 this.presenter = resolvePresenter();
 }
 
 @Override
 protected void onPostCreate(Bundle savedInstanceState) {
 super.onPostCreate(savedInstanceState);
 this.presenter.onCreateView();
 }
 
 protected abstract T resolvePresenter();
 
 @Override
 protected void onDestroy() {
 super.onDestroy();
 getPresenter().onDestroyView();
 getPresenter().unBindViewAndWireframe();
 }
 
 protected T getPresenter() {
 if (presenter.getView() != this) throw new IllegalArgumentException("Not bound!");
 return presenter;
 }
 }
  • 12. Trick: solving orientation changes • Views use onSaveInstanceState • Stateless Presenters are recreated • State is recovered from network cache + database • Single data retrieving flow • High simplification of code vs Resource consumption
  • 13. How: dependency injection • Homemade solution • Dagger 1 was too complicated (still no Dagger 2 release) • The team needed to understand the benefits and how to use it • Easier than expected • Implementation: • Shared: DependencyInjector + DependencyCache • App: AndroidDependencyInjector
  • 14. How: dependency injection public abstract class DependencyInjector { ... public abstract Scheduler provideUiScheduler(); public CalibrationPresenter provideCalibrationPresenter() {
 return new CalibrationPresenterImpl(
 provideConnectToZowiInteractor(),
 provideMeasureZowiBatteryLevelInteractor(),
 provideCheckInstalledZowiAppInteractor(),
 provideSendAppToZowiInteractor(), provideSendCommandToZowiInteractor(),
 provideFactoryFirmwarePath(),
 provideUiScheduler());
 } public MeasureZowiBatteryLevelInteractor provideMeasureZowiBatteryLevelInteractor() {
 return new MeasureZowiBatteryLevelInteractorImpl( provideSendCommandToZowiInteractor(),
 provideZowiDataController()); } public abstract BTConnectionController provideBTConnectionController(); ...
 }
  • 15. How: dependency injection public class AndroidDependencyInjector extends DependencyInjector { ... @Override
 public Scheduler provideUiScheduler() {
 return AndroidSchedulers.mainThread();
 } @Override
 public BTConnectionController provideBTConnectionController() {
 return getCache().get(BTConnectionControllerImpl.class, new DependencyCache.Provider<BTConnectionControllerImpl>() {
 @NotNull
 @Override
 public BTConnectionControllerImpl get() {
 return new BTConnectionControllerImpl( application.getApplicationContext(),
 BluetoothAdapter.getDefaultAdapter(), provideSessionController(), provideUiScheduler());
 }
 });
 } ... }
  • 16. Why: Rx Java • Easy to manage complex communications • Great for projects involving HW • Make thread management easier • Beware of concurrency problems: they do not disappear! • Improve team development speed… • … once the initial learning curve is overcome • RxAndroid only for AndroidSchedulers.mainThread();
  • 17. How: Rx Java + CLEAN View View Interface Presenter Presenter Interface Interactor Interface Interactor ControllerWireframe Wireframe Interface Controller Interface Android Java
  • 18. Future steps • Package structure refactoring • Order by feature, not CLEAN layer (avoid useless classes/interfaces) • Improves maintainability and decouple features • Shared (pure Java) module will disappear • But will remain in every feature-package • Dagger 2 • Too much boilerplate to maintain a homemade solution nowadays • Improves visibility: we do not need everything public • Helps testing
  • 20. Why • Small QA team: • With a great functional framework • But still very dependent of manual testing • Unit and integration tests were needed to: • Automate everything that can be automatically tested • Spend QA team time in engineering tasks -> mental health • Ensure quality before testing the app as a user will do • Avoid the “Great certification” phenomenon (aka Ping-Pong) • Keep crash rate under 1%

  • 21. How: use case • For “device storage is full” feature, we will show • What is tested • How it is done • In every CLEAN layer Click on book cover Manage click to download book Tries to download or return typed error Computes available space against file size Asks system about storage available View Presenter Interactor Storage Controller Device Controller
  • 22. How we tested this before • QA people fill a device storage using adb • Create a user with suitable context properties • Able to download a book • With a heavy book in the library • Etc. • Try to download the book manually • Check that “No space message” error is shown
  • 23. How: unit tests • Interactor: • Tests method in charge of returning NO_SPACE error when the device does not have enough space for download • Mocking controllers • Controller: • Tests method in charge of deciding whether or not the device has enough space to download a file • Mocking system • Using JUnit & Mockito
  • 24. How: integration tests • Controller • Tests usage of Android APIs responsible of informing about device free storage in bytes • Using Robolectric • Shadow storage API
  • 25. How: view tests • View + Presenter • Tests that a Dialog is shown to the user in case the device does not have enough space to download a file • Validates the interaction between view and presenter • Do not test them separately! • Using Mockito & Espresso • Mocking interactors
  • 26. How: smoke tests • Backend API • Tests request that informs the app about the file size to be downloaded • Using JUnit & Robolectric • Working with Interactors/Controllers • Useful for quick reporting of backend errors & breaking changes
  • 27. Future steps • Improve current testing frameworks • E.g. Analytics -> tests screen tracking • Saves 2 hours of manually testing per certification • Increase coverage • Apply robot pattern • To encode high level actions that takes place on a view in order to use them in many tests
  • 29. • The repository must be a sanctuary • Git-flow to avoid errors and allow hooks • Everything is automated • The less human intervention, the better • Ensure that every pull-request passes the tests • Otherwise, fail fast • Easy daily distribution of APKs • Real-time awareness of project state Why KEEP CALM AND AUTOMATE
  • 30. How: automatic localization • POeditor Android Gradle Plugin • Allows single multi-platform string definition • Download all strings files (every available lang) from PoEditor • Process incoming strings to fix some PoEditor incompatibilities with Android strings system • Create strings.xml files to /values-<lang> • or /values in case of the default lang • Available on GitHub!
  • 31. How: automatic localization flow /values/strings.xml /values-sw600dp/strings.xml /values-es/strings.xml /values-es-sw600dp/strings.xml UX multi-platform strings POeditor Android Gradle Plugin Marketing Translation team
  • 32. How: assets automation • Automatic graphic resources integration • Designers push resources to a suitable branch • The branch is merged periodically • Forget about Dropbox, Drive…
  • 33. How: automate version code & name /**
 * Gets the version name from the latest Git tag. E.g. tag v.3.0.1.2 -> versionName 3.0.1.2
 */
 def computeVersionName() {
 def stdout = new ByteArrayOutputStream()
 exec {
 commandLine 'git', 'describe', '--abbrev=0', '--tags'
 standardOutput = stdout
 }
 return stdout.toString().trim().replaceAll('v', '')
 }
 
 /**
 * Gets the commit number from the current Git commit. E.g. 538
 */
 def computeVersionCode() {
 def stdout = new ByteArrayOutputStream()
 exec {
 commandLine 'git', 'rev-list', '--count', 'HEAD'
 standardOutput = stdout
 }
 return stdout.toString().trim().toInteger()
 } defaultConfig { versionName computeVersionName()
 versionCode computeVersionCode() ... } Uses tag-flow Increases snapshot version only when HEAD is not tagged
  • 34. How: pull-request workflow pull-request to develop Build Test Report See Stash pull request build plugin Polling Comment result
  • 35. Ninjas, ninjas everywhere… But sometimes a ninja commit could be necessary/useful
  • 36. How: daily snapshot workflow tag-flow assemble git clone /develop importGraphicResources importPoEditorStrings computeVersionCode computeVersionName build minified + sign test APK publication (maven-publish) test results publication Notify release: +
  • 37. How: app delivery • Daily snapshots of all necessary product flavors • Homemade RepoApp allows coworkers to download the latest version with one click • Maven repository is hidden to make things easier • Weekly delivery to Google Play alpha users • Provides real feedback from real users = free manual testing • Don’t worry about crashes! • Google Play beta used to test RCs • A promote to production!
  • 38. How: project dashboard • By monitoring Jenkins reports we know when • A test has failed • A build is broken • And enjoy the pleasure of blaming
  • 40. How: project dashboard • By monitoring Jira we know projects status • Stories, improvements, tasks & bugs • To do, in progress & blocked
  • 42. How: project dashboard • By monitoring Bugsnag we know the existing problems: • Errors • Warnings • Infos
  • 44. How: project dashboard • By monitoring Google Play we know • Latest user reviews and ratings • Average apps rating • [4, 5] • [3, 4) • [1, 3)
  • 46. Future steps • SonarQube for static code analysis • Performance analysis • Update ticket status with build number after successful pull requests • Ready for QA • Google Play REST API to automate publication
  • 48. Common sense • Do not be afraid of improving when your context and necessities demands it • But please, do not be reckless when more people are affected by your decisions • And remember: hype is the enemy of reality
  • 49. BQ Open Source • https://github.com/bq/poeditor-android-gradle-plugin/ • https://github.com/bq/tag-flow • Dashboard widgets based on Dashing.io • Bugsnag Error: http://bit.ly/29LnMw2 • Google Play Reviews: http://bit.ly/2a0wNmG • Google Play Rating: http://bit.ly/29z8aJO
  • 50. The key to success is a great team
  • 51. Daniel Gallego Vico - Android Lead daniel.gallego@bq.com @thanos_malkav Namaste!