Before I begin, I do have five book recommendations on how to modelling the domain and last two for unit testing:
- Practical Object Oriented Design in Ruby by Sandi Metz
- Domain Driven Design Quickly by Abel Avram and with Floyd Marinescu as managing editor.
- Growing Object Oriented Code Guided by Test by by Freeman and Price
- Art of Unit testing by Roy Osherove
- Working effectively with legacy code by Michael Feathers
Below is the rough requirement for the app to be used:
Should track fill-ups, mileage, and fuel consumption.
Just enter fuel per unit price, amount and odometer while you are at the pump.
The application will show you distance and average fuel consumption.
- Gradle as build tool
- Android Studio as IDE
- Java as programming language
- CircleCI as CI
Code Quality Measure
The idea of the fuel logger is to create a offline Android app using java where the user can:
- Can view metrics like Average consumption, Driving cost and Total Kms, Total amount costs, Total Fuel consumption upon opening application
- Can add a fuel log with mandatory fields like date, current odometer, fuel unit price, amount filling
- ̶C̶a̶n̶ ̶e̶d̶i̶t̶/̶d̶e̶l̶e̶t̶e̶ ̶a̶n̶y̶ ̶e̶n̶t̶r̶y̶ (not covering as part of this)
- Can see full log entries.
I did tests on the FreeBSD operating systems. You can download the project:
Now, you can run unit test
Above command executes (shared) instrumented tests + unit tests on JVM.
Additionally, you can run UI (or Instrumented) test on device or emulator
Above command executes (non-shared + shared) instrumented tests tests on Device/Emulator.
You can see more details of the implementation by looking at the project’s git homepage.
Intro to Instrumented test:
Identification of Dependent and How to inject dependency
First things first, as you start writing the unit testing for UI, question that will raise in our mind is how to mock the dependency of viewmodel within Fragments.
That being said, To get to into this level all your business logic should have been moved to viewmodel, your fragments or activity should be dumb enough to just bind the data or manipulate UI attributes (example visibility, enabled) based on data.
Identified domain models are “FuelLogs”, “FuelLog”, “FuelDao”:
FuelLogs Composite of FuelLog, responsible for calculating stats on collection of FuelLog entities like average consumption, total distance, total fuel consumption, total amount since inception.
FuelLog An “Entity Object” having timestamp as identity and other attributes that makes sense to problem statement.
FuelDao The Data Access Object (DAO) to isolate the application/business layer from the persistence layer (usually a relational database, but it could be any other persistence mechanism) using an abstract API.
Let’s examine which of these are a more natural way of expressing our intent.
FuelLogs has a List of FuelLog objects or,
FuelLogs is a List of FuelLog objects.
In real world, driver would be having a book, having all entries entered in row wise. Similarly FuelLogs is equivalent to book, so we can conclude that FuelLogs has a list of FuelLog objects hence composite relation.
Also FuelLogs has one to many relationship with FuelLog.
- Passing Event Triggered from View to ViewModel
- Passing Event Triggered from background Operation to View
- Passing Event from Fragment to Activity or Vice Versa
are performed view ObservableList or MutableLiveData which are observable pattern.
And in the fragment/activity, need to observe for the event as below
Few extension I would like to see is support for multiple vehicle, better way of calculation stats without loading full data, supporting multiple metrics, ability to skip the entry for stats computation.
This project is only used for studies using android developed by layman in the subject, and perhaps not one of the best implementations, techniques, and uses of the language.
I am always open to feedback, so free feel to let me know what you think in the comments below.