Data-Driven Product Management at Groupon

Data-Driven Product Management at Groupon

Data-Driven Product Management at Groupon

Laura Hamilton
Group Product Manager
May 22, 2018


At Groupon, we have a very data-driven philosophy of product management. In this blog post, I’ll talk through how we approach product ownership in a data-driven way, from financial forecasting to roadmapping to feature development to experimentation.


Financial Forecasting and Roadmap Creation

For every candidate feature, we calculate the projected financial upside according to the following formula:

feature_revenue_forecast =
expected_lift x platform_factor x success_probability x platform_revenue


  • feature_revenue_forecast is what we are trying to calculate (the expected revenue from the feature)
  • expected_lift is the increase in conversions we expect from users in the treatment group vs. users in the control group. The vast majority of experiments fall between -1.0% and +1.0% lift.
  • platform_factor is what percent of all users of the platform (whether iOS, android, mobile web, or desktop web) are part of the experiment. For example, for a test on the checkout page on mobile web, the platform factor will be 100%—100% of users who place an order on mobile web visit the checkout page during their journey. For a test on the getaways deal page, the platform factor will be much smaller, so the overall financial impact of the test will be smaller.
  • success_probability is a haircut we apply to take into account that not all experiments will succeed. In fact, only about 30% of our experiments are successful. The success_probability for a given feature could be greater than or lower than 30%, depending on how confident we are that the experiment will succeed. For some experiments that are primarily for strategic reasons, such as maps improvements, we will use a success_probability of 90% or 100%.
  • platform_revenue is the total revenue generated by the platform. For example, the platform_revenue for iOS is the total revenue from orders placed via the iOS app.

With this formula, we have a consistent and data-driven way to estimate the upside from each proposed initiative. Then, once each experiment concludes, we compare our estimates to the actual results, and over time we refine our estimations.

We use these estimated upside figures to create product roadmaps. In order to prioritize initiatives and determine the cutlist, we need to introduce another data point—the engineering effort required. Then, we use the following formula to calculate the ROI of each feature:

ROI = feature_revenue_forecast / level_of_effort

We then stack rank features according to their ROI.

ROI is an input into the creation of the product roadmap and the determination of the cutlist, but it is not the only input. I always like to ensure that there is a healthy amount of time spent on engineering excellence (site stability, paying down technical debt, reducing latency, library upgrades, increased test coverage, improved tooling). I also like to ensure that we have a customer focus. Many of our features come directly from customer feedback via focus groups, quantitative surveys, and app store feedback; the Wishlist feature was one of these. I also reserve a healthy amount of time for strategic initiatives that may not provide lift in the short term but that set us up for success in terms of the Groupon 2020 vision.


Image source:

Data-Driven Features

At Groupon we are lucky to have vast amounts of data that we can use to deliver a delightful product to our customers. We have worked with one million merchants to date; we have pumped more than $18 billion into local businesses; we have more than 1 billion Groupons sold; our app has been downloaded 171 million times, and we have saved customers more than $28 billion.

The Groupon platform handles tens of billions of user actions per month, and for machine learning algorithms that drive core product features our platform needs to make decisions (such as which deal to show the user next) in fractions of a second.

Developing product features that take advantage of these vast amounts of data in a performant way is an interesting challenge.

We use machine learning algorithms in a variety of ways to develop products here at Groupon:

  • Supply intelligence – There are millions of merchants we could call at any time to get onto our platform; how do we pick the best ones?
  • Fraud prevention – Fighting the bad guys in realtime.
  • Discovery and personalization – Selecting which deals to show a given user in her mobile app deal feed.
  • Image recognition – Identifying the best user-generated images with neural networks.
  • Logistics – Getting ahead of the order rush by sending extra inventory to the right warehouse in advance of high demand.
  • Customer support – AI-based chatbots to respond to and resolve customer issues instantaneously.

Groupon Mobile App

To make developing data-driven products faster, we built a generic, extensible machine learning platform at Groupon called Flux. Flux is the “Rosetta Stone” between data scientists and engineers.

Flux capaciter

Image: Wikimedia Commons

Data scientists work primarily in R. Flux models are written in Java and Clojure for stability and speed. Python is the glue that connects R and Java. It all runs on Groupon’s large Hadoop cluster.

To make the process for productionalizing machine learnings more robust, Groupon has an ETL management platform called Quantum Engineered Data (QED). QED reads from any source, and includes built-in data cleaning, error correction, and anomaly detection. Clean data is preserved and made available as a “feature catalog.” QED handles failures smartly, supporting falling back to yesterday’s model when appropriate. QED is able to plug into any source of truth—including streams, warehouse tables, and JSON endpoints.

Smart people doing interesting work

QED gives us a lot more confidence in the robustness of our models. In general, subtle changes to a single data field can seriously impact model performance, and nuances in the data set could look fine to tests but fail in the real world.

machine learning - xkcd

Image credit: XKCD


This blog post would be incomplete without a brief discussion of Groupon’s monitoring tools. We have a healthy suite of realtime alerts on product and engineering KPIs. We use splunk for logging and wavefront for graphing. Each service is staffed with a 24/7 on-call schedule, with escalation handled by pagerduty.

Additionally, each product area and business has an Amazon-style Weekly Business Review, where we look at metric trends longitudinally, identify areas of change or concern, and begin deep dives where appropriate.

The data warehouse uses Teradata and Apache Hive.


There are 100 teams at Groupon that run experiments. At any given time, around 200 experiments are being run simultaneously on the Groupon platform.

Groupon has a dedicated team called Optimize that built a bespoke tech platform for running product experiments with mathematical rigor. The experimentation platform is called Finch Express. Finch Express is built with Ruby on Rails, Node.js, Ember.js, Python, R, and Hadoop/Hive. The team has filed three patents for its innovations on product experimentation.

Essentially, Finch Express uses a technique called Group Sequential Analysis, first developed by Abraham Wald in 1945. Group Sequential Analysis has been used extensively in high-risk clinical trials, such as heart valve studies, where it’s possible that one treatment is actually harming the patients. Ethically, we would want to stop a harmful clinical trial immediately—but statistically, checking the experiment results mid-run or “peeking” will vastly increase your rate of false positives and invalidate your statistical results.

Group Sequential Analysis provides a controlled, statistically rigorous way to “peek” at experiment results at set points during the experiment run. This allows Groupon to end an experiment early if it is losing money, and to roll out an experiment early if it is deemed an early winner (capturing more upside).

Finch Express does all of this automatically. Product managers create the experiment in Finch Express, add a description and screenshots (to save the details for future product managers to reference), and launch the experiment at 50/50. Finch Express does the heavy lifting of dynamically determining the appropriate lift sensitivity for the experiment (based on traffic and conversion rate), performing the Group Sequential Analysis calculations, deeming the experiment a “success,” “failure,” or “flat” (most experiments end flat), and even automatically rolling out or rolling back the experiment based on its results. Then, Finch Express reports on the financial results of the experiment. The experimentation platform prevents product managers from statistical no-nos, such as peeking, unbalanced bucketing, and concluding the experiment too early. As a result, our experimentation processes have a high degree of statistical rigor.

On average, Group Sequential Analysis allows us to conclude experiments an average of 57.53% earlier compared to simply running them to a single final checkpoint. This reduces the cost of failed experiments, hastens upside capture of successful experiments, and allows for much faster iteration and innovation.

To date, Groupon product managers have run a total of 2,500 experiments, thanks in large part to the proprietary and patent-pending experimentation platform.

correlation - xkcd

Image credit: XKCD


Thanks for staying with me until the end! I hope this gives you an idea for how we use big data at global scale here at Groupon to create our product roadmaps, to innovate with new products and features, to monitor product performance, and to evaluate the impact of new initiatives. If you’re interested in learning more about data-driven product management opportunities at Groupon, have a look at our open roles.

Laura heads up product for consumer web, international, and LivingSocial at Groupon. She has a bachelor’s in mathematics from the University of Chicago and a master’s in computer science with specialization in machine learning from Georgia Tech. She has more than 10 years of experience in ecommerce product management at four Chicago tech companies, from early stage startups to publicly traded global companies. She is passionate about using analytics and machine learning to create a delightful customer experience.

Laura Hamilton

Group Product Manager

A Leader’s Garden—Designing a thriving organization when you aren’t in control.

A Leader’s Garden—Designing a thriving organization when you aren’t in control.


Aug 19, 2014

A Leader’s Garden—Designing a thriving organization

when you aren’t in control

Written by Todd Webb, Senior Technical Leader

What if organizations were natural ecosystems, and like any other part of nature, cannot be controlled?


We like to think that we stand apart from nature, but what if we do not? What if our organization is just like a garden, with all its living and non-living elements, each at the same time independent and interdependent? How would this inform the way leaders approach the challenge of building and maintaining an organization?

If organizations were ecosystems then leaders must act as gardeners. Just as the master gardener must tend to an infinitely complex natural ecosystem, the leader must tend to an infinitely complex human ecosystem. Though the complexity of the ecosystem may be beyond our comprehension, if we understand its fundamental properties, we can help it thrive without the illusion of control.

What are the fundamental properties of a thriving organization?

A thriving organization is fundamentally a network of people with diverse motivations, sharing a purpose and objectives, and acting heedfully via systems and patterns of feedback.

A network of people

When you envision your organization do you think of a hierarchy? If you do, you are missing nearly everything important about how your organization works. If you were to visualize the real interactions between people inside and even outside the organization, you would see a tangled web of connections, some formal, some informal, some known, some unknown. You find people who influence the organization far more than their title or authority would suggest and others who have far less influence than you would expect given their positional power.

Although we may influence, we cannot control the network’s form, or evolution, but through an awareness of the network, can unleash its power.

(For more on networks watch The Power of Networks)

With diverse motivations

When you envision the motivations of the people in your organization do you think of everyone pulling the same direction with similar motivations or acting in self-interest and pulling against one another? Humans are wonderfully diverse and messy. They often have motives in line with organization goals, but they also have power motives, career motives, fear motives, outside interest motives.

Although we cannot control people’s motives, we can influence those motives through understanding and an expression of empathy. We must amplify shared motives and help people accept and find strength and creativity in diverse motives.

(To learn more about what happens when we fail to understand diverse motivations and act with empathy read Leadership and Self-Deception)

Sharing a purpose and objectives

When you ask anyone in your organization what the shared mission is, can they recite it? Do they list the organization’s values and principles? Do they share stories about people who embody those values and principles?

A shared understanding of values provides the glue for the foundation of the organization. This shared understanding of mission, values, principles, and objectives must permeate the organization and become a common lexicon within the company.

Acting heedfully

When you look around at the people working in your organization, are they aware of what is going on around them? If something went horribly wrong how quick would they notice and how well coordinated would their response be?

We must design and foster patterns of heedfulness. Heedfulness leads to resilient teams that can overcome significant chaos and change to reach a goal.

(To learn more about resiliency and heedfulness read Managing the Unexpected: Resilient Performance in an Age of Uncertainty)

Via systems and patterns of feedback

Keeping all those fundamental properties in mind, we must tend to the organization by designing and encouraging systems and patterns of feedback that foster heedfulness, and harness diversity, while reinforcing shared purpose and objectives.

Designing in Systems and Patterns

A master gardener understands the underlying patterns of the garden. They understand how each element of the garden produces, uses, or affects the nutrients, sunshine, water, temperature and other factors that help the garden thrive. They design their garden to reinforce those patterns with no illusion that they are in control. Master gardeners are systems thinkers.

We must be systems thinkers too. We must understand and design in systems and patterns of feedback. A thriving organization has many layers of feedback:

  • An all-hands Q&A with senior executives
  • A personal pat on the back for a teammate
  • A practice community that shares knowledge about the Java programming language
  • A book club that studies management practices
  • A governance meeting that helps an engineering team decide what they should work on
  • Software developers pair programming
  • Employees job shadowing to learn what it’s like for someone in a different department
  • A retrospective meeting
  • An always-on group chat room for a project team
  • A team standup meeting at the beginning of each day
  • An employee survey
  • A weekly 1-on-1 coaching session

The next time you think about how to influence your organization, to build great culture, to do great things—think about systems and patterns of feedback. Know that you are not in control, but if you design and foster the right systems and patterns of feedback you can help your organization thrive.

(To learn more about systems thinking read The Fifth Discipline)

Modularization of Android Apps

Modularization of Android Apps

Modularization in Android Apps

The mobile team organized a Meetup yesterday in Palo Alto out of the new large Spontaneous Combustion conference room. We had about 30 engineers from the area attend plus a great turnout from our team. Eric Fararro introduced Groupon engineering as a whole, followed by a technical talk about application modularization / instant app preparation given by Aolei Zhang and Erik Kamp. We fielded questions about this topic after the talk and had a handful of engineers interested in joining the Groupon mobile team as a result!

Special thanks to Stephane Nicolas for mentoring us through the talks, Daniel Molinero and Cody Henthorne for all the great feedback and pointers, and Lupe Leon for all the help organizational-wise.

Architecture Patterns for Backends beyond SOA

Architecture Patterns for Backends beyond SOA

Architecture Patterns for Backends beyond SOA

Javier Cano, Senior Software Engineer
Sergey Burkov, Senior Java Developer
December 13, 2017

In the Merchant Experience team specifically, and in Groupon in general, we have to deal with the challenge of scale and performance that our global business imposes. We make heavy use of SOA and microservices in our platform, though that is usually not enough. The solutions that we need make us explore and try different architectural patterns that move beyond what a SOA approach can provide. In this short talk we’ll explore some of these alternatives architectures, which problems they solve and how they integrate in microservices platform.

