DONN FELKER

Lessons Learned From the Software Industry

  • Home
  • About
  • Development Training
  • Fragmented Podcast
  • Learn to Work for Yourself
  • Contact

Connect

  • GitHub
  • Google+
  • Instagram
  • LinkedIn
  • RSS
  • Twitter

Powered by Genesis

TDD Your UI Layer – #uitestsmatter

January 24, 2017 by Donn Felker 17 Comments

TDD Your UI Layer

A recent conversation developed on twitter when I posted a link to a Caster.IO lesson where I talk about using TDD to drive your UI development.

The problem?

Some folks feel that you cannot TDD your UI layer with a functional testing framework like Espresso.

I disagree.

Why? Well, before I dive into details, I thinks it’s only pertinent to re-establish what TDD is.

What is TDD?

TDD by definition is: Test Driven Development. TDD is a software development process.

Key word: process.

The process of TDD is comprised of 5 steps:

  1. Add a test – each new feature, update, fix, etc starts with writing a test to cover that new code/change/etc.
  2. Run all tests and see if the new tests fails (typically to save time, I’ll run the new test in isolation to speed things up, then loop back later to run all of them to check for regressions).
  3. Write the code (this is what you orignally needed/wanted to do anyway – implement a feature/etc).
  4. Run the test(s) – Again, typically I’ll run my single new test in isolate to speed up this process a bit. If it passes, I run all the tests to see if I broke anything.
  5. Refactor – After all tests are passing, you now have a safety net to catch you in case you make a mistake. At this time you can now start refactoring to change the desired implementation of the code.

 

Then … repeat the steps for each new feature/update/fix/etc. You may need to do this many times over. One test for the “happy path” (when everything works as you hope/expect it would), one for all the edge cases, one for null value paths, one for catastrophic failures, etc etc. You usually end up with may tests covering all the different expected (and unexpected outcomes) for that given code path.

So, how do you TDD your UI Layer?

Let us keep the full TDD process in mind when walking through this example …

This means writing your test first, even before particular UI elements exist. In this case I’ll do it with Espresso, the defacto Android UI testing framework along with jUnit as the driver.

Step 1: Create the Test

I’ll create a test like so:

As you can see, the buttonx id does not exist yet (this is why it is red). At this point I’d go implement the button and we’d then see something like this:

The id, buttonx, is now found (it changed colors and we can navigate to its definition now). How I implemented it is not important as it’s an implementation detail and we’re worried about the TDD process here. I can compile successfully. Ok, now I can move onto step 2 of the TDD process:

Step 2: Run The Test
I run the test and I expect it to fail because the text “Hello from buttonx” does not exist. If it does not fail (meaning that it passes) I have a problem and I need to dig into that. Let’s assume it fails and at that point I’m ready for Step 3 …

Step 3: Write The Code
At this point I’m able to write the code that is needed in order to get this code to pass (whatever that may be – adding a click listener to buttonx and having it output “Hello from buttonx” somewhere on the screen). Then move onto step 4 …

Step 4: Run the test(s)
We run the test(s) to make sure that the tests passes and to make sure that other tests still pass. This is integral to the TDD process. You will want to run all the tests (usually at least all the tests that interact with this component/screen/etc) to catch any regressions that may popup because of this new code you have added. After everything is green (passing) I’ll move onto Step 5 …

Step 5: Refactor
This is where I’d come in and clean up the code to make it more proper. Maybe make things more private, final, or extract methods, etc. Maybe I find an area of code that I can improve the design on/etc. If thats the case; for example maybe I’ve refactored some logic into a new class I’d introduce a new TDD test process for a new refactoring/etc. When would that happen or why? Maybe I see that I’ve duplicated code in a few places and I can extract this into another class. At that point I’d probably want some tests around that class so I’d go through the TDD process with that class.

I’ve followed TDD to implement a feature/change a chunk of code/fix a bug/etc that is on the UI using Espresso.

Most importantly – I used TDD a process to implment it.

 

Arugments Against TDD in this Context

Sure, this example is fairly contrived and it’s super simple, and it’s that way for a reason – I’m trying to demonstrate a point. TDD is a software development process. Alas, there are some folks who feel that TDD represents something different. Let’s chat about those opositional points of view.

TDD should not use a UI Testing Framework

I completely disagree with this because TDD is a software development process. The UI is part of the software and if you want to develop it using TDD then you can. Step 1 states that we need to write a test. Does it matter what framework we use to write it in? No. IMO, any test is better than no test (but thats another topic for another day). Looking at the Wikipedia entry for TDD I found the following under the definition of Part 1 – Add a test:

The developer […] can write the test in whatever testing framework is appropriate to the software environment.

We’re writing the UI, therefore Espresso is an appropriate testeing framework to use as it is a UI testing framework. Right tool. Right job.

The reason most folks oppose following TDD with UI testing is because it’s slow, which brings me to the next item …

When doing TDD, all tests should be fast

I totally can relate to this one. I’ve been part of teams that have HUGE Espresso/UI test suites and they can take hours upon hours to complete. Running the full test suite can be a pain and it’s simply not feasible. In this case I rely on CI to run full test suite. During development though, for steps 2 and 4 (where we run the tests) I’ll run a small subset of tests. Usually the test(s) that I’m writing or the small suite of tests in that test file/package that is pertinent. This allows me to remain nimble. Typically this is anywhere from one to twenty tests (give or take).

I agree, this is slow compared to JVM unit tests that can run at hundreds (if not thousands) per second. However, I’m doing UI development here so given the state that UI testing is in (for Android) we’re unfortunately stuck with some slower tests. It is what it is, but the TDD process can still be used.

Doing TDD on the UI is an Anti-Pattern

I’ve seen this mentioned a few times, and it’s mainly because having slow running tests is an anti-pattern … but as I stated above, that’s the situation were in. How do you get around that though? Extract your logic out into something like the MVP pattern. You can then test the majority of your code in fast jvm tests. You’ll still need a thin layer of UI tests to make sure your UI works as you (and your customers) expect it to.

I say this because you need to verify what your customer is going to see … because …

If your apps UI fails/crashes/doesnt do what it is supposed and it does not do what the customer wants, they’ll think its garbage. It doesnt matter if your app is beautifully architected with fancy patterns and so forth. If the UI doesnt work and do its job as expected, the customer is unhappy and will most likely not use your app. At that point all your work is moot.

How many times have you used an app and initially it looked great, but then when you started using it … well … it just felt like things were wrong. What was your reaction then? Most likely a negative one. You probably didnt use the app or even uninstalled it right away. I definitely don’t want that and I’m sure you don’t either. #uitestsmatter

What I’m trying to say is, UI tests are extremely useful, even if its a thin layer and that layer can be test driven thorugh TDD.

… but, I heard TDD is Dead

This has been going around for the last few years. I’ve been through the TDD inception/rediscovery in 2003 by Kent Beck and seen it rise and fall and rise again and so forth. It’s cyclical. One moment it’s in favor, the next its not. The hard part is … TDD is hard. With some languages TDD is seen as a way to help improve the overall design of the app (which is usually the case with statically typed languages like Java). Dynamic languages have some other benefits when it comes to testing and mocking that statics do not (but they have their own downfalls too, which I wont get into here).

Back in 2014, Martin Fowler, Kent Beck and DHH hosted a series of online videos where they discussed if TDD was dead or not. You can find them here – Is TDD Dead? I’ll let you decide if TDD is dead. Each person in the group had great points and at times I agreed separately with each one of them on different topics.

I’m not here to argue if TDD is dead. I’ll leave that up to you to determine.

However, I do hope that this article does prove the point that TDD can be possible with UI development.

 

So … Is TDD with UI Development Possible?

Yes.

Remember, TDD is a software development process that can be applied anywhere in software.

As always, please leave comments below. Thank you for reading. 🙂

Filed Under: Development

