Mark M. | has entered the room |
Mar 14 | 3:55 PM |
Mark M. | turned on guest access |
Mar 14 | 4:10 PM |
Kai H. | has entered the room |
Mark M. |
hello, Kai!
|
Mark M. |
how can I help you today?
|
Kai H. |
Hello, Mark
|
Kai H. |
If I have an app that depends on a (in house) library, how would I best integrate that library so the app stays testable?
|
Mark M. |
I don't see how it being an in-house library matters (compared to a third-party library or code that is part of the app itself)
|
Mar 14 | 4:15 PM |
Mark M. |
in other words, where the code comes from itself does not usually impact testability
|
Mark M. |
so, use dependency inversion and similar techniques for keeping your code loosely coupled, as you would with stuff that is purely within the app's own modules
|
Mark M. |
so you can use mocks and spies in tests as needed
|
Kai H. |
It can become complicated because of the integration. Right now it resides in a folder outside the app folder and is referenced via '../some-library'
|
Mark M. |
you might want to switch to publishing it to a private Maven repo, so there is proper versioning
|
Mark M. |
that's not strictly related to testability, but rather is a matter of overall long-term maintainability
|
Mark M. |
so, for example, a firm that I am helping has an Android app for mobile devices, plus a family of apps that run on an IoT device
|
Mark M. |
we have a library with some code that is shared between the mobile app and the IoT apps
|
Mark M. |
that library is published to a private Maven repo, so each consumer of that library can depend on a specific version
|
Mark M. |
that way, library updates don't immediately affect all projects -- each project can upgrade to the new version when appropriate
|
Mark M. |
in our case, that private Maven repo is on Amazon S3, as the development team is distributed, but there are many possible options for where the repo would reside
|
Kai H. |
That also means that, for each change in the library, you need to push it. Which can be quite cumbersome if the library grows and changes with an app. And the library would really need to be "independent".
|
Mar 14 | 4:20 PM |
Mark M. |
IMHO, the library should be independent
|
Mark M. |
with regards to the "cumbersome" part, IMHO, not really
|
Kai H. |
I agree, but it isn't. It's a bit of a mix of different classes and methods that "kinda belong into a library", with some actually being shared while others are only there for one single app, but need to be in it because the functionaliy/class they belong to is already in there.
|
Kai H. |
Isn't independent, I mean.
|
Mark M. |
perhaps the library needs to be refactored, then
|
Kai H. |
When doing a new feature, I go "this part belongs in the app" and "this part belongs in the library, because this and that class needs to be modified for it" and then I fiddle around ind the app and the library.
|
Mark M. |
that does not imply that you should avoid versioning the library
|
Mark M. |
if anything, it increases the need for such versioning
|
Kai H. |
Yes it does.
|
Mark M. |
now, if you would prefer to handle that via something like git submodules, you're welcome to do so (personally, I much prefer the Maven route)
|
Mar 14 | 4:25 PM |
Kai H. |
I guess git submodules would work, as that also works with gitlab continuous integration as far as I know.
|
Mark M. |
I presume there is a recipe for that, but I can't say for certain
|
Kai H. |
The Maven route is hard, because of the quite hard dependency of library and app.
|
Kai H. |
But yea, that would be the proper way to do it ;-)
|
Mark M. |
¯\_(ツ)_/¯ I don't agree, but there may be aspects of your project that might cause me to change my mind
|
Mark M. |
so long as you have a reasonable system of ensuring that changes to the library that are needed by App A do not immediately break the builds for Apps B through Z, you should be in reasonable shape
|
Kai H. |
The reasonable system is opening the other apps and manually testing if they still work.
|
Mark M. |
you have a generous definition of "reasonable" :-)
|
Kai H. |
And finding out that they don't and then trying to find a solution that will make both apps work.
|
Kai H. |
Well, it's not my definition of reasonable, but the companys.
|
Kai H. |
The alternative would be refactoring the library and the app and writing tests for both of them.
|
Mar 14 | 4:30 PM |
Kai H. |
Which would probably take like a year or more.
|
Mark M. |
OTOH, tech debt does not usually go away on its own, except in fairly drastic forms (e.g., dumping the entire app, company shuts down, zombie invasion)
|
Mark M. |
so long as everyone, including management, recognizes the pileup of tech debt, and you wish to continue piling it up, that's your call
|
Mark M. |
and there may be very legitimate reasons for doing that
|
Kai H. |
I guess the reasons are that "the app works and will probably continue to work" and that it's more important to get the new features in.
|
Mark M. |
and so long as everybody is making that decision with eyes wide open, that's fine... but, it will make seemingly innocuous questions like "how do we think about integrating this library with regards to testability" more challenging to answer, as the recommended solutions might not be applicable
|
Mar 14 | 4:35 PM |
Kai H. |
I guess as I get faster in implementing new features, I might get some time to address the tech debt.
|
Mark M. |
that's a typical approach: budget X% of time towards chipping away at the tech debt
|
Mark M. |
unfortunately, some aspects of the tech debt might not be amenable to that sort of incremental approach
|
Mark M. |
but, it's better than nothing
|
Kai H. |
I guess so
|
Kai H. |
Do many companies use continuous integration with Android? I just set it up in Gitlab and am playing around with it
|
Mark M. |
CI is pretty popular, whether in-house (e.g., Jenkins) or external (e.g., Circle CI, GitHub, GitLab)
|
Mark M. |
IMHO, its utility depends a lot on your testing -- if you don't have many tests, then IMHO the value of CI falls off
|
Mar 14 | 4:40 PM |
Kai H. |
I see. I currently have no tests, so yea :D
|
Mark M. |
but, you can also use CI for enforcing Lint rules or for just ensuring that nobody merges a PR if the code won't compile
|
Mark M. |
so, for example, the mobile app project is using ktlint to enforce Kotlin code style, so CI yells at us if we failed to format things properly
|
Kai H. |
I see.
|
Mar 14 | 4:45 PM |
Kai H. |
So tests and linting are the most important values of testing?
|
Mark M. |
using Lint is somewhat independent of testing
|
Kai H. |
Sorry, I meant CI, not testing
|
Mark M. |
ah, OK
|
Mark M. |
well, one could argue that "don't break the build" is the baseline value for CI
|
Mark M. |
if your CI is integrated into your version control process (e.g., GitHub PRs can't be merged without a clean CI build), then "don't break the build" is much easier to avoid
|
Kai H. |
In my case that would be "don't break the repo", as the build is pretty much on my machine.
|
Kai H. |
Or rather "don't forget to add all files into the repo before committing"
|
Mark M. |
yeah, I'm using a more historical base for that expression, I suppose
|
Kai H. |
What we want to achieve is to also have signed .apk and .aab at the end of the CI process.
|
Mark M. |
regardless, you don't want to commit changes to the repo that prevent others from building once they pull down those changes
|
Mark M. |
that's possible
|
Kai H. |
So a build can be done without a certain developer, for example.
|
Mark M. |
yeah, well, that's a double-edged sword, if anyone can publish an app update
|
Kai H. |
Have you ever had the need to produce an .aab with a special name?
|
Kai H. |
I guess so.
|
Mark M. |
I avoid app bundles like the plague, so I haven't deal with that particular issue
|
Kai H. |
Ok
|
Kai H. |
Why do you avoid them?
|
Mark M. |
I do not want other parties signing my apps, and with app bundles, that's unavoidable
|
Kai H. |
Btw, right now only one person can publish an an app update, which isn't ideal either. That is a bus factor of 0.
|
Mar 14 | 4:50 PM |
Kai H. |
Ah, yes.
|
Mar 14 | 4:50 PM |
Mark M. |
agreed, and in a smaller firm there may not be many shades of gray between "one magic developer who can publish" and "everyone can publish"
|
Mark M. |
and, yes, having more than one person who can publish is important, as right now the bus has "COVID-19" written on the side
|
Kai H. |
And "anyone can publish" might be better than "no one can publish at all"
|
Mark M. |
oh, definitely
|
Kai H. |
We have a lot of zeroes as bus factor at my company right now, but they are starting efforts to change that a little.
|
Kai H. |
Like code reviews
|
Kai H. |
Even though it's a bit half hearted, as there is always the fear of too much productivity getting lost
|
Kai H. |
So code reviews are pretty much "does it adhere to the style guidlines and do you see any obvious errors when reading through it" right now.
|
Mark M. |
reviewing code is a skill, like many other things, and not everyone has developed that skill
|
Mark M. |
so, superficial code reviews is an unfortunate fact of life on many projects
|
Mark M. |
however, a secondary benefit of code reviews is at least exposing more developers to more of the code, which can have benefits for your bus factor scenario
|
Mar 14 | 4:55 PM |
Kai H. |
Exactly, but only if they should actually understand what they are reading
|
Mar 14 | 5:00 PM |
Mark M. |
that's a wrap for today's chat
|
Mark M. |
as usual, the transcript will appear on https://commonsware.com/office-hours/ shortly
|
Mark M. |
the next chat is Tuesday at 7:30pm US Eastern
|
Kai H. |
Have a good time
|
Mark M. |
have a pleasant day, and stay healthy!
|
Kai H. |
same
|
Kai H. | has left the room |
Mark M. | turned off guest access |