You can see lots more video of Grouponers and their smart friends on our YouTube channel.

Messaging at (Groupon) scale

Messaging at (Groupon) scale

Messaging at (Groupon) Scale

Nikita Berdikov
Senior Software Engineer
December 13, 2017

Every company is using messaging one way or another. So do we at Groupon. Messaging platform allows distributed heterogeneous services communicate with each other in asynchronous publish-subscribe fashion. Let’s talk about problems it helps to solve and problems it creates (especially from the owners of messaging infrastructure point of view). In addition we will go through tools we have built around messaging for better monitoring, maintenance and issues.

You can see lots more videos from Grouponers and other smart people on out YouTube channel.

Geekfest: Web.js (Full Stack Javascript)

Geekfest: Web.js (Full Stack Javascript)

Web.js (Full Stack Javascript)

Jaime Garcia Diaz
Software Engineer
November 14, 2017

Javascript is one of the most popular programming languages.
It's flexibility has impacted the way the web is being built.
s build a full-stack application with Javascript.
We'll touch on integrating with Docker, Mongo, Nextjs, Graphql, React and MaterialUI.
Recommended for anyone interested on Javascript and how it can be used on different web architecture tiers.

See all Geekfest videos from Groupon and our friends.

Data Driven Chicago (Second Edition)

Data Driven Chicago (Second Edition)

Data Driven Chicago

Ilhan Kolko (Echo)
Andrew Lisy and Laura Hamilton (Groupon)
Tyler Hanson (Reverb)
Mary Feigenbutz and Greg Reda (Sprout Social)
Laurie Skelly and Elizabeth Cleveland (Trunk Club)
Moderated by Alli Diedrick (Built In Chicago)
November 2, 2017

Showcasing some of the great data-driven and machine-learning talent here in Chicago. Brought to your by Groupon, hosted by Built In Chicago.

See more videos from Groupon and our friends.

Grox: The Art of the State

Grox: The Art of the State

Grox: The Art of the State

Alin Turcu
Android Software Engineer
November 2, 2017

Once upon a time, you started a new app and everything was simple and nice: a few features, a simple UI and that’s it. But then it became bigger and bigger, and the logic became more complex, more entangled. Suddenly, you have a database, you have multiple network calls, several components talking to each others on different threads, callbacks everywhere and multiple user interactions.

The state of your app is modified from everywhere and at any time. At this point you can’t even clearly say in which state your app is after a user interacts with a few elements in the UI.

Let’s consider a typical Android App

Our apps do things like interacting with a server, with the local disk storage, and the UI. All these interactions can change the state of our app and can happen on different threads. How can we easily coordinate all this without losing our clear state?


Grox is an open source library inspired by Flux, Redux, Cycle, and Rx Managed State that makes it easier to manage the internal state of complex applications.

Let’s see how the above diagram would change with Grox.

Wow… That’s a lot of new stuff!

Let’s walk through all the elements in the diagram.

Grox concepts

Grox comes with 3 different modules.

The “Grox-Core” module defines the Action and Store classes.

The Store is the component that contains the state of your app. It is the unique source of truth about its state. The Store keeps state, dispatches actions and notifies its listeners of state changes. This part of the library is synchronized so only one action can change the state of the store at a time.

There is a second variant of the Grox-Core module, called “Grox-Core-Rx“ which uses Observable instead of a list of listeners.

Actions change the state inside the store, and in turn the store will emit the new state. Actions are pure functions, 100% reproducible and testable, their only purpose is to create a new state from the old one. The above diagram exemplifies how the store and actions work together. Actions are generated by commands.

Commands produce a stream of Actions. They are part of the Grox-Commands module and are based on RxJava. Commands return a stream of actions represented by an Rx Observable. Every possible output of the command is mapped to an Action. Commands are used in Grox to interact with non-pure logic, not 100% reproducible parts of your app such as a network call, an interaction with the file system, etc. Events are generated by user interactions or by system evens like push notification or location change. They are mapped to commands that get triggered when an event occurs.

How to Grox

Let’s use the concepts described above to create a login screen.

The sequence of events would be something like this:

Let’s see what happens when the user presses the login button:

  1. A click event is generated.
  2. A command will be started that will make a HTTP call to our server. This command knows the sequence of steps to be executed for the “Login use case”
  3. The first action the command will emit will create a new state that will represent the “login in progress state”.
  4. Once the HTTP call is completed, the command will emit a new Action that will change the state from “login in progress state” to “login finished successful” state.