Automating Screenshots: Simplifying Internationalization on Android

February 11, 2016 by Donn Felker 5 Comments

I’ve worked on some fairly large internationalized apps (50MM+ installs on each app) and on each app I’ve always had a problem with internationalization. It presents its own set of challenges. If you have not internationalized an app before you’ll quickly realize that your app design may not fit various locales – especially when text widgets are horizontally adjacent to each other. The text will eventually overlap or just look wonky and this can create odd UI bugs. You’ll find this out during testing, or as in my experience, when someone reports an odd text widget is overlapping another part of the UI. Finding these issues usually resulted in having your QA team go through each screen in the app to visually inspect the app for each locale. An optimal solution would be to visualize all of the different screens in the different locales so that it would be easy to inspect. Unfortunately that, solution did not exist …

While there is no silver bullet for this situation, there is a new tool that can help with this process (which also has ancillary uses as well).

I recently had the honor to work with the Fabric team – the same trusted team who brought us the Crashlytics tool that we all rely on. They were looking for some feedback on a new open source tool called screengrab. I got to try it out, and after some setup, I had an “Aha!” moment that made me want the tool immediately. It’s a tool that any pragmatic Android developer should evaluate as a possible candidate for their Android development toolbox – especially if your app is internationalized.

Let me explain why …

What is screengrab and why should I care?

Put simply, it is a command line tool that helps you take screenshots of your application at desired execution points in your functional android tests (Espresso) … in any locale.

running-screengrab

 

 

A screenshot tool? Really? Any Locale? Why Should I care about that?

Therein lies the magic …

One thing you notice during the localization effort is that during design and development strings that fit in one language (English for me) do not necessarily translate well to other languages. Meaning that a five-letter word in English may translate to a twenty letter word in another language.

This is problematic when you are dealing with horizontal space. Longer text entries will overflow onto other widgets and you’ll have a problem.

As stated above, you often don’t realize it until it’s too late because manually testing your application on various locales is difficult and extremely time intensive.

How Does screengrab Help?

The screengrab tool will help automate the process of visually inspecting the various locale output of your app. You can configure screengrab to load up different locales, run all the UI tests and take screenshots during the execution of the test on various devices and configurations at the same time … and then ….

Screengrab will output all of the screenshot files for each locale for you. You can then use those files to quickly visually inspect if there are in fact visual problems with your application and locales. 

Simply scroll through the files and check to see if anything is broken.

This can result in huge time savings when you make a feature change, add a new screen, etc.

How Do I Install It and Use it?

As usual, the Fabric team is making this as easy as possible. It’s one file to setup after the installation that anyone on your team can run once it’s checked into github (setup once, setup everyone forever).

Once installed you can start taking screenshots in your tests with the following Screengrab.screenshot(“screenshot_name”);

@Test
public void testTakeScreenshot() {
    Screengrab.screenshot("before_button_click");

    onView(withId(R.id.fab)).perform(click());

    Screengrab.screenshot("after_button_click");
}

The above code is a jUnit 4 test that allows you to take a screenshot before an action with a the tag “before_button_click”. This tag will show up on the screenshot so you can trace the execution of your test and screenshots.

Then we click on a button, then take another screenshot.

Almost done …

Configuring Various Locales

Now, lets assume you have mulitpe locales and you want to test those various locales and see the screenshot results. To do that you’ll need to provide some configuration values in the screengrabfile.

The screengrabfile was generated when you installed screengrab. You’ll want to add the following information to the screengrab file:

# locales to test
locales ['en-US', 'it-IT']

# clear all previously generated screenshots in your local output directory before creating new ones
clear_previous_screenshots true

This configures screengrab to run the US Ensligh locale and the Italian locale.

Now Lets Run It

You’ll need to make sure you’ve built your application so that you have an application APK and the test APK. Build that with the following command:

$> ./gradlew assembleDebug assembleAndroidTest

Now that the application and test app are built you’re ready to kick off screengrab. Execute the following command:

$> screengrab

