Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Testing your app

Testing your app

#androidtest #unittest #integrationtest

José Caique Oliveira

February 09, 2019
Tweet

More Decks by José Caique Oliveira

Other Decks in Technology

Transcript

  1. T E S T I N G Y O U

    R A P P J O S É C A I Q U E
  2. W E W I L L S E E •

    Test advantages • How to write Unit Testing • How to write Integration Test • How to write Acceptance Test
  3. A D VA N TA G E S O F

    T E S T I N G • Keep code simple • Scalability • Best way to find bugs • Indicates refactoring opportunities
  4. If you test is failing, verify the code instead of

    delete the test I M P O R TA N T
  5. val maxRetries: Int = 4 fun shouldRetry(retryCount: Int): Boolean {

    return retryCount < maxRetries } W R I T I N G U N I T T E S T
  6. @Test fun `verify if should proceed with retries`(){ val retryCount

    = 3 val shouldProceed = shouldRetry(retryCount) assert(shouldProceed == true) } JUnit W R I T I N G U N I T T E S T
  7. W R I T I N G U N I

    T T E S T - M O C K Retrieve Movie - Real Retrieve Movie - MOCK Fake< > Movie(name ="Madman", url = "tt123") listOf(Movies)
  8. class ImdbViewModel(private val cache: CacheService): ViewModel { companion object {

    val URL = "https://m.imdb.com"} fun url() : String { return cacheService.retrieve<Movie>(Detail)?.let { "$URL/title/${imdb.value}" } ?: URL } W R I T I N G U N I T T E S T
  9. @Test fun `given a movie mount the url`() { val

    url = vm.url() assertThat(url) .isEqualTo(ImdbViewModel.URL + "/title/tt123" ) } assertJ W R I T I N G U N I T T E S T
  10. private val cache = mock<CacheService>() private val vm: ImdbViewModel(cache) private

    fun `cache return value`() { whenever(cache.retrieve<Movie>(any())) .thenAnswer { movie } } private val movie = Movie(name = "Madman", url = "tt123") Mockito/Mockito Kotlin W R I T I N G U N I T T E S T - M O C K I N G
  11. @Test fun `given a movie mount the url`() { `cache

    return a value`() val url = vm.url() assertThat(url) .isEqualTo(ImdbViewModel.URL + "/title/tt123" ) } W R I T I N G U N I T T E S T
  12. class FileCreator(private val context: Context) { private val RECEIPTS_PATH =

    "receipts" fun create(receiptInfo: FileReceipt): File { val pathFile = context.cacheDir return pathFile .resolve(RECEIPTS_PATH) .apply { if (!exists()) mkdir() } .resolve(“receipt.pdf”) .apply { this.writeBytes(receiptInfo.byteArray) } } } W R I T I N G U N I T T E S T
  13. private lateinit var creator: ReceiptFileCreator private val receipt = FileReceipt("123".toByteArray(),"fileName")

    @Before fun `before each test`() { val context = RuntimeEnvironment.application.applicationContext creator = ReceiptFileCreator(context) } @Test fun `given a file receipt should create a file`() { val file = creator.create(receiptInfo) assertThat(file.name).isEqualTo("fileName.pdf") } W R I T I N G U N I T T E S T - A N D R O I D robolectric
  14. object CountTheWords { operator fun invoke(text: String): Map<String, Int> {

    return text .split(' ') .asSequence() .filter { it.isNotBlank() } .groupingBy { it } .eachCount() } } object GetEveryTenthPosition { operator fun invoke(text: String): String { return text .asSequence() .filterIndexed { index, _ -> (index + 1) % 10 == 0 } .joinToString(" ") } }
  15. interface BlogService { fun retrieveBlogPost(): Observable<String> } class BlogPostProcessor (private

    val api: BlogService) { fun process(): Observable<Result> { return api .retrieveBlogPost() .map{ text -> Result( everyTenthPosition = GetEveryTenthPosition(text), wordCount = CountTheWords(text)) } } } data class Result( val everyTenthPosition: String, val wordCount:Map<String, Int> )
  16. class BlogPostProcessViewModel( private val useCase: BlogPostProcessor ) : ViewModel() {

    fun retrieveBlogPostInformation(): Observable<Result> { return useCase .process() } }
  17. W R I T I N G I N T

    E G R AT I O N T E S T val useCase = mock<BlogPostProcessor>() val vm = BlogPostProcessViewModel(useCase) val api = mock<BlogService>() val useCase = BlogPostProcessor(api) val vm = BlogPostProcessViewModel(useCase)
  18. W R I T I N G I N T

    E G R AT I O N T E S T fun `api return blog post`(){ val post = "a string to test the count count the words words" whenever(api.retrieveBlogPost()) .thenAnswer{ Observable.just(post) } } val expected = Result( wordCount = mapOf( "test" to 1, "count" to 2, "words" to 2), everyTenthPosition = "t t n n h w” ) @Test fun `given a blog post process the words`(){ `api return blog post`() val test = vm.retrieveBlogPostInformation().test() test.assertResult(expected) } RxJava Test
  19. I N T E G R AT I O N

    T E S T - CountTheWords - GetEveryTenthPosition - BlogPostProcessor - BlogPostProcessViewModel
  20. A C C E P TA N C E T

    E S T S Function N Function 1 Integration Test Acceptance Test(UI) Fake Function 1 Function N UI Interaction
  21. val shows = """ [ { "id": 250, "name": "Kirby",

    "language": "English", } ]""" val response = MockResponse() .setResponseCode(200) .setBody(shows) server.enqueue(response)
  22. open class MyApplication : Application() { open val url =

    "http://api.tvmaze.com/" } //inside androidTest folder class TestApplication : MyApplication() { override val url: String get() = "http://localhost:8080" }
  23. class MyRunner : AndroidJUnitRunner() { @Throws(InstantiationException::class, IllegalAccessException::class, ClassNotFoundException::class) override fun

    newApplication( cl: ClassLoader, className: String, c: Context): Application { return super .newApplication(cl, TestApplication::class.java.name, c) } } AndroidJUnitRunner
  24. android { compileSdkVersion 28 defaultConfig { applicationId "com.package.androidfest" minSdkVersion 24

    targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "com.my.package.MyRunner" } }
  25. W R I T I N G A C C

    E P TA N C E T E S T @get:Rule val activity = ActivityTestRule(MainActivity::class.java, true, false) val response = MockResponse() .setBody(shows) //json .setResponseCode(200) var server = MockWebServer() @Test fun verify_content_proper_showed() { server.start(8080) server.enqueue(response) activity.launchActivity() onView(withId(R.id.toolbar)).check(matches(isDisplayed())) onView(withId(R.id.moviesRv)).check(matches(isDisplayed())) }
  26. J C A I Q U E _ J O

    S E C A I Q U E J O S E C A I Q U E T H A N K S ! !