The app will receive the new state from the store by subscribing to a stream of states. These states will be used to change the UI of your app. This way the UI becomes a passive representation of the state.

Enough talking, show me code!

Grox works wonderfully with RxJava so we will also use it in our example. Grox does not impose the use of RxJava, we can use the Store and Actions without it but we would need RxJava if we want to use commands.

First we define our login states.

Next, we build the initial state of the store. In the initial state we have no logged in user and the login request is not started.

Let’s see how the Login command looks like:

In the above example we assume that we have a LoginApiClient class that performs the actual network request and throws an error if the request fails or returns an error code different than 200. We perform the request in a separate class and we pass it as a parameter so we are able to test this command by mocking the loginApiClient object. The LoginApiClient returns the logged in user if the request is successful

All the outputs of a command must be actions, even in the case of errors. At the network layer, errors do occur but in upper layers, they will represent a state of the app. In case of an error, a new “error state” is created and the UI can display it accordingly.

Using the RxChain, we map the successful result of the request to a LoginSuccessfulAction and in case of an error to a LoginFailedAction. We also start with a LoginInProgressAction so, we change the state to “in progress” which will make the UI display a progress indicator while the actual network request will be performed.

The LoginSuccessfulAction and the LoginInProgressAction are very similar, their responsibility is to create a new state using the old one.

LoginSuccessfulAction saves the logged in user in the store so that the UI can display the user details.

The LoginInProgressAction works exactly in the same way. It just sets the loginState to LOGIN_IN_PROGRESS. Pretty straightforward, right? LoginFailedAction should also look familiar by now.

As you can see in the example, actions are pure functions and are easy to test. They are 100% reproducible (so, no network calls, no disk access, etc. as they can fail). The non-reproducible part of the job of our app goes into commands.

Wiring everything together

Ok. We have built all our components. Every component is encapsulated, testable, and has a clear responsibility. The next thing we need to do is to wire everything together. This can be done inside the View or inside the Presenter, it depends on what kind of design you have inside the app. For simplicity in our example we wire everything inside the LoginActivity.

Let’s walk through what is happening here. First we subscribe for store updates. states is a static method in Grox library that receives the store as parameter and returns a stream of states. We observe these states on the main thread and we update the UI once a new state is emitted.

Next, for every click event, we create a LoginCommand and we “launch” it by calling the actions() method. This method will return a stream of Actions that will be dispatched to the store. If we use RxBindings the code becomes even more elegant:

Now you can clearly see that the click event is mapped to a LoginCommand. That’s it! Pretty simple, right? We can now apply this design for every event and every operation in your app.

Once you start to Grox, you never go back

Smart people doing interesting work

Grox your Android app!

Grox provides a clean solution for managing the state of an app. The main benefits of using the Grox design are:
Clear Concepts: Every entity described above has a well defined role. Grox provides a clean architecture, with a clear separation of concerns between state, store, commands, events.

  • Unified Process: Using Grox design you can actually represent everything that can change the state of your app or of a certain screen. All parts of an app, all screens, can use Grox to unify their handling of state. You can represent user interaction and you can represent operations. These operations can have different purposes like accessing the file system, making network request or even performing some computations.
  • Scalable: You can add as many operations as you want and your app state will still be clear at any time. The same design easily scales to all events and for every operation that changes your app’s state.
  • Testable: All the components that you create using Grox can be tested.

More info:


Cool introduction video:

Thanks to Stephane NICOLAS, keith smyth, Cody Henthorne, Eric Farraro, Samuel Guirado Navarro, David Dumitru, and Mihaly Nagy.

How I Learned to Love Unit Testing with Toothpick

How I Learned to Love Unit Testing with Toothpick

How I Learned to Love Unit Testing with Toothpick

Siqi Guo
Android Software Engineer
October 13, 2017

Once upon a time, you started a new app and everything was simple and nice: a few features, a simple UI and that’s it. But then it became bigger and bigger, and the logic became more complex, more entangled. Suddenly, you have a database, you have multiple network calls, several components talking to each others on different threads, callbacks everywhere and multiple user interactions.

The state of your app is modified from everywhere and at any time. At this point you can’t even clearly say in which state your app is after a user interacts with a few elements in the UI.


In object-oriented programming, a class usually depends on other classes. However, as a good practice, you should only test one method of one class at a time. If a test interacts with more than one class, it would not be a unit test, but an integration test instead. In that case, when the test fails, it’s not clear which unit caused the failure. It could be the class under test or one of its dependencies.