This will fire off your tests in each locale and you’ll see your device(s) reacting and your console going wild, as this gif showcases:

screengrab-output

(Click for larger)

When screengrab is done your screenshots will be stored in the fastlane/metadata/android/images directory of where you ran the screengrab command.

View The Results

Viola! Open the file to see how everything went. Here’s an example:

screengrab-output

(Click image for larger resolution)

 

What else can I use this for?

The screengrab tool integrates with the Ffastlane toolsuite right out of the box.

It’s fairly new for Android, so if you haven’t heard about it I totally get it. Here’s a quick synopsis – fastlane lets you, as a developer or release manager, automate your deployment pipeline. From integrating with continuous integration taking screenshots, to placing them into device frames (currently iOS only though, hopefully Android soon! Hint Hint Fabric team!),  to upload the files to Google Play automatically. Fastlane helps you automate the deployment process of your Android apps. Check out fastlane for more detailed info.

The screengrab tool has a few additional use cases:

  • Design/Product Manager Review
    • Keep your product and design teams up to date with all of the screens in your application on a per build basis.
  • Automate Screenshots for release
  • Automate Screenshot automation for internal dog fooding and review processing with other tools.
  • … and of course, to validate what might have gone wrong during a test.

Does this replace my other screen capture tooling?

No,  screengrab complements the existing toolchain that is out there. If you need/want to use your other solutions, feel free to keep using it. Screengrab is just another tool in your toolbox.

Pragmatic Development Tooling

I’m very pragmatic in my day to day development. When I do internationalize my next app (which I’m actually doing in the next month or two) I will be reaching for screengrab as the tool to help sanity check my work.

Why?

It’s simple. It’s easy. It helps me solve a problem and it gets out of my way. I don’t need to write the tool myself. It just works.

As with anything new, it has a purpose and it now occupies a space in my toolbox. Maybe it will help you save some time too.

Filed Under: Development, Mobile

The Rule of Thirds

February 5, 2016 by Donn Felker 2 Comments

Photo by Aaron Escobar via Creative CommonsPhoto by Aaron Escobar via Creative Commons

I learned one simple thing years ago that helped me more than I think anything else I’ve learned in awhile.

What is it?

You can’t make everyone happy.

 

I’ve tried. It just doesn’t work.

When you do try to make everyone happy you eventually end up feeling defeated and burned out. At the end of the day you’ve wasted part of your life on trying to please people who do not want to be pleased.

I eventually learned to accept what I call the rule of thirds. I’m not the first one to come up with this, but it is very useful so I thought I’d share it here.

The Rule of Thirds

The rule of thirds is a mental system which you can apply to your day to day life to help alleviate the mental load of worrying about making everyone happy.

The rule of thirds is as follows …
When you create something in life (a business, products, a presentation, public speaking, an idea, something at work, etc – it doesn’t matter .. its anything) people are going to react in one of three ways:

  • 1/3 of people are going to be positive about it
  • 1/3 of people are going to be indifferent about it
  • 1/3 of people are going to be negative about it

As soon as you realize that this is the way the world works, the easier things become.

Give a presentation on XYZ Topic at your local MeetUp? Most may like it, some may hate it, and some are indifferent.

You can’t make everyone happy … and that’s ok.

Thats why this world is great. We all have different opinions, emotions and things we enjoy. Everyone is unique.

So the next time someone trolls you online about something you’ve done, just realize what bucket they’re in and move on with your life. Don’t let it disrupt your day.

Filed Under: Business, Health, Marketing, Misc

Why Podcasts Have Become Popular

January 3, 2016 by Donn Felker 1 Comment

Photo on 5-7-15 at 6.17 PM #3

The way we consume video content is changing.

Netflix. Hulu. You Tube. HBO Now. Amazon Instant Video. DVR.

The way we communicate is changing.

Email (always is popular). SMS/Text. WhatsApp. Facebook Messenger. Voxer. Telegram.

The way we physically get around is changing.

Uber. Lyft. Sidecar. Curb.

