Screenshot Kata for Android Developers with Kotlin. The main goal is to practice UI Screenshot Testing.

Overview

Karumi logo KataScreenshot in Kotlin Build Status

You can compare this testing approach with a different testing strategy where the application UI is tested using just Espresso.


Getting started

This repository contains an Android application to show Super Heroes information:

ApplicationScreencast

This Application is based on two Activities:

  • MainActivity showing a list of super heroes with name, photo and a special badge if it is part of the Avengers Team.

MainActivityScreenhot

  • SuperHeroDetailActivity showing detailed information about a super hero like his or her name, photo and description.

SuperHeroDetailActivityScreenshot

The application architecture, dependencies and configuration is ready to just start writing tests. In this project you'll find Kodein configured to be able to replace production code with test doubles easily and Espresso to be able to interact with the application user interface and a screenshot testing framework ready to compare your application changes.

Remember that after any production code change you can record your screenshots again executing:

./gradlew executeScreenshotTests -Precord

To verify the correct behaviour of your code you can execute:

./gradlew executeScreenshotTests

To be able to get a deterministic test scenario all our tests will be executed on the same emulated device. You can use the Travis-CI configuration to get the same emulator working on your computer.

Tasks

Your task as Android Developer is to write all the UI tests needed to check if the Application UI is working as expected.

This repository is ready to build the application, pass the checkstyle and your tests in Travis-CI environments.

Our recommendation for this exercise is:

  • Before starting

    1. Fork this repository.
    2. Checkout kata-screenshot branch.
    3. Execute the application, explore it manually and make yourself familiar with the code.
    4. Execute MainActivityTest and watch the only test it contains pass.
  • To help you get started, these are some test cases for MainActivity:

    1. Setup mocked SuperHeroRepository in MainActivityTest to return a list of some Super Heroes.
    2. Test the MainActivity is showing the super heroes obtained from the SuperHeroesRepository.
    3. Test the empty case is shown if there are no super heroes.

Considerations

  • If you get stuck, master branch contains already solved tests for MainActivity, SuperHeroDetailActivity and SuperHeroViewHolder.

Extra Tasks

If you've covered all the application functionality using UI tests try to continue with the following tasks:

  • Add a pull to refresh mechanism to MainActivity and test it.
  • Modify SuperHeroDetailActivity to handle an error case where the name of the super hero used to start this activity does not exist and show a message if this happens.
  • Modify the project to handle connection errors and show a SnackBar to indicate something went wrong.
  • Modify SuperHeroesRepository test double to perform a Thread.sleep and use the custom idling resources you'll find in this repository to get your tests working.
  • Compare your tests implementation with the KataSuperHeroes solved using Espresso.

Documentation

There are some links which can be useful to finish these tasks:

Data provided by Marvel. © 2017 MARVEL

License

Copyright 2017 Karumi

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Comments
  • Add presenter

    Add presenter

    The scope of this pull request is setting the first version of MVP for the superhero kata.

    The idea is you can start to review the DI code, Presenter code and invocation between them.

    I will update the PR with a small test.

    opened by flipper83 3
  • Add usecase repository

    Add usecase repository

    This pull request contains the first commit with information come from use cases. I like update the PR step by steps because I have some code that I like your approval :)

    This first commit contains usercases, list representation and resultValues. Next commit will contains a list test and travis configuration. After that I will start working on repository code.

    opened by flipper83 1
  • Travis CI build failing and .iml files pushed up

    Travis CI build failing and .iml files pushed up

    opened by albodelu 0
  • Show the activity title with the appcompat toolbar

    Show the activity title with the appcompat toolbar

    :pushpin: References

    • Issue: #5

    :cyclone: Git merge message

    • Install the support toolbar in every activity through the BaseActivity class
    • Configure the toolbar title in the super hero detail view to show the super hero name
    • Remove error handling and funktional.either dependency as it's one of the extra task we are asking for in the kata.

    :memo: Notes

    • It's oddly satisfying to see how the two katas now produce the same screenshots 😅
    • I'll cherry-pick this PR into kata-screenshot branch BTW
    opened by Serchinastico 0
  • Super hero cell tests

    Super hero cell tests

    :pushpin: References

    • Issue: #4

    :cyclone: Git merge message

    • Create a ScreenshotTest trait with methods to verify that views/activities/viewholders are correct by using the Facebook library. The logic has been extracted from the previous AcceptanceTest class so that it can be used with non-activity tests
    • Create screenshot tests for super hero cells by just porting it from our Java implementation
    • Fix some typos in the travis configuration file

    :memo: Notes

    • There are some other minor style changes, don't even bother with those if you don't want to
    opened by Serchinastico 0
  • java.nio.file.NoSuchFileExceptio

    java.nio.file.NoSuchFileExceptio

    On Windows 10 x64 + AS 3.4.1

    run task executeScreenshotTests always encounter this exception

    It works fine on OSX but Windows at least I try it on 2 PCs The compare files will be placed correctly, but all the file size is 0

    Exception is:

    Caused by: org.gradle.api.UncheckedIOException: java.nio.file.NoSuchFileException: \tmp\shot\screenshot\app\com.entertainment.MainActivityTest_testScreenshotEntireActivity.png at org.gradle.internal.UncheckedException.throwAsUncheckedException(UncheckedException.java:61) at org.gradle.internal.UncheckedException.throwAsUncheckedException(UncheckedException.java:41) at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:76) at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:48) at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:41) at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28) at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:704) at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:671) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$2.run(ExecuteActionsTaskExecuter.java:284) at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:301) at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:293) at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:175) at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91) at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:273) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:258) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$200(ExecuteActionsTaskExecuter.java:67) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:145) at org.gradle.internal.execution.impl.steps.ExecuteStep.execute(ExecuteStep.java:49) at org.gradle.internal.execution.impl.steps.CancelExecutionStep.execute(CancelExecutionStep.java:34) at org.gradle.internal.execution.impl.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:69) at org.gradle.internal.execution.impl.steps.TimeoutStep.execute(TimeoutStep.java:49) at org.gradle.internal.execution.impl.steps.CatchExceptionStep.execute(CatchExceptionStep.java:33) at org.gradle.internal.execution.impl.steps.CreateOutputsStep.execute(CreateOutputsStep.java:50) at org.gradle.internal.execution.impl.steps.SnapshotOutputStep.execute(SnapshotOutputStep.java:43) at org.gradle.internal.execution.impl.steps.SnapshotOutputStep.execute(SnapshotOutputStep.java:29) at org.gradle.internal.execution.impl.steps.CacheStep.executeWithoutCache(CacheStep.java:134) at org.gradle.internal.execution.impl.steps.CacheStep.lambda$execute$3(CacheStep.java:83) at org.gradle.internal.execution.impl.steps.CacheStep.execute(CacheStep.java:82) at org.gradle.internal.execution.impl.steps.CacheStep.execute(CacheStep.java:36) at org.gradle.internal.execution.impl.steps.PrepareCachingStep.execute(PrepareCachingStep.java:33) at org.gradle.internal.execution.impl.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:38) at org.gradle.internal.execution.impl.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:23) at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:96) at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:89) at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:52) at org.gradle.internal.execution.impl.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:36) at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:34) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:91)

    opened by frog1014 0
Owner
Karumi
Karumi, the Rock Solid Code studio
Karumi
Maxibon kata for Kotlin Developers. The main goal is to practice property based testing.

Kata Maxibon for Kotlin. We are here to practice property based testing. We are going to use KotlinTest to write our tests. We are going to practice p

Karumi 44 Oct 3, 2022
TODO API Client Kata for Kotlin Developers. The main goal is to practice integration testing using MockWebServer

KataTODOApiClient for Kotlin We are here to practice integration testsing using HTTP stubbing. We are going to use MockWebServer to simulate a HTTP se

Karumi 61 Nov 20, 2022
KataContacts written in Kotlin. The main goal is to practice Clean Architecture Development