Mock objects are commonly used to isolate the class under test from its dependencies. They are created to mimic the behavior of real objects. We can use mocked versions of the dependencies instead of real ones when unit testing. The class under test is unaware of whether the dependencies are mock or real objects. So we can test that the class under test behaves as expected by controlling the state of the mocks.

Here is an app, inspired from our business domain at Groupon, that sells deals. It uses the MVP pattern:

  • DealActivity is used to display the details of a deal.
  • DealPresenter is the presenter of DealActivity. It is responsible for reacting to user interaction and updating the view. DealPresenter has four dependencies, DealUtil, DealApiClient, WishlistManager and DealViewStateModel.

  • DealUtil is an utility class for deals.
  • DealApiClient is used to make network calls.
  • WishlistManager is used to add or remove the deal from the wishlist.
  • DealViewStateModel contains no logic. It is simply a bundle of variables that represent the view state. There is no method in that class, so nothing to mock.

DealPresenter needs to be isolated from its dependencies, when we are testing it. We can do this by creating mock objects for DealUtil, DealApiClient and WishlistManager. Then, expose these mocks to DealPresenter with Dependency Injection.

Dependency Injection (DI)

The intent behind DI is to decouple the dependencies from a class by passing in instances of those dependencies.

In the example above, instances of DealUtil, DealApiClient and WishlistManager are not created by DealPresenter, but are passed into its constructor.

How can DI make mocking easy? The class under test is not in charge of instantiating it’s dependencies. They will be passed to the object by the DI and the object just has to use them. Consequently, when unit testing, we can pass in mock objects which have the same interface as the real dependency.

In the previous example, we can pass in mocks for DealUtil, DealApiClient and WishlistManager, when testing DealPresenter. Note that we do not inject it but instantiate it manually, hence there is no need to mock the DealViewStateModel.


DI seems simple to implement in the example above, but if there are more classes in project, it’s not so simple anymore. In the graph below, class A has dependencies B and C, and class C has dependencies D and E. If we want to create these classes using DI, we need to inject D and E into C, then we need to inject B, C, D and E into A. Try to imagine in a real Android app, the dependency tree may be much bigger, it is a disaster to implement the DI manually. 😱

So we usually use dependency injection frameworks. You may have heard of some popular ones such as Dagger or Roboguice. At Groupon, we actively contribute to many open source libraries and have also developed a DI library named Toothpick. It’s as fast as Dagger, but designed with ease-of-use in mind. If you are interested in the library, you can get more info from Github.

Creating dependencies is really easy with Toothpick, we just need to annotate the fields with @Inject. Toothpick will create the dependencies and assign them to the right field for us:

But let’s go back to our topic, why am I talking about Toothpick? Because it comes with advanced test support!


Toothpick supports Mockito and EasyMock test frameworks. We will use Mockito in our example. Mockito comes with a JUnit Rule, MockitoRule. MockitoRule injects mocks into the fields that are annotated with @Mock, that way we can use them both in our test and in the class under test at the same time.

Afterwards, we can include the ToothPickRule provided by Toothpick. It does two things:

First, the ToothPickRule will create a real instance of the class under test.

Smart people doing interesting work

Second, it will inject the dependencies of the class under test. If we have created a mock using the MockitoRule, it will inject that mock inside the class under test. Otherwise, it will create a real object and inject it.

So for our example these would be the steps:

  1. ToothPickRule creates dealPresenterUnderTest.
  2. It finds four fields annotated with @Inject in DealPresenter: DealUtil, DealApiClient, WishlistManager and DealViewStateModel.
  3. It tries to inject DealUtil into dealPresenterUnderTest and finds that we have defined a mock for this type with MockitoRule, so it will inject the mock.
  4. Same with DealApiClient and WishlistManager.
  5. While injecting DealViewStateModel, as we haven’t defined any mock for that type, it will inject a real one.
  6. We have our class isolated and ready to be unit tested!


Although there are some alternative DI libs available for Android and Java, Toothpick is still worth checking out. It is effortless to use and provides powerful test support. Thanks to the ToothPickRule, we can inject the mocks inside the class that we are testing in an simpler manner.

Unit testing helps improve your code quality and it becomes more and more important as you scale your projects. With Toothpick, you will start to enjoy writing unit tests, so I recommend you to go try it out!

With 💚 , the Groupon Android team.

Thanks to daniel hw, Jaden Choi, Eric Farraro, Aolei Zhang, Stephane NICOLAS, David Luu, Weihua Wang, Alin Turcu, and Michael Ma.

From Fragments to Activity: the Lambda Way

From Fragments to Activity: the Lambda Way

