Optimizing Testing For Server Driven Mobile Development at Strava
Hi there 👋I’m Xin Yi, a junior at UC Berkeley studying computer science. The first time I heard about Strava was through my dad, who had become a dedicated user since the day he discovered the app. Of course, being the teenager I was, I dismissed his suggestion to join despite already being an avid runner. It wasn’t until later on, when I witnessed the real world friendships that blossomed from runs with his local running club buddies that I finally caved — and I haven’t looked back since. Naturally, when I found myself looking for summer internships, I applied and luckily enough, here I am.
This summer, I had the rewarding opportunity of being an Android intern on the Multisport team. Currently, we’re focused on fleshing out an authentic experience for users who participate in athletic activities beyond cycling, swimming, and running, hence “Multisport”. Our main focus was rolling out a re-designed and re-engineered activity details page with a server-driven design for rendering views which I can best describe as this: Each entry on a page is comprised of multiple components — a graph, some text, maybe an icon or two — which Strava calls modules*. Rather than letting the client hold the logic to create specific views, we let the server drive the work. Think of the feed versus the activity details page. For each activity in either view, there’s a header section with the athlete image, name, and badge. Seems a bit silly to have the client hold the same logic to render this in both classes. Instead, we could build a single athlete header template and plop those into these pages when the server’s response says it needs to be displayed.
An analogy to explain the approach is using atoms and molecules. Each entry is like a molecule and each view module is like an atom. An atom of a specific element can be used in a variety of different molecules. You wouldn’t have a hydrogen atom that’s solely used in water molecules and another solely for sugar molecules. The overall page is the final object made up of a variety of entries (molecules).
A question we constantly ask at Strava is, “How can we better serve our athletes?” From delivering useful activity data to shipping app releases consistently, I’ve learned that Strava always holds itself true to its mission — building the most engaged community of athletes in the world. Yet what about serving our employees? Part way through my internship, I realized I wanted to create something that would increase our engineering efficiency so that we could spend more time focusing on the aforementioned mission. That is how I ended up building a mini application to increase the efficiency of testing the UI aspect of server driven rendering.
*Point of clarification: Android itself has modules, which are containers for app code that can be individually tested. At Strava, we call the “atoms” in our “molecules” modules. For sake of clarity, these will be referred to as view modules for the rest of my article.
It began with Jams, a three-day internal hackathon, during which all employees are encouraged to hack on whatever they choose. My fellow intern, Megan Paik and I, along with the help of our mentors, worked on creating an internal switch for employees to toggle between free and premium user accounts. Even within just our team, we saw the many tickets related to the differing account experiences, from displaying upsell copy to an existing premium user to a premium feature being visible to free users. It was refreshing to develop an internal tool versus a user facing feature. This is what peaked my curiosity into looking for other ways to better the development workflow.
Enter Charles. Charles Proxy is an HTTP debugging proxy application. Using their rewrite tool, I was able to change the responses of network requests to my own test JSON responses. This allowed me to test the expected behavior of views before the server side logic was available. Unfortunately, there were an inordinate amount of instances where it just wouldn’t work. Sometimes my phone couldn’t connect to the network properly with Charles. Other times, I would receive random EOF (end of file) errors. In fact, I have yet to get it to work on any of my emulators. What was a pain point for me became my motivator to work on the module UI rendering application.
During an acceptance meeting, I noticed iOS seemed to be rendering JSON responses of their own except it didn’t look like it was being done on their main application. After speaking with Kyle, one of the iOS engineers, and my manager Rod, I found out that iOS had their own example project for the purpose of rendering and testing sample JSON responses. Realizing the benefit Android could have from this, I started hacking away.
After syncing up with my mentor, we realized there was some necessary refactoring before I could start the core work for my project. The way Android was registering supported view modules wasn’t optimal as we had view modules residing in multiple Android modules, some of them in feature modules and others in our base module, where the master list was maintained. During our Guild week, a week where all the engineers on a horizontal team congregate to better the platform’s overall codebase, we re-structured the dependencies between Android modules in our application. The previous way of registering view modules would not be sustainable due to the nature of these changed dependencies. I first worked on changing this process by creating view module lists in the Android modules in which they lived. These modules would then be collected into one master list by our main application module. For future view modules that are created inside of Android modules, a similar format can be followed. This will further compartmentalize the code related to specific features in their respective modules.
With the refactoring completed, I was now able to work on the mini application itself.
I modeled the application after what existed in our main application and stripped out any unnecessary methods and functionalities. The mini application also depends on mostly feature Android modules, as those were where most of our view modules resided. By not relying on the base application module, build times were much shorter when testing. Typically for me, building the main application would take 3 to 4 minutes. When I build the mini application, this shortens to 1 to 1.5 minutes. When only testing the visuals of a view module, this becomes incredibly helpful, especially in situations such as checking one margin dimension change.
Due to the time constraints, many of the features I wanted to add to the application didn’t come to fruition. One improvement I was able to make beyond rendering local JSON was connecting to the prexisting iOS repo with a large number of JSON files through a git submodule. This allows both platforms to test with the same files going forward. As seen below, the application itself is a separate, buildable application module in the Android repo that opens up to the following screen. From here, the user can select the JSON file they want to render from the list in either spinner, which is derived from files stored in the application’s assets folder and the shared repo with iOS. After selection, voila! The JSON response is rendered! No more Charles and no more 3 minute waits.
Like the other interns, the highlight of my summer of Strava was more than solely the work — it was the people and environment I was working in. I was constantly encouraged to ask questions, give feedback, and pursue learning more about any aspect of the company. Interested in building a tool? Talk to your manager. Curious about developing for another platform? Set up a one on one with another engineer. Want to observe a design review? Just ask. It was clear from the start that Strava wants its interns to succeed. From attending the monthly women roundtables, where speakers were invited to talk about their work as entrepreneurs or venture capitalists, to the engineering tech talks, which any Strava engineer can sign up for to speak on an engineering topic they’re excited about, I have learned so much about what others, both within and beyond the company, have done. I already know I’ll miss the WoWs (Workout of the Week), during which employees go on a lunch workout run together, and the energy at All Hands, our company-wide meetings every Tuesday morning. Yet instead of me attempting a mediocre description of just how amazing this internship was, click play below to see it for yourself.
A special shoutout to: my mentors Dave Rozsnyai and David Lee, engineering manager Rod Gutierrez, and co-workers on the Multisport team for the guidance, the laughs, and dealing with my many questions and over usage of my favorite Slack react: