Unit testing
• Robolectric + Mockito
• No emulator = fast
• Focus on ViewModel and Model.
Activity and Fragment are not target.
• Easy to inject mock objects by Dagger 2
• Run by git push on Circle CI
Slide 9
Slide 9 text
mockito-kotlin
• mockito extension for Kotlin
• `when` problem
• NPE on any
• Easy to read & write
Slide 10
Slide 10 text
@Test
fun doAction_doesSomething(){
/* Given */
val mock = mock {
on { getText() } doReturn "text"
}
val classUnderTest = ClassUnderTest(mock)
/* When */
classUnderTest.doAction()
/* Then */
verify(mock).doSomething(any())
}
Slide 11
Slide 11 text
jacoco-android-gradle-plugin
• Add gradle tasks to run unit test and code
coverage
• Need to exclude classes generated by kapt
• Data binding, ORM, Parcelable, etc
• No badge now
• Codecov, Coveralls
Slide 12
Slide 12 text
ktlint-gradle
• Coding style checker and formatter for Kotlin
• Default style is official style from kotlinlang.org
• Not same as Android Studio default setting
• Override: ktlint —apply-to-idea
• Run style check on Circle CI
Slide 13
Slide 13 text
cookpad/license-tools-plugin
• Generate license page by gradle task
• Check licenses on Circle CI
• Avoid missing license
Slide 14
Slide 14 text
Testing
• Unit testing
• UI testing
Slide 15
Slide 15 text
UI testing
• Espresso + UI automator
• Use Espresso basically
• Use UI automator to OS/other app UI (ex. permission
dialog)
• Don’t run on CI due to long exec time
• Run before release to confirm important flows don’t degrade
• ex. Sign up flow
Slide 16
Slide 16 text
Mock in UI testing
• MockWebServer of Retrofit
• Unlike Mockito, JSON parse can be tested
• Share MockWebServer object between
Application class and test classes
• Change API response at every test case
Slide 17
Slide 17 text
Firebase Test Lab
• Still experimental
• Run UI testing on OS x device matrix
• In parallel
• Video recording in testing
• 5 or 10 tests/day in free plan
• Run before release manually?
Slide 18
Slide 18 text
Continuous Delivery
Slide 19
Slide 19 text
Crashlytics
• Share the latest apk to team
• master branch = debug build
• Development endpoint
• Debug screen with debot
• Deploy at every git push (10~ times / day)
• release/1.2.3 branch = beta build
• Production endpoint
• Deploy at code freeze
Slide 20
Slide 20 text
Google Play
• gradle-play-publisher
• Gradle wrapper of Google Play Developer API
• Need to set up Google API console
• Can publish as alpha, beta and staging rollout
• Triggered by GitHub Release (git tag)
• However CircleCI 2.0 doesn't support tag…
Slide 21
Slide 21 text
Workaround
• Add CircleCI 1.0 deployment block
deployment:
fake_deploy_for_cci2:
tag: /.*/
commands:
- echo "make tags run in 2.0"
Slide 22
Slide 22 text
Version name and code
// App version
def versionMajor = 1
def versionMinor = 11
def versionPatch = 2
// version code
def vc = 0
if (System.getenv("CIRCLE_TAG") != null) {
// tag = release build
vc = versionMajor * 10000 + versionMinor * 100 + versionPatch
} else if ("true" == System.getenv("CI")) {
// no tag but CI = dev build
vc = System.getenv("CIRCLE_BUILD_NUM") as Integer
} else {
// otherwise = local build
vc = versionMajor * 10000 + versionMinor * 100 + versionPatch
}
Slide 23
Slide 23 text
CircleCI
Slide 24
Slide 24 text
Like
• Can start by free event if private repo
• Many users
• We can search YAML file on GitHub
• Kind support
• ex. Memory limit of my project has been
increased before
Slide 25
Slide 25 text
Dislike
• OOM
• Slow build
• Official docs is still poor
Slide 26
Slide 26 text
Dislike (CircleCI 2.0)
• OOM Fixed?
• Slow build Fixed
• Official docs is still poor
Slide 27
Slide 27 text
CircleCI 1.0 -> 2.0
Build time 60% down
Slide 28
Slide 28 text
Breakdown (Total 5:30)
Slide 29
Slide 29 text
Breakdown (Total 5:30)
Unit testing
Deploy
Slide 30
Slide 30 text
I want…
• Trigger by git tag
• Firebase Test Lab on CircleCI 2.0
• Docs
• There is only docs for CircleCI 1.0
• May need Docker image?