Concerning validation of an Android application, are there any points for writing lines of codes to be simply testable (both manual and automatic tests) ?
In my opinion, testing small applications is not a top priority (since they suppose to be implemented fast and quickly and most of the time they serve a small purpose) and you can be skeptical with that since not writing test can save a bit of time. therefore no need to write the code in a way that is testable too.
But remember a few things:
Writing a testable code is a skill that an intermediate developer must have.
A testable code will lead to a maintainable code and that is very important for applications that have a future (almost all of them)
adding features is a lot easier when you have tests on.
Building a team and even passing the code to another person to maintain/add new features is a lot easier with a testable app.
As far as I know, in android testable code means architected code and architecture is compulsory for almost all applications.
Testable codes need to be following coding standards like SOLID Principles
Maintain code in layers, such as separate classes for Api calls and make separate classes for views that you are using at multiple places in Application
Don't write too much code in activities, and don't make functions too long that you have to deep search for piece of code after some time.
Try to write comments frequently, so that some one can understand your code easily
thus try to learn how to write testable and do your best to write test. It will pay off before you know it
Update
to run your test automatically you can use a CI server.
there are lots of option on how to create and configure one. but there are plug and play options as well.
but for further details you can read official Android Developer Doc
hope I answered your question
The following link dirrects us to Test Driven Development:
https://developer.android.com/training/testing/fundamentals
Related
i am trying to make a project that is designed for a business and a customer where the business will be on the desktop side and the customer will be on the android side.
i was wondering since both the platforms will have unique UI(tabs/services/actions... etc.) that serves their needs:
should i use Kotlin multiplatform and use as much shared code as possible or build a standalone app that works separately on each platform and then share information by servers?
are there even other ways to accomplish my goal?
so far here are the most important pros and cons of multiplatform:
+reduce time consumed
+ability to share code which reduce bugs and possible errors.
still in alpha version (experimental) which means not enough libraries in support .
to be honest the only thing that is stopping me from choosing multiplatform is the "experimental " warning sign and if i chose to make desktop app alone might as well make android/IOS app altogether( since the sharing code ability between android and IOS is very much reliable) and in that way i would have gained an extra platform for my phone app in return for the added time of development
i really need an answer from any experienced Kotlin developer and thank you in advance :)
What the KMP thought for is sharing business logic between platforms.
If you have different business logic(business/customer sides) not sure how much you’ll be able to share, but the least you can do is data objects: you can share same objects between business/client/server to make sure your json parsing is stable and doesn’t require changes in many places.
You’ll be able to share a lot of stuff if you choose to share android business logic with iOS, but note that there’re some pitfalls you need to learn, so I’d say you’ll spend 2x time for two platforms in first 1-3 month (same time as if you would do for two separate apps), and then your’ll be able to make two apps with average speed of 1.5x time.
Don’t forget that all UI part will take same time as for a separate app, so it won’t be “free”
Still if your project is big enough, it should pay off.
What’s about KMP being experimental: as for me it’s already stable enough and I’m using it in my current project for sharing code between ios/android/server.
It’s in active development phase so most of problems you face will be fixed fast, or you’ll get a workaround on the youtrack
For the JVM part you almost loose nothing: you had to use Native frameworks but if you need to using jvm dependencies in the shared module, you had to provide alternative code for an each other platform(ios, etc) using expect/actual
It has some limitations for iOS platform. The main one, I think, is that you had to work with a specific memory model: you can’t modify objects from different threads, but if you choose your architecture wisely it won’t be a big problem.
I think your decision should depend on how much logic code you need to share between different platforms, and if there's a lot - KMP is a good solution.
Recently I’ve been rethinking my android architecture project, trying to adapt it to a more “clean architecture”, specifically, the kind of design suggested by “Uncle Bob”.
Which it involves several layers of abstractions, a nice isolation of responsibilities and a very strong dependency inversion achieved by dependency injection; which, ultimately, leads to a very decoupled-portable system. A perfect candidate to be tested by unit testing and integration testing.
In my android implementation I’ve ended up having three different modules or layers:
-domain: entities, interactors, presenters (pure java module)
-data: (acts as a repository to supply the data to the domain) (android library module)
-presentation: ui related stuff, fragments, activities, views, etc (android application module)
So, I’m trying to figure out what would be the best approach on the iOS ecosystem.
I’ve tried creating a project with multiple targets to achieve the same solution:
-domain: command line target (which seems very weird but I think is the most pure swift target available)
-data: cocoa touch framework
-presentation: cocoa touch framework
With this approach I can use these targets in the way I did with android modules. But the first caveat I’ve found it is that I need to add manually every new file to the dependent target.
But my knowledge is very limited in projects with multiple targets. I mean I’ve never created an iOS application with multiple targets. So I don’t know even if the solution would be use a framework (cocoa touch/cocoa) as a target instead of a command line module for the domain layer.
Any thought would be really appreciate.
Thanks!
Uncle Bob's Clean Architecture absolutely applies to iOS, Swift, and Obj-C. Architecture is language agnostic. Uncle Bob himself codes mostly in Java but in his talks he rarely mentions Java. All his slides do not even show any code. It is an architecture meant to be applied to any project.
Why am I so sure? Because I've studied MVC, MVVM, ReactiveCocoa, and Clean Architecture for 2 years. I like Clean Architecture the best, by far. I tested it by converting 7 Apple sample projects to using the Clean Architecture. I've used this approach exclusively for over a year. It works out better every time.
Some of the benefits are:
Find and fix bugs faster and easier.
Extract business logic from view controllers into interactors.
Extract presentation logic from view controllers into presenters.
Change existing behaviors with confidence with fast and maintainable unit tests.
Write shorter methods with single responsibility.
Decouple class dependencies with clear established boundaries.
We also added a router component so we can use multiple storyboards. No more conflicts.
Writing unit tests is greatly simplified too because I only need to test the methods at the boundaries. I don't need to test private methods. On top of that, I didn't even need any mocking framework because writing your own mocks and stubs becomes trivial.
I've written my experience for my last 2 years studying iOS architecture at Clean Swift I also put together some Xcode templates to generate all the Clean Architecture components to save a ton of time.
UPDATE - To answer #Víctor Albertos's question about dependency injection in the comment below.
This is a really great question and demands a long detailed answer.
Always keep the VIP cycle in mind. In this case, the doSomethingOnLoad() method is not a boundary method. Rather, it is an internal method invoked only within CreateOrderViewController. In unit testing, we test a unit's expected behavior. We give inputs, observe outputs, then compare the outputs with our expectations.
Yes, I could have made doSomethingOnLoad() a private method. But I chose not to. One of the goals of Swift is to make it easy for developers to write code. All the boundary methods are already listed in the input and output protocols. There is really no need to litter the class with extraneous private modifiers.
Now, we do need to test this behavior of "The CreateOrderViewController should do something on load with this request data" somehow, right? How do we test this if we can't invoke doSomethingOnLoad() because it is a private method? You call viewDidLoad(). The viewDidLoad() method is a boundary method. Which boundary? The boundary between the user and view controller! The user did something to the device to make it load another screen. So how do we invoke viewDidLoad() then? You do it like this:
let bundle = NSBundle(forClass: self.dynamicType)
let storyboard = UIStoryboard(name: "Main", bundle: bundle)
let createOrderViewController = storyboard.instantiateViewControllerWithIdentifier("CreateOrderViewController") as! CreateOrderViewController
let view = createOrderViewController.view
Simply calling the createOrderViewController.view property will cause viewDidLoad() to be invoked. I learned this trick a long time ago from someone. But Natasha The Robot also recently mentioned it too.
When we decide what to test, it is very important to only test the boundary methods. If we test every method of a class, the tests become extremely fragile. Every change we make to the code will break many, many tests. A lot of people give up because of this.
Or, think about it this way. When you ask how to mock CreateOrderRequest, first ask if doSomethingOnLoad() is a boundary method that you should write test for. If not, what is? The boundary method is actually viewDidLoad() in this case. The input is "when this view loads." The output is "call this method with this request object."
This is another benefit of using Clean Swift. All your boundary methods are listed at the top of the file under explicitly named protocols CreateOrderViewControllerInput and CreateOrderViewControllerOutput. You don't need to look elsewhere!
Think about what happens if you were to test doSomethingOnLoad(). You mock the request object, then assert that it equals to your expected request object. You are mocking something and comparing it. It's like assert(1, 1) instead of var a=1; assert(a, 1). What's the point? Too many tests. Too fragile.
Now, there is a time when you do mock CreateOrderRequest. After you've verified the correct CreateOrderRequest can be generated by the view controller component. When you test CreateOrderInteractor's doSomething() boundary method, you then mock CreateOrderRequest using interface dependency injection.
In short, unit testing is not about testing every unit of a class. It is about testing the class as a unit.
It is a mindset shift.
Hope that helps!
I have 3 series of draft posts in Wordpress on different topics:
In-depth look at each of the Clean Swift components
How to break up complex business logic into workers and service objects.
Writing tests in Clean Swift iOS architecture
Which one of these do you want to hear more first? Should I bump up the series on testing?
In my opinion Clean Architecture is a set of ideas, rules, principles... to make a code better.
[Android Clean Architecture]
With this approach I can use these targets in the way I did with android modules.
You are able create a target[About](application target or framework target...) but it depends on your needs
If you read Architecting Android...Reloaded from Fernando Cejas
you might have seen that I used android modules for representing each layer involved in the architecture.
A recurring question in discussions was: Why? The answer is simple… Wrong technical decision
The idea is that is not necessary to use some build components to implement Clean Architecture
I have just been given a task at work to help audit a code base for a mobile app. I am not a mobile app programmer, although I've been a software developer for many years now, but know nothing about mobile apps. I was wondering if there's any tips or tools that I can use for this code audit.
I have seen the replies to this older post for a Java EE application, which can't be applied to my case since they're mostly based on having maven to build the app and in my case they use Gradle. Also these replies are from 2011 and perhaps there are more recent ones I'd really be very grateful to hear about.
In itself, the fact of appointing someone with no experience in the target environment seems like a complete nonsense to me, so I'd question the management here.
I do hope for you that you know at very least the languages these apps are written in: probably Java for Android & Objective-C for iOS (your question didn't mention what technologies your past experience concerned). If not, you're bound to just make remarks about comments, file size, and maybe some about naming conventions, which is of little interest compared to a real audit.
Beyond programming languages, iOS and Android are designed in very different ways, with different conventions & patterns. I actually know very few people who are really good in both environments, and there's a reason for this: these are different worlds, each of which you can easily spend your whole time on to learn APIs, common libraries, design philosophy, work-arounds for common issues, and understand a bit of how the internals work.
I don't know how much time you have to perform this task, but I'd suggest you learn how to code a basic app on the target environment, and learn about the key components.
My approach is generally:
gather some context from the team
get the source
build the app & get a taste of what it's doing (I usually hand-draw a screen flow diagram at this stage, it's useful later when you navigate in the code), also take note of bugs, slow features, non-user-friendly stuff (feedback is important to the team)
go to the source code, examine it's macroscopic layout:
. look at the build scripts to see what external libs it's using
. take note of the general package hierarchy, check that the naming is consistent, that packages are not overloaded with junk
. look generally at the class naming: is it consistent? do class names help figure out what's actually inside
. do some basic stats about file sizes: it's something that can quickly indicate some design flaws
now about the code in itself:
. read it until satisfied that you understand the general way it works (drawing a technical flow diagram helps), I like to start by the app entry-point (generally an activity in Android)
. make sure you spot how what you read achieves what you saw while testing the app
. take note of bad coding habits you spot while reading (naming, comments, it can be anything: there's no limit to how bad the code can be ^^)
. take note of unreadable/overly-complex bits of code (but don't spend days just to understand them)
. if you had noticed slow features in the app, it might be worth looking at those bits of code a little more carefully
. have a good night sleep, then re-read all your notes, and try to extract some high-level remarks about the application design
Now, specifically for Android, here the most common list of things to look for, based on my experience:
components life-cycle handling issues (for components like activities, services, fragments and such): symptoms include device rotation and application switches causing issues
thread handling issues (things done on the UI thread, when they should really run in background)
massive activities / services (many people think that creating activities / fragments / services is all that's required in terms of architecture - it is true only for very simple apps)
I won't enter more into the specifics, because people a lot more intelligent than me wrote books about this. And you have to code apps to really get a grasp of those subjects: a lot of them, so that's what you should start with: code apps yourself, otherwise: 1/ your audit will be irrelevant 2/ the team will spot your lack of skills pretty fast - depending on the aim of this audit, you might have a very hard time facing them...
My apps are mostly GUIs that communicate to a server for most of their information. If anything goes wrong it will usually be in the network call or making a wrong assumption about a JSON object.
Unit Tests are not good for these network-related and i/o related tasks, otherwise, they won't be called unit tests.
SO I am trying to gather the point of Unit Tests in my case. Why would I test if an Android button can click or an EditText can see what I type? I just don't understand the utility of implementing these tedious tests
private void initElements(){
placeButton = (Button) findViewById(R.id.currplace);
placeButton.setText(MainActivity.this.getString(R.string.findingLocation));
placeButton.setEnabled(false);
selectplaceLayout = (LinearLayout)findViewById(R.id.selectplaceLayout);
selectplaceLayout.setVisibility(View.GONE);
splash = (RelativeLayout)findViewById(R.id.splashbg);
infoLayout = (LinearLayout)findViewById(R.id.infoLayout);
}
if this above method passed, which all my activities run in onCreate, then I know the app works. A unit test of this would be a redundant time-consuming thing to create. Time-consuming because I am not familiar with all the methods in the jUnit and Android testing framework.
So, long story short, what's the point? Is there a particular way I should be thinking about these tests? All examples and tutorials I've seen so far only talk about the simplest examples, for the sake of brevity, but I cannot think of any practical uses for unit tests in a predominately client-server app.
What am I expected to discover by accessing the android views that I already know I declared and initialized? I must be thinking about this in a too limited way
so, insight appreciated
There are lots of facets in your question, but to my opinion - you probably don't need unit-tests in your project.
Unit tests really shine when you need lots of business logic to your project. In this case you probably want to divide your application into multiple layers (say, 3-tier architecture) to, among other, add some natural isolation for business-logic layer and cover it with safety net of unit tests.
This safety net covers your ass during refactor of the business layer, and that's one of the main things you what from unit tests (TDD can offer some nice extra side effects though).
However, it's not all unicorns and rainbows and unit-test may cost, and sometimes they cost a lot. Good unit tests are isolated (i.e. deal with small chunks of code). This means that you have to add layers of abstraction in order to put your classes under the test.
This may have positive affect on your system or negative one. Layering makes your system more flexible with cost of increased complexity.
Having that said - the value of the unit-tests is proportional to the amount of abstract business-logic you are going to introduce in your project. You may think of it also this way - if it is overkill to add abstract layers to your architecture - don't add unit-tests - they will only make things more complicated (architecture and build wise).
Based on your description - your typical app tend to be pretty much presentation layer for some external server-side. It does not that much except presenting information on android handset and transforms user actions to commands to server-side where main business logic gets done (controlling).
With this approach most of the code you probably write is related to "how to display this and that" or "how to signal server in this and that case". This sort of code is obviously heavily depend on platform and this mean that if you do want to put it under test you'll have to mock lots and lots of Android specific code\behavior.
Now, Android is somewhat specific platform. It was designed to be both performance optimized and allow developers to start and produce apps quickly. Often this means some amount of "swiss-knife" classes you have use\extend and generally this speeds up writing code, but mocking those classes can become a real hell. Not to mention that you have to have understanding of how platform works under the hood to make those mock useful. In other words overhead from making those test is going to be high.
Another thing that is wrong with testing presentation layers is that they tend to change much more dynamically than business layers. And, of course this mean that you'll have to refactor thee tests which adds even more overhead.
I have to say one thing about various utility/helper classes though. Even if these classes are belong to presentation layer and do depend Android code, but do some rather non-trivial logic and it is easy to mock and write unit tests for them, it might actually be a good idea to do this. However, if you do have lots of such code - this is might be a signal that you haven't designed your architecture/layering well, and need to rethink what you are doing.
In the end to answer your question you have to answer these questions first:
Will it be overdesign to add abstract layer that is separated from the platform to your application (seems like in your case it will)? If yes - do not use unit-tests - they will only slow you down. If no - do use them.
Are you going to refactor a lot? If that's large project with lots of code and thus maintenance - you probably will, so invest in layering and unit-tests (but, at a glance, it does not seem that this is your case). If that is not your case - do not bother with unit-tests and go fast.
Do you need to mock platform a lot to write your unit tests? If yes (seems to be your case) - don't write unit tests - they do not worth the effort.
Hope this will help.
UTesting in Android generally takes relevance when you are using some layering with a good architecture. Nowadays the most popular is Clean Arch, which is all about maintainability and testability. Every part of the architecture has exactly one purpose. We just need to specify it and check that it actually does its job every time.
When testing use cases we should test that use case calls correct methods in repositories or executes other use cases. We should also test that use case returns proper callback.
When testing repositories, you should arrange DAOs – make them return or receive some dummy data, and check that repository is handling the data in a proper way.
When testing mappers (converters), specify input to the mapper, and exact output you expect from the mapper, then assert they are equal. Do the same for services, parsers etc.
Leaving the architecture besides any good modular and decoupled design will contain business logic in functions and classes, and if those follow single responsibility principle (they should), then likely should be tested.
Think about testing before and during coding. That way you can write testable and decoupled code. Use your tests as class specification, and if possible write them before the code.
Examples and expanded info: https://five.agency/android-architecture-part-5-test-clean-architecture/
from Android.Docs
For testing Android apps, you typically create these types of automated unit tests:
Local tests: Unit tests that run on your local machine only. These tests are compiled to run locally on the Java Virtual Machine (JVM) to minimize execution time. Use this approach to run unit tests that have no dependencies on the Android framework or have dependencies that can be filled by using mock objects.
Instrumented tests: Unit tests that run on an Android device or emulator. These tests have access to instrumentation information, such as the Context for the app under test. Use this approach to run unit tests that have Android dependencies which cannot be easily filled by using mock objects.
Note: Unit tests are not suitable for testing complex UI interaction events. Instead, you should use the UI testing frameworks, as described in Automating UI Tests.
I want to implement MVC in my Android application for reasons I have heard but not realized. Can anyone lead me to implement MVC in my application? Kindly mention the benefits for using the same.
Thanks
The key benefit of MVC (and its variations) in general and not only for Android is separation of concerns. This means you keep business logic isolated in the Model instead of mingled with the presentation logic. In turn the Model becomes easier to unit test, modify, and reuse (when reuse is a concern at least).
I'm not sure if there is much sense in testing the View or Controller parts of MVC. The View for one thing is supposed to be as much 'dumb' as possible, to the point of lacking even presentation logic.
MVC apparently has trouble telling where the presentation logic belongs to -- this seems to be the reason why MVP has been created, so all this logic goes to the Presenter. So by using MVP instead of MVC you would also have the benefit of easily testable presentation logic.
MVC also allows (in theory at least) to change the user interface adopted by the application, though I'm not sure how this applies to Android (maybe for games?).
Needless to say, Android apps DO NOT implement MVC by design. Otherwise those benefits would be available to Android apps by design, which is not true.
It's already implemented as per this post here: MVC pattern on Android
For one thing, it allows you to plug in a different algorithms or data store/source into your app with a single line of code. So in my sample Android app, I can switch from DES, to AES to TDES encryption in one line of code. It allows you to port your algorithm to another app with a completely different user interface and architecture. So in .NET I can write a Windows Form app and then port it to a Web Form app without re writing the core algorithm code. If you are looking for an example in Android I have a complete example here. If you can read C# code I have an example here.
Have fun.
JAL
Java has very powerful features behind it. The word MVC means at the bottom line, basically, componentization. Components are a very important definition in a OOP language like Java, and even more important to languages that implement memory allocation and handling like Java with the GC (Garbage Collector).
There's lots of GC algorithms & types implemented out there, each JVM has it's own number of sets, Oracle has it's own, IBM, Apache's OpenJDK, and so on and on. But the concept is almost every time the same: reference counting. Let's picture an example where you have an object A, that define a property of type B, and this class B has also a property to another class called C, and they are all in the same processing scope (e.g. a method). Analysing this example, the runtime (JVM) could only release "B" after "C" is out of scope (out scoped), and also "A" could not be liberated because of "B" being used by the same scope. Putting this in perspective, the scope modifiers, methods, classes, static methods and classes, final declarations, everything needs to be carefuly chosen.
Summing all together, that means not only you get a more well organised code using patterns like MVC, but also more performance in the JVM runtime, because depending on the size of your program, your GC pool can really be a bottom-neck, and fine grained java code, with methods with a just few lines divided by a few number of classes, will always perform better. Huge classes, with just a few methods with a lot of lines of code within, tend to perform poorly.
... and that's the beauty of things. MVC not only gives a more well organised code, but also, more performance. Hope it helps!