From Fragments to Activity: the Lambda Way

Stephane Nicolas
Senior Software Engineer
September 28, 2017

Activities have their lifecycle, and the same goes for Fragments. Hence, communication from Fragments to Activities is notoriously problematic.

The communication between Fragments and Activities cannot be as simple as passing a listener to the fragment that the activity could implement: the Activity would soon rotate and the Fragment would keep a reference to an Activity that had died and would leak. Google recommends a “good old pattern” to achieve this goal and limit the risk of leaks. In this article, we will demonstrate that lambdas are a better solution, more expressive, and easier to maintain.

We have created a Github repo that contains the code of our solution:

The Good Old Way

The official way to make a Fragment communicate with its hosting Activity involves creating a communication interface and to implement it in the Activity:

The Fragment will get a reference to its hosting Activity and use an ugly and risky cast to communicate to the Activity via the communication interface:

There are various issues with this approach:

  1. the casting statement is ignominious and fails at runtime.
  2. you don’t see clearly how the Fragment and the Activity are linked. The link is more implicit than explicit.

This makes the Good Old Way crash-prone, and hard to maintain. Let’s try something different!

The Lambda Way

The Lambda Way will favor composition over inheritance. We don’t want our Activity class to implement the communication interface anymore:

Our communication interface is modified to use any Activity. Thus it becomes independent of the Activity instance and won’t leak it:

We will see below why it uses a generic and it is Serializable.

The Fragment will pass its current hosting Activity instance to the listener when it wants to communicate with it:

And here’s the key: the activity will now set a listener to the Fragment, using a simple method reference.

What is this method reference : MainActivity::onArticleSelected?

This is one of the tough questions of this approach, and it gives us an opportunity for a good dive into the Java syntax.

Actually, MainActivity::onArticleSelected is an ambiguous java statement. It can represent:

  • either a reference to a static method;
  • OR a reference to non static method of object of a specific type.

If onArticleSelected was a static method of MainActivity, we could refer to it via MainActivity::onArticleSelected. Referencing a static method is the most typical use of this type of reference.

But, in our case, onArticleSelected is not static. So, we would usually refer to it as mainActivityInstance::onArticleSelected. This method reference would point to the non-static method onArticleSelected. You could use, for instance, in a Rx chain to map an observable of positions:

So, what does MainActivity::onArticleSelected refer to?

Internally, all non-static methods in Java are compiled in the same way as static methods, but with one hidden first parameter of the type of its enclosing class. Thus, the 2 methods below are almost equal from the byte code perspective:

The method reference MainActivity::onArticleSelected is a reference to the second form of this method. It is now pointing to a method that takes 2 parameters: a MainActivity and a int.

This second method is interesting for us because it is independent of the MainActivity instance. Hence, a reference to it doesn’t leak the activity instance!

From a lambda perspective, the meaning of this method reference is now slightly different: it is indeed a method that accepts a MainActivity and invokes the method onArticleSelected on this activity:

MainActivity::onArticleSelected is equivalent to activity -> ((MainActivity)activity).onArticleSelected(position)

In other words, MainActivity::onArticleSelected is a method reference to a HeadLineListener implementation that is independent of the activity and will work with any instance of MainActivity.

For a fine-grained explanation of method references, please visit the official Java documentation.

Smart people doing interesting work

Disambiguating MainActivity::onArticleSelected

As explained above, this method reference can be misunderstood by the Java compiler. It could understand it as a static method reference. In order to disambiguate it, both the interface HeadlineListener, and the method HeaderFragment#setHeadlineListener will use generics to trigger what is called a target type inference:

Thanks to these 2 generics, the compiler understands that the future method reference passed to setHeadlineListener as a reference to a non static method of object of a specific type, and it will only accept references that point to a method inside a class that extends Activity. This last constraint is reasonable because, from a Fragment perspective, we can easily get the hosting Activity using getActivity(). This is why we can now invoke our listener method on the current Activity:

Surviving the Fragment Lifecycle

The last point is to make sure that our fragment still knows about its callback when it dies and it is recreated by the FragmentManager (e.g. after a rotation). For this, we will serialize the listener into the arguments of the fragments.

In our Github repo, we opted for a very structured approach to create our HeadlineFragment by using a builder pattern. The builder will let you create the fragment with an appropriate listener. Of course, the builder is not mandatory for the “lambda way” to work, you just need to serialize the lambda and you can do it the way you want.