The way we listen to audio is changing.

iTunes. Google Play Music. Spotify. Pandora. Rdio (RIP)

The way we educate is changing.

Kahn Academy. Code.org. Code Academy. MIT/Standford/Etc Free Online Classes.

The way we research things changed about two decades ago.

The Internet. Wikipedia. Blogs.

What do all of things have in common?

They’re all on-demand.

We live in a world where we can now determine when and where we will reply to a text message or email. We get to watch what we want to watch when we want to watch it. We get to usher a cab/ride when we need to go somewhere at any point in the day. We get to listen to the music that we want to listen to when we want to listen to it. We get to learn what we want to learn when we want to learn it.

Many industries are getting disrupted by the on-demand economy.

Radio has been changing for years

Radio is ineffective because it’s live. I can only listen to what is on, right now, pre-programmed by someone who has tastes that are marginally similar to mine.

Don’t like a song?

Too bad. Listen to it.

Don’t like this ad?

Too bad. Listen to it.

Podcasts Are On-Demand Radio

That’s all there is to it. They’re on-demand radio that give you the ability to fast forward, rewind, save for later, etc.

Can’t listen to it now?

No problem. Listen to it later when you have time.

Can’t listen to the whole show?

No problem. Listen to the rest when you have time.

Miss something?

No problem. Hit rewind and listen to it again.

This is one of the reasons why Howard Stern remains a powerhouse on Sirius/XM. Though his show is not a podcast it is consistently replayed all day and through his off time during the weeekends/etc. If fans miss a show, they can tune in and catch it any time of the day. Without this, his show would be far less popular, IMO. Unfortunately not everyone can listen to it at any time they want but this consitent replay exposes his show as an on-demand show. Listeners listen during the day when they have time.

This is exactly why podcasts are becoming popular.

Podcasts are On-Demand Radio.

Download it and listen to it when you have time. Today. Tomorrow. Next week. Whenever.

That is why Podcasts are becoming popular.

If you’re an Android Developer/Mobile Developer you might like my podcast – Fragmented. Its a podcast about Android Development that I host with Kaushik Gopal.

Filed Under: Business, Development, Marketing, Misc, Mobile Tagged With: Android, Productivity

Staying Sane and Productive While Working Remotely

December 30, 2015 by Donn Felker 8 Comments

Here’s some tips I can give you after working remotely for nearly 10 years.
4051398710_8985c07e0e_o
Image by jnyemb via Creative Commons

Read REMOTE by Jason Fried and DHH

Read (I highly advise listening to it on Audible): REMOTE: http://37signals.com/remote

Alot of what I say is regurgitated in the book above. When I listened to the book years ago I thought to myself “Whoa, OMG, these guys think the same way I do … I’m NOT ALONE!!!!” – so I’ve been recommending it for ages.

Stick to a Schedule

Schedule. Schedule. Schedule. Stick to a schedule when starting out. It will save you.

I get up at the same time every day, just like if I had a on-site job. I take a shower, get dressed and wear a collared shirt (think Golf shirt) and pants (usually jeans). I do my hair, and “get ready for work”. This is PURELY MENTAL. It prepares your mind and gets you into the mindset of work. Futhermore, being presentable goes a long way in a video call!

Preparation

I then get the tea/coffee ready, grab some snacks, some water in a water bottle and head off to my “office”. This again, is mental. I grab drinks and snacks so that I do not have to leave the office for awhile.

Distractions are abound in your house, you need to limit your exposure to them.

 

By preparing these small things you are getting yourself into the mindset for work. Let’s be100% honest here, there is no way in hell you can be effective with an interesting movie blaring in the background and working in 2 hour chunks through the day. You need to be in the mental mindset and have a schedule.

Now, work your 6, 8, 10 hours or whatever you deem a work day. Get up and use the restroom, sparingly. When you eat lunch, spend 30 mins to 1 hour. Prepare your lunch before work if at all possible. Again, this is to limit distractions.

Make Time For Exercise