KataContacts written in Kotlin We are here to practice Clean Architecture Development. Clean Architecture is a way of structuring code. We are going t

Karumi 48 Oct 3, 2022
Kata to practice Clean Architecture & MVI by building TodoList Application

Mvi Todo Kata Application Features TODO specification Title Description Due Date Priority Supported Operations Create a new TODO Remove a TODO Select

seungmin shin 0 Nov 3, 2021
MVVM + Kotlin + Jetpack Compose +Navigation Compose + Hilt + Retrofit + Unit Testing + Compose Testing + Coroutines + Kotlin Flow + Io mockK

MvvmKotlinJetpackCompose Why do we need an architecture even when you can make an app without it? let's say you created a project without any architec

Sayyed Rizwan 46 Nov 29, 2022
Registration validation testing, Room database testing using JUnit4

Notes app Registration details validation testing, Room database testing using JUnit4 ✨ Screenshots Authors Tridev Deka - LinkedIn - Tridev Deka MIT L

Tridev Deka 0 Mar 30, 2022
Transport Tycoon Kata

Transport Tycoon Kata This is a kata proposed by SoftwarePark. You can find the original one here I modified some parts of it, to make it different, m

Albert Casanovas 0 Aug 30, 2022
Cody Engel 2 Apr 20, 2022
Shot is an Android project you can use to write screenshot for your apps in a simple and friendly way

Shot is an Android project you can use to write screenshot for your apps in a simple and friendly way. What is this? Shot is a Gradle plugin and

Pedro Gómez 1k Dec 30, 2022
A reliable android app that shows upcoming fixtures, updated league tables, and top goal scorers in a Premier League and French Ligue 1

RapidScore Screenshots Table of Contents Description Dependencies API Reference Lessons Learnt Contributing Roadmap Google Playstore License Author In

Breens Mbaka 12 Jul 7, 2022
Proyect with the goal to show my skills in android

ChipperMovie Es una aplicación de peliculas y sus detalles filtrados por categorias para demostrar el uso de mis habilidaedes en desarrollo movil. Ace

null 0 Nov 10, 2021
The goal of this assignment is to implement GameOfFifteen

Game of Fifteen Demo The board for the game of Fifteen is filled randomly with numbers from 1 to 15 and one empty space. You can move the neighboring

Josue Lubaki 0 Dec 6, 2021
GOD - Goal of the day is the notes app which tracks your daily tasks, most important tasks & monthly goals

GOD - Goal of the day GOD - Goals of the day Problem Statement: People always face problems in finding their goals and keeping track over a period. Th

Shubham Jitiya 1 Jan 16, 2022
A console-based productivity app involving both To-Do Lists and Goal tracking

This is a console-based productivity app involving both To-Do Lists and Goal tracking. It allows users to create To-Dos, check them off, and filter the display between complete/incomplete items

Joel Jossie 3 Dec 25, 2022
App consist of 4 main fragments accessable from bottom navigation

Bug demo Demo App consist of 4 main fragments accessable from bottom navigation, each fragment is a tablayout hosting 2 more child fragment, child fra

Babish 0 Nov 21, 2021
Cryptac is a mobile application that allows you to track the main important information about your favorite cryptos

Cryptac is a mobile application that allows you to track the main important information about your favorite cryptos.

null 1 Jan 21, 2022
Smart-flight - This app was created to learn and practice Kotlin language

Smart Flight This app was created to learn and practice Kotlin language. Works o

Kamil 1 Feb 9, 2022
Android practice shared ViewModel

Cupcake app This app contains an order flow for cupcakes with options for quantity, flavor, and pickup date. The order details get displayed on an ord

Gabriela Fernanda Soto Ramirez 0 Dec 13, 2021
Android Practice (1sem)

Lab6) 1.Залил 3 простых экрана заставка регистрация авторизация профиль Lab7) Изменил в прошлых экранах некоторые поля EditText с квадратного на кругл

Daniel 0 Nov 30, 2022