It is generally advised not to serialize lambdas in Java, exactly for the same reasons as inner classes. Nevertheless, this issue is softened here as:

  • On Android, serialization is short term and cannot create issues during application upgrades and class changes.
  • The lambda/method reference is fully static and stateless, and is intrinsically protected from any serialization issue as it can’t contain any reference to a non serializable element nor refer to entities that could have died (e.g. the Activity or the Fragment).


This new approach is quite technical, we agree on this. It also infringes the general rule of not serializing lambdas. However, we believe that this approach brings a few benefits to our code base:

  • The link between Activities and Fragments is now explicit. It can be traced easily inside our IDE as opposed to implementing an interface the Good Old Way.
  • We got rid of the hideous casting of the Good Old Way.
  • We favor composition over inheritance.
  • Code looks quite close to the rest of our modern Rx chains.
  • When using a Fragment with such an API, using the listener interface is as easy as using a method reference and most of the complexity of the solution goes behind the scene.
  • It enforces building fragments using a builder pattern to setup the arguments which reduces bugs at runtime.

Thanks to Samuel Guirado Navarro for bullet-proofing the approach.

Let us know what you think, and thx for reading this article!

With 💚 , the Groupon Android team.

Thanks to Carlos Sessa, Mihaly Nagy, Alin Turcu, Cody Henthorne, daniel hw, Eric Farraro, and Samuel Guirado Navarro.

Alejandro Salinas Talks Network Automation on Packet Pushers Podcast

Alejandro Salinas Talks Network Automation on Packet Pushers Podcast


Alejandro Salinas Talks Network Automation on Packet Pushers Podcast

18 August 2017

Packet Pushers Podcast

On this week's episode of Packet Pushers, Groupon's very own Alejandro Salinas discusses the business impact of network automation. Listen to the episode here.


"We start by exploring the reasons that GroupOn decided to pursue network automation. We also explore how Salinas got buy-in from key stakeholders, including executives and IT teams. We also explore the challenges that come with running a NetOps team, including training, tool maintenance, and employee retention."

Dependency Injection Checks

Dependency Injection Checks

Dependency Injection Checks

Mihaly Nagy
Android Software Engineer
August 15, 2017

Dependency Injection is great to design testable and modular apps, but whether you use Toothpick, Dagger or any other library, there are some tricky problems that come with DI. They can be hard to detect and quality and static code analysis tools (like pmd, findbugs, etc.) can’t help you to solve them.

At Groupon, we ❤️ Open Source software, and we decided to release a tool we developed internally. In this article we introduce Dependency Injection checks that will help you solve some issues that are common to all JSR 330 DI libs.

As code complexity grows, it can be difficult to track all of the dependencies that a particular class uses. This problem is even more complicated when we take inheritance into account. If multiple classes in a hierarchy inject the same dependency, it is perfectly valid from the language perspective, but it leads to slower runtime as you create the dependency subtree multiple times and your dependencies can get out of control. Let’s take a closer look at this issue we call a “duplicate injection”, and how we can use the new ‘Dependency Injection Checks’ library to automatically validate our design:

You’re writing a component “Foo” that uses an util class called “Waldo”, so you inject “Waldo” in that class. Now this class “Foo” in time is extended by “Bar” and “Baz”. Your project evolves and now you have another class “Qux” extending “Bar”.

There’s a new requirement in “Qux” to use “Waldo” for something, but by this time you already forgot all of the injected members of “Foo” so you inject the “Waldo” in “Qux.”

So now you have “Waldo” as a member of both “Foo” and “Qux”, and this is perfectly valid, but it’s not a good design since you can change the visibility of “Waldo” from “Foo” to “protected” and use it in “Qux” as well.

There is no tool to catch these sort of errors, and they creep into the cleanest of codebases.

Dependency Injection Checks

Open Source library is an annotation processor that detects common DI related issues (like the one described above). When a duplicate injection is found, compilation fails, pointing you to the right place in the codebase to fix your issue.

The library uses annotation processing to build up an internal model of the hierarchies that use the @javax.inject.Inject annotation (JSR 330). It then checks to see if an injection is found twice in a hierarchy and records the place where this mistake occurs. Once all the injections are processed it checks for errors and gives the compiler a non successful exit code if one is found.

As mentioned above this will work with DI frameworks that rely on JSR 330 (e.g uses the @javax.inject.Inject annotation) like Toothpick, Dagger and much more.

We designed the library to extend it and add more checks related to dependency injection and we have a plan to add some in the future, like making certain classes forbidden for injection.

You can check it out here:

Feel free to use it in your projects, share it with other projects that might benefit an automated check like this.

We would be happy to get your feedback in this article, and invite every one to contribute with GitHub issues or even pull requests to our new project.