SlideShare uma empresa Scribd logo
Material:
Melhorando seu App com Kotlin e Testes
Eduardo Carrara
@DuCarrara
Android Developer
Material:
Adoramos melhorar nossas aplicações!
Para nossos usuários e nós mesmos!
Material: Photo by Carl Rice on carlrice.io
Kotlin esta aí!
Material:
Null Safety
Menor verbosidade
Integração com Java
Properties
String Templates
Sem Checked Exceptions
Expressões Lambda
Extension Functions
Inline Functions
Data Classes
Material:
Functions
fun noArgumentsFunction() { /* ... */ }
fun withArgumentsFunction(firstArgument: String, secondArgument: Int){
/* ... */
}
fun oneLiner() = "No value"
fun sum(a: Int, b: Int) = a + b
Material:
Variables
// Immutable
val variable: Int = 5
val variable2: String
val variable3 = 345
// Mutable
var variable4 = "Testing"
var variable5 = listOf("One",
"Two", "Three")
var variable6: Long
Material:
Classes
open class SimpleClass
class ComplexClass : SimpleClass()
data class DataClass(val immutableValue: Int = 123)
object ObjectClass
fun justForFun() {
val dataClassInstance = DataClass()
val dataClassInstance2 = DataClass(immutableValue = 438)
print(dataClassInstance.immutableValue)
}
Material:
Lambdas
// lambda ou função anônima
val lambdaFunction = { a: Int, b: Int -> a + b }
val toIntLambda = { value: String -> value.toInt() }
// "Useless" Higher Order Function
fun map(value: String, transform: (String) -> Int) = transform(value)
fun messingAround() {
print(map("458", toIntLambda))
print(map("458", { s -> s.toInt() }))
}
Material:
Extension Functions
fun String.toInt(): Int = java.lang.Integer.parseInt(this)
fun Int.isNegative(): Boolean = this < 0
Material:
Material:
Como começar a refatorar meu app?
Qual o estado atual do meu código?
Material:
Minha App
Um olhar sobre a Arquitetura
Feature A
Presentation
Domain
Data
Feature B
Presentation
Domain
Data
Feature C
Presentation
Domain
Data
Material:
Megazord Monolith
Um Olhar sobre Arquitetura (Realidade)
Component
Zord
Component
Zord
Component
Zord
Component
Zord
Component
Zord
Component
Zord
Component
Zord
Component
Zord
Material:
Vá em frente e quebre umas features por aí...
ou
Tentar algo mais tranquilo?
Photo by The Matrix Movie
Material:
Que tal começar
com testes?
Photo by Danielle MacInnes on Unsplash
Material:
Por onde começar?
Testes funcionais com foco no usuário
Escolha uma delas para começar
Entenda e mapeie as funcionalidades mais importantes
Utilize Espresso + Kotlin para automatizar os testes
Material:
Crash Course
Espresso Cheat Sheet
Material:
ViewMatcher ViewAction ViewAssertion
Crash Course
withId
withText
isDisplayed
isVisible
is
...
click
doubleClick
longClick
pressBack
scrollTo
...
matches
doesNotExist
isLeftOf
isAbove
...
Material:
Anatomia de um Instrumentation Test
@RunWith(AndroidJUnit4::class)
class TestClass {
@get:Rule
var activityInitializationRule =
ActivityTestRule<TestActivity>(TestActivity::class.java)
@Test
fun simpleTest() { /* test stuff */ }
}
Test Runner
Class Definition
Initialization Rule
Test
Material:
Um teste não tão simples!
@Test
fun whenOpened_withOneBookLending_displayBookLendingCorrectly_pureEspresso() {
val fakeBook = testDataRule.fakeBook
onView(allOf<View>(withId(R.id.book_name_text_view),
hasSibling(withText(fakeBook.title)))
).check(matches(isDisplayed()))
onView(allOf<View>(withId(R.id.book_author_text_view),
hasSibling(withText(fakeBook.authors.joinToString(","))))
).check(matches(isDisplayed()))
}
Code: https://goo.gl/RR7DxW
Material:
Realmente novo?
Material:
Instrumentation Testing Robots
Um Pattern com foco na organização dos testes
Melhorar a legibilidade e manutenção dos testes
Separar "o como testar" do "o que testar"
Muito similar aos Page Objects
Test
(O que)
Robot
(O como)
View
Presenter
(O como)
Fake Model
(O que)
Material:
Um Teste mais Feliz
@Test
fun whenOpened_withOneBookLending_displayBookLendingCorrectly() {
val fakeBook = testDataRule.fakeBook
lentBooks {
checkForBookTitle(fakeBook.title)
checkForBookAuthors(fakeBook.authors.joinToString(","))
}
}
Code: https://goo.gl/RR7DxW
Material:
ITR Internals
class LentBooksRobot {
fun checkForBookTitle(expectedTitle: String): LentBooksRobot {
onView(allOf<View>(withId(R.id.book_name_text_view),
hasSibling(withText(expectedTitle)))
).check(ViewAssertions.matches(isDisplayed()))
return this
}
}
Code: https://goo.gl/c4K6bo
Material:
ITR Internals
class LentBooksRobot {
...
}
fun lentBooks(func: LentBooksRobot.() -> Unit) =
LentBooksRobot().apply { func() }
Code: https://goo.gl/c4K6bo
Material:
ITR - Outro Exemplo
@Test
fun lendBookToContact() {
val expectedIsbn = "8575224123"
val expectedBookTitle
= "Dominando o Android"
lentBooks {
addBookLending()
}
searchBook {
fillIsbn(expectedIsbn)
confirm()
}
bookDetails {
checkForBookTitle(expectedBookTitle)
checkForBookIsbn10("ISBN-10: $expectedIsbn")
lend()
}
contacts {
pickContact("Meu Irmao")
}
lentBooks {
checkForBookTitle(expectedBookTitle)
}
...
Code: https://goo.gl/cbMLLA
Material:
Suficiente?
Temos nossa "proteção" inicial contra bugs, mas lembre-se ...
Maior probabilidade de Test Flakiness
Testes instrumentados são mais lentos
E agora?
Material:
Hora de atacar o Megazord!
Material:
Parta para o Refactoring
Modularize, Isole Componentes, Crie abstrações
Escreva testes unitários!
Adote padrões de Arquitetura
Material:
Testes Unitários
Verificam os "internals" da aplicação
Rápidos e Abrangentes
Viáveis com baixo acoplamento e em pequenas unidades
Utilize JUnit + Mockito (ou outras ferramentas de mocking)
Material:
Exemplo - Vilibra
App Data Layer
BookRepository
Outras
Camadas
RemoteDataSource
LocalDataSource
database
Serviços Externos
Material:
Testando o BookRepository
interface BookRepository {
fun getByIsbn(isbn: String): Maybe<Book>
}
class BookCachedRepository(
private val bookRemoteDataSource: BookRemoteDataSource,
private val bookLocalCache: BookLocalCache
) : BookRepository {
override fun getByIsbn(usbn: String): Maybe<Book> {
/* ... */
}
}
Material:
Testando o BookRepository
@RunWith(JUnit4::class)
class BookCachedRepositoryTest {
@Test
fun testingOurRepository() { }
}
Test Runner
Test
Material:
Testando o BookRepository - Mocks
@RunWith(MockitoJUnitRunner::class)
class BookCachedRepositoryTest {
}
@Mock
lateinit var bookRemoteDataSource: BookRemoteDataSource
@Mock
lateinit var bookLocalDataSource: BookLocalCache
Note: Mock the unmockable: opt-in mocking of final classes/methods
Material:
@RunWith(MockitoJUnitRunner::class)
class BookCachedRepositoryTest {
/* Mocks Configuration */
}
Testando o BookRepository - Tests
@Test
fun getByIsbn_whenCalled_withExistingIsbnInCache_returnsCachedBook() {
//Arrange
//Act
//Assert
}
Code: https://goo.gl/Ybh62x
Material:
Testando o BookRepository - Tests
@Test
fun getByIsbn_whenCalled_withExistingIsbnInCache_returnsCachedBook() {
//Arrange
//Act & Assert
}
val fakeBook = prepareFakeBook()
whenever(bookLocalDataSource[fakeBook.isbn10])
.thenReturn(Maybe.just(fakeBook))
val bookCachedRepository =
BookCachedRepository(bookRemoteDataSource, bookLocalDataSource)
bookCachedRepository.getByIsbn(fakeBook.isbn10)
.test()
.assertValue(fakeBook)
Code: https://goo.gl/Ybh62x
Material:
Último Truque!
@Test
fun getByIsbn_whenCalled_withExistingIsbnInCache_returnsCachedBook() {}
Podemos melhorar esse nome?
@Test
fun `Call to getByIsbn with ISBN in cache returns cached Book`()
Nota: isso, no android, só funciona com testes unitários. É necessário desabilitar a
verificação por IllegalAndroidIdentifier nas preferências da IDE para o target de
testes unitários.
Que tal...
Material:
Pensamentos Finais
Implementar melhorias é difícil e pode haver riscos.
Antes de qualquer refactoring proteja-se com testes.
Kotlin pode ajudar a melhorar seu código...
Photo by Martins Zemlickis on Unsplash
… mas não fará o trabalho por você! ;)
Material:
“… if you are afraid to change something it is clearly poorly designed.”
- Martin Fowler
Perguntas?
Material:
Eduardo Carrara
@DuCarrara
Obrigado!
github.com/ecarrara-araujo
Material:
Referências
1. Kotlin Home Page
2. The Kotlin Koan
3. Introduction to Kotlin (Google I/O '17)
4. Android Development with Kotlin by Jake Warthon
5. GOTO 2016 • Kotlin - Ready for Production - Hadi Hariri
6. Instrumentation Testing Robots by Jake Warthon
7. Espresso Cheat Sheet
8. Testing on Android Documentation by Android Developers
9. Android Testing Patterns Youtube Playlist
10. The Art of Unit Testing by Roy Osherove
11. Page Objects
12. Android Tests by Goggle Samples
13. Android Testing Templates by Google Samples
14. Mockito Kotlin Lib

Mais conteúdo relacionado

ODT
Guia Rápido Java
PPT
Aula5
PDF
TDC2016POA | Trilha Android - Testes no Android
PDF
TDC2016POA | Trilha Android - Testes no Android
PPTX
Uma abordagem de testes instrumentados usando MockK, Koin e Robot Pattern
PDF
Android: testes automatizados e TDD
PDF
Indo além com Automação de Testes de Apps Android
Guia Rápido Java
Aula5
TDC2016POA | Trilha Android - Testes no Android
TDC2016POA | Trilha Android - Testes no Android
Uma abordagem de testes instrumentados usando MockK, Koin e Robot Pattern
Android: testes automatizados e TDD
Indo além com Automação de Testes de Apps Android

Semelhante a Melhorando seu App com Kotlin e Testes (20)

PDF
Android DevConference - Indo além com automação de testes de apps Android
PDF
Turbinando o desenvolvimento Android com Kotlin
PDF
Não tem teste ? Já nasceu legado.
PPT
Palestra Ministrada no 3 Encontro do GTS-CE
PPTX
Workshop espresso
PPTX
Como escrever bons testes! - Dex transforming days
PDF
Testes: Por onde Começar?
PDF
Kotlin first
ODP
Palestra Mocks - AgileBrazil 2010
PDF
Kotlin no desenvolvimento Mobile - FTSL
PDF
Minicurso kotlin UTFPR
PDF
Minicurso kotlin no desenvolvimento mobile - UTFPR
PDF
Testes de Unidade com JUnit
PDF
Android DevConference - Automatizando testes sem sofrimento
KEY
Android testing PT-BR
PPTX
Android - Frameworks de Testes
PDF
Automatize seus testes de UI com a Espresso!
PPTX
Curso: Desenvolvimento de aplicativos híbridos (dia 2)
Android DevConference - Indo além com automação de testes de apps Android
Turbinando o desenvolvimento Android com Kotlin
Não tem teste ? Já nasceu legado.
Palestra Ministrada no 3 Encontro do GTS-CE
Workshop espresso
Como escrever bons testes! - Dex transforming days
Testes: Por onde Começar?
Kotlin first
Palestra Mocks - AgileBrazil 2010
Kotlin no desenvolvimento Mobile - FTSL
Minicurso kotlin UTFPR
Minicurso kotlin no desenvolvimento mobile - UTFPR
Testes de Unidade com JUnit
Android DevConference - Automatizando testes sem sofrimento
Android testing PT-BR
Android - Frameworks de Testes
Automatize seus testes de UI com a Espresso!
Curso: Desenvolvimento de aplicativos híbridos (dia 2)
Anúncio

Mais de Eduardo Carrara de Araujo (18)

PDF
Só um appzinho aê!? - O guia de sobrevivência para o dev da ideia inovadora a...
PDF
Android apps ci
PDF
2016 - Por que mobile?
PDF
Android ndk: Entering the native world
PDF
Android NDK: Entrando no Mundo Nativo
PDF
Implementation of a Participatory Sensing Solution to Collect Data About Pave...
PDF
GDG ABC - Aventura 2015
PDF
Android Test Automation Workshop
PDF
Android M - Getting Started
PDF
Testando Sua App Android na Nuvem
PDF
Utilizando Espresso e UIAutomator no Teste de Apps Android
PDF
Começando com Android (#AndroidOnIntel)
PDF
Android Auto Basics
PDF
Debugging in Android
PDF
Android 101: Do Plano ao Play
PDF
Testing Your App in the Cloud
PPTX
Android 101: Do Plano ao Play em 30 minutos
Só um appzinho aê!? - O guia de sobrevivência para o dev da ideia inovadora a...
Android apps ci
2016 - Por que mobile?
Android ndk: Entering the native world
Android NDK: Entrando no Mundo Nativo
Implementation of a Participatory Sensing Solution to Collect Data About Pave...
GDG ABC - Aventura 2015
Android Test Automation Workshop
Android M - Getting Started
Testando Sua App Android na Nuvem
Utilizando Espresso e UIAutomator no Teste de Apps Android
Começando com Android (#AndroidOnIntel)
Android Auto Basics
Debugging in Android
Android 101: Do Plano ao Play
Testing Your App in the Cloud
Android 101: Do Plano ao Play em 30 minutos
Anúncio

Melhorando seu App com Kotlin e Testes

  • 1. Material: Melhorando seu App com Kotlin e Testes Eduardo Carrara @DuCarrara Android Developer
  • 2. Material: Adoramos melhorar nossas aplicações! Para nossos usuários e nós mesmos!
  • 3. Material: Photo by Carl Rice on carlrice.io Kotlin esta aí!
  • 4. Material: Null Safety Menor verbosidade Integração com Java Properties String Templates Sem Checked Exceptions Expressões Lambda Extension Functions Inline Functions Data Classes
  • 5. Material: Functions fun noArgumentsFunction() { /* ... */ } fun withArgumentsFunction(firstArgument: String, secondArgument: Int){ /* ... */ } fun oneLiner() = "No value" fun sum(a: Int, b: Int) = a + b
  • 6. Material: Variables // Immutable val variable: Int = 5 val variable2: String val variable3 = 345 // Mutable var variable4 = "Testing" var variable5 = listOf("One", "Two", "Three") var variable6: Long
  • 7. Material: Classes open class SimpleClass class ComplexClass : SimpleClass() data class DataClass(val immutableValue: Int = 123) object ObjectClass fun justForFun() { val dataClassInstance = DataClass() val dataClassInstance2 = DataClass(immutableValue = 438) print(dataClassInstance.immutableValue) }
  • 8. Material: Lambdas // lambda ou função anônima val lambdaFunction = { a: Int, b: Int -> a + b } val toIntLambda = { value: String -> value.toInt() } // "Useless" Higher Order Function fun map(value: String, transform: (String) -> Int) = transform(value) fun messingAround() { print(map("458", toIntLambda)) print(map("458", { s -> s.toInt() })) }
  • 9. Material: Extension Functions fun String.toInt(): Int = java.lang.Integer.parseInt(this) fun Int.isNegative(): Boolean = this < 0
  • 11. Material: Como começar a refatorar meu app? Qual o estado atual do meu código?
  • 12. Material: Minha App Um olhar sobre a Arquitetura Feature A Presentation Domain Data Feature B Presentation Domain Data Feature C Presentation Domain Data
  • 13. Material: Megazord Monolith Um Olhar sobre Arquitetura (Realidade) Component Zord Component Zord Component Zord Component Zord Component Zord Component Zord Component Zord Component Zord
  • 14. Material: Vá em frente e quebre umas features por aí... ou Tentar algo mais tranquilo? Photo by The Matrix Movie
  • 15. Material: Que tal começar com testes? Photo by Danielle MacInnes on Unsplash
  • 16. Material: Por onde começar? Testes funcionais com foco no usuário Escolha uma delas para começar Entenda e mapeie as funcionalidades mais importantes Utilize Espresso + Kotlin para automatizar os testes
  • 18. Material: ViewMatcher ViewAction ViewAssertion Crash Course withId withText isDisplayed isVisible is ... click doubleClick longClick pressBack scrollTo ... matches doesNotExist isLeftOf isAbove ...
  • 19. Material: Anatomia de um Instrumentation Test @RunWith(AndroidJUnit4::class) class TestClass { @get:Rule var activityInitializationRule = ActivityTestRule<TestActivity>(TestActivity::class.java) @Test fun simpleTest() { /* test stuff */ } } Test Runner Class Definition Initialization Rule Test
  • 20. Material: Um teste não tão simples! @Test fun whenOpened_withOneBookLending_displayBookLendingCorrectly_pureEspresso() { val fakeBook = testDataRule.fakeBook onView(allOf<View>(withId(R.id.book_name_text_view), hasSibling(withText(fakeBook.title))) ).check(matches(isDisplayed())) onView(allOf<View>(withId(R.id.book_author_text_view), hasSibling(withText(fakeBook.authors.joinToString(",")))) ).check(matches(isDisplayed())) } Code: https://goo.gl/RR7DxW
  • 22. Material: Instrumentation Testing Robots Um Pattern com foco na organização dos testes Melhorar a legibilidade e manutenção dos testes Separar "o como testar" do "o que testar" Muito similar aos Page Objects Test (O que) Robot (O como) View Presenter (O como) Fake Model (O que)
  • 23. Material: Um Teste mais Feliz @Test fun whenOpened_withOneBookLending_displayBookLendingCorrectly() { val fakeBook = testDataRule.fakeBook lentBooks { checkForBookTitle(fakeBook.title) checkForBookAuthors(fakeBook.authors.joinToString(",")) } } Code: https://goo.gl/RR7DxW
  • 24. Material: ITR Internals class LentBooksRobot { fun checkForBookTitle(expectedTitle: String): LentBooksRobot { onView(allOf<View>(withId(R.id.book_name_text_view), hasSibling(withText(expectedTitle))) ).check(ViewAssertions.matches(isDisplayed())) return this } } Code: https://goo.gl/c4K6bo
  • 25. Material: ITR Internals class LentBooksRobot { ... } fun lentBooks(func: LentBooksRobot.() -> Unit) = LentBooksRobot().apply { func() } Code: https://goo.gl/c4K6bo
  • 26. Material: ITR - Outro Exemplo @Test fun lendBookToContact() { val expectedIsbn = "8575224123" val expectedBookTitle = "Dominando o Android" lentBooks { addBookLending() } searchBook { fillIsbn(expectedIsbn) confirm() } bookDetails { checkForBookTitle(expectedBookTitle) checkForBookIsbn10("ISBN-10: $expectedIsbn") lend() } contacts { pickContact("Meu Irmao") } lentBooks { checkForBookTitle(expectedBookTitle) } ... Code: https://goo.gl/cbMLLA
  • 27. Material: Suficiente? Temos nossa "proteção" inicial contra bugs, mas lembre-se ... Maior probabilidade de Test Flakiness Testes instrumentados são mais lentos E agora?
  • 29. Material: Parta para o Refactoring Modularize, Isole Componentes, Crie abstrações Escreva testes unitários! Adote padrões de Arquitetura
  • 30. Material: Testes Unitários Verificam os "internals" da aplicação Rápidos e Abrangentes Viáveis com baixo acoplamento e em pequenas unidades Utilize JUnit + Mockito (ou outras ferramentas de mocking)
  • 31. Material: Exemplo - Vilibra App Data Layer BookRepository Outras Camadas RemoteDataSource LocalDataSource database Serviços Externos
  • 32. Material: Testando o BookRepository interface BookRepository { fun getByIsbn(isbn: String): Maybe<Book> } class BookCachedRepository( private val bookRemoteDataSource: BookRemoteDataSource, private val bookLocalCache: BookLocalCache ) : BookRepository { override fun getByIsbn(usbn: String): Maybe<Book> { /* ... */ } }
  • 33. Material: Testando o BookRepository @RunWith(JUnit4::class) class BookCachedRepositoryTest { @Test fun testingOurRepository() { } } Test Runner Test
  • 34. Material: Testando o BookRepository - Mocks @RunWith(MockitoJUnitRunner::class) class BookCachedRepositoryTest { } @Mock lateinit var bookRemoteDataSource: BookRemoteDataSource @Mock lateinit var bookLocalDataSource: BookLocalCache Note: Mock the unmockable: opt-in mocking of final classes/methods
  • 35. Material: @RunWith(MockitoJUnitRunner::class) class BookCachedRepositoryTest { /* Mocks Configuration */ } Testando o BookRepository - Tests @Test fun getByIsbn_whenCalled_withExistingIsbnInCache_returnsCachedBook() { //Arrange //Act //Assert } Code: https://goo.gl/Ybh62x
  • 36. Material: Testando o BookRepository - Tests @Test fun getByIsbn_whenCalled_withExistingIsbnInCache_returnsCachedBook() { //Arrange //Act & Assert } val fakeBook = prepareFakeBook() whenever(bookLocalDataSource[fakeBook.isbn10]) .thenReturn(Maybe.just(fakeBook)) val bookCachedRepository = BookCachedRepository(bookRemoteDataSource, bookLocalDataSource) bookCachedRepository.getByIsbn(fakeBook.isbn10) .test() .assertValue(fakeBook) Code: https://goo.gl/Ybh62x
  • 37. Material: Último Truque! @Test fun getByIsbn_whenCalled_withExistingIsbnInCache_returnsCachedBook() {} Podemos melhorar esse nome? @Test fun `Call to getByIsbn with ISBN in cache returns cached Book`() Nota: isso, no android, só funciona com testes unitários. É necessário desabilitar a verificação por IllegalAndroidIdentifier nas preferências da IDE para o target de testes unitários. Que tal...
  • 38. Material: Pensamentos Finais Implementar melhorias é difícil e pode haver riscos. Antes de qualquer refactoring proteja-se com testes. Kotlin pode ajudar a melhorar seu código... Photo by Martins Zemlickis on Unsplash … mas não fará o trabalho por você! ;)
  • 39. Material: “… if you are afraid to change something it is clearly poorly designed.” - Martin Fowler Perguntas?
  • 41. Material: Referências 1. Kotlin Home Page 2. The Kotlin Koan 3. Introduction to Kotlin (Google I/O '17) 4. Android Development with Kotlin by Jake Warthon 5. GOTO 2016 • Kotlin - Ready for Production - Hadi Hariri 6. Instrumentation Testing Robots by Jake Warthon 7. Espresso Cheat Sheet 8. Testing on Android Documentation by Android Developers 9. Android Testing Patterns Youtube Playlist 10. The Art of Unit Testing by Roy Osherove 11. Page Objects 12. Android Tests by Goggle Samples 13. Android Testing Templates by Google Samples 14. Mockito Kotlin Lib