Using visual diff to review code changes

Overview

Changes that affect the architecture and design of a project are among the most important changes that can be made. However, design changes can also be some of the most difficult changes to understand. AppLand’s visualizations of code design and behavior are a powerful way to review design changes, because they depict the code behavior directly, rather than requiring a developer to imagine how code might work by analyzing diffs of source code text files. With branch-specific recordings of code behavior, AppLand enables development teams to quickly and effectively review code behavior and design changes across development branches. This is particularly useful for reviewing pull/merge requests. With recordings of application behavior loaded into AppLand, you can use AppLand’s powerful filters to find and highlight exactly the code behaviors that are proposed in a new branch. Focus on commands, responses, the data model, SQL, and changes to key classes in order to help a reviewer understand how you propose to change the design of the code.

This tutorial uses a variety of open-source applications as examples. You can record and upload test cases of your own applications using the AppMap client tools.

Configure the project to record scenarios from tests

Effective review of design changes starts by creating good test cases and recording these test cases with AppLand. For understanding code behavior, tests which are “medium” in scope provide the most useful information. “Unit” tests are often too small to effectively demonstrate design. Better results are obtained from tests which connect multiple components of the code together. For example, functional tests at the “controller” or “request” level of a web service project are ideal. “Integration” or “system” tests, which exercise an entire app using a tool like Selenium, also provide useful scenarios. So, as you make a significant upgrade or modification to an app, take the time to create functional or integration tests that show how the new code works as a system.

Generate and upload AppMaps from the CI/CD pipeline

Once your application has some good tests, configure your project to record scenarios from these tests. Follow the client setup instructions to add the AppLand client library to your project, and configure your test cases to record scenarios. Once you have this working locally, follow the CI/CD integration instructions to configure your CI/CD pipeline to record AppMaps while running the project test cases and upload them to AppLand.

For many examples of open source applications integrated with AppLand and CI/CD (using Travis), visit the Land of Apps GitHub reposistory.

Inspect the mapsets for the base and head branches

When your CI/CD pipeline records scenarios from test cases, all the AppMaps are uploaded and grouped together in a "mapset". Mapsets reference the branch name and commit hash from which the tests were run, allowing you to find a mapset that's relevant to your work.

Performing a code review entails comparing two code branches: the base branch and the head branch. "Base branch" is Git terminology for the branch in which all approved work is integrated together. It is usually named "main" or "master". A "head branch" is a branch which contains new work. After it’s been reviewed and finalized, the head branch is merged into the base branch. A pull request (also known as a merge request), is submitted by a developer when they are ready to have new code on a head branch reviewed by fellow developers for inclusion into the base.

By integrating AppLand with the CI/CD pipeline, it ensures that two mapsets are available for each pull request: one for the base branch and one for the head branch.

Here’s an example of a project which has mapsets for several versions of the master (base) branch, as well as mapsets for several pull request (head) branches:

With the base and head branches available, it’s time to make the reviewer’s job easy by finding and linking to specific views and scenarios that will demonstrate how a pull request is changing the application design. There are many kinds of design changes, but here are a few that you’ll definitely want to cover.

Describing new features

In this section, we will use the example of a new web service route to show how to use AppLand to help code reviewers understand and analyze how new features work.

Routes define the API of a web service or microservice. So, whenever you add a route, you’ll want to make that obvious to the reviewer. Suppose you’ve added a new route POST /api_keys , which the client can use to issue a new API key. Open the application filters, and type “api” to list the routes. Then select the route POST /api_keys . The component diagram updates to show just the code which is relevant to the new route.

The Related scenarios list enables the user to drill down into a recording that shows exactly how the new route is implemented.

Include a link to this page showing the component diagram with the route filter POST /api_keys applied.

Next, open the scenario, and find the section in the code trace where the new route is invoked:

Put a link to this scenario view into the pull request as well.

Now the reviewer can see:

  • Exactly what new route was added
  • How it relates to other code at a high level
  • Details of how the route is implemented

Describing feature changes

When the design of a web service or other important application feature is changed, follow a procedure similar to the one above. Help your reviewer understand the behavior of the new code by putting links to the application and scenario views into the pull request description. Additionally include links to the previous design and code behavior. This is why having mapsets for the base branch is important: it allows code reviewers to see both the existing "old" and proposed "new" behavior.

Common types of design changes

In the previous section, we talked in general terms about how to provide a reviewer with useful links to understand a new feature or change. Here are some specific types of design changes and suggestions on how to help get them reviewed effectively.

New web service route

This is the example covered in the previous section. Submit links to the application profile page with the route filter selected and additionally include links to any relevant sections of scenario traces.

Web service route removed

The reviewer will be able to verify that searching for the web service in the filters no longer turns up any results. This confirms that the old route has been removed.

New web service parameter

When a new parameter is added to an existing route, add a functional test to show how the new parameter is handled by the application code. Then include a link to this scenario in the pull request, so that the reviewer can:

  1. Instantly confirm that the new parameter is tested
  2. Understand in detail how the parameter affects the flow.
You can also include a link, or links, to other requests to the same route which do not use the parameter. In this way, the effect of the parameter is compared and contrasted.

SQL query change

Often, important code changes are reflected primarily as new or modified SQL queries. When SQL is generated by code, it can be hard for reviewers to understand what the old and new SQL actually are. AppLand scenarios make it very easy to understand an application’s use of SQL, even when the queries are generated by complex code. Simply find and select the query in a scenario, and submit the URL with the pull request description.

N+1 query fixes

When using an object-relational mapper, it’s easy to accidentally issue "N+1" queries to fetch an object and its associations (for example, in a discussion app, a user and their recent posts). N+1 queries are easy and obvious to find in AppLand: the long trails of identical SQL queries stand out prominently.

Include a link to the code that exhibits the N+1 query problem, and the new scenario trace that has the fix. Highlight the new query that eager-loads the data to avoid making N+1 queries.