During lunch, fit in a workout in the garage if you can (or go to the gym/fitness group/etc – see below). Health is important. You don’t commute, so pick up some freaking weights or run or row, etc.

Don’t have equipment?

Go for a run. Do Calisthenics, etc.

If you need help here, I can help you – I have tons of fitness programs I do on the road, visiting family, in my garage, all with no equipment. I’m no Hulk, but I’d say I’m “in shape” somewhat, so it must be working.

Eat Healthy

This is key! Eat healthy! Tip: Eat ONE salad per day. I don’t care when. Only requirement: Do not soak it in dressing. I recommend Olive Oil and vinaigrette or some variation. Not ranch or thousand island or any of those heavy variants. Eating one salad a day will do insane things for your health and mindset. Doing this alone will make positive changes in your diet and health.

Understand and Recognize Cabin Fever

Cabin fever is real.

If you live in a city, get out for lunch at least once a week. Go to a taco shop, meet a friend, have a lunch date with your wife/girl[boy]friend/husband/etc.

Get out of the house.

Plan to work out of the house 1-2 days a week.

Time Block Your Tasks

List a couple of tasks that you want to complete that take about 2-4 hours to complete, go to a coffee shop or coworking space and get it done. It will do an insane amount for you mentally and creatively. Do that a couple times a week. I find that sometimes doing one task at one coffee shop and then going to another place (library, etc) and doing the other one will also help break the monotony.

Outside of Work (AKA: Social Life)

Outside of work – do something that requires you to get out of the house. Join a fitness group – yoga, pilates, CrossFit, Brazilian Jiu-Jitsu, etc. You’ll get that social connection that way. I highly recommend it to be fitness or martial arts related.

Fitness and martial arts communities are very tight knit and you’ll find a vast array of individuals you can connect with that have differnet backgrounds. Through these groups I’ve become friends with Lawyers, Doctors, Dentists, stay at home mothers, Insurance Reps, Students, you name it – they’re all there. Fitness and martial arts crosses all boundaries. It will be worth your while. Trust me on this one.

Create Some Mental Space

Try to meditate. Not into meditation? Try the free 10 day guided meditation from headspace.com (download the app and try it out).

If you haven’t noticed yet, this is all mainly mental.

Communication when Remote

As for your typical day to day work routine …

You are going to have to communicate about 3x-4x as hard as you did before.

That’s the way it is.

Being remote means you have to be way more proactive.

Don’t hear from your boss/teammate/etc and you’re stuck?

Pick up the phone. Text. Call. Blow up the slack channel. Anything. i.e. – Clear your own road.

When you’re remote you’re not visually there and sometimes you have to be loud before others respond. Voice your opinions.

The goal is to communicate very well.

TLDR;

Its all mental.

You need to create a schedule, stick to it, take care of your body, create the proper mental mindset and cultivate it (day in and day out). You need to create “out of band” social connections so you don’t go crazy. Do that with a fitness/martial arts group. Break work into chunks and get out of the house a couple times a week. Lastly, communicate the hell out of everything. If you’re not sure if you communicated enough, do it more. Annoy people if you have to, you’re remote and sometimes people forget about you if they can’t see you.

Follow those simple steps and you’ll thrive in a remote atmosphere and you’ll end up enjoying life 10x more than you ever did before.

Finally, if you ever have a question about remote working – email me – I’ll help. I’ve been through probably almost anything you’ve been through working remote.

Filed Under: Business, Development, Health

« Previous Page
Next Page »
Donn Felker Google Android GDE Fragmented - An Android Developer Podcast

Projects / Apps

Caster.IO
Fragmented Podcast
American Express Android
Aaptiv
AndroidJobs.IO
Groupon
MyFitnessPal
Poynt

Books

  • Android Developer Tools
  • Android App Dev For Dummies V2 (V1)
  • Android Tablet App Dev for Dummies

Categories

  • Book
  • Business
  • Development
  • Health
  • Marketing
  • Misc
  • Mobile
  • Screencasts
  • Uncategorized