Often reviews have been conducted with the developer and reviewer sitting side by side, having a discussion about the areas that could use improvement, identifying any use cases or logic that was missing.
Nowadays, just as with everything else, this communication has shifted to an online system, such as GitHub, which enables reviewers to highlight code and enter comments against it. Developers can reply to those comments if further explanations are needed to justify a coding approach. Additionally, they can make the requested changes and check it back in for another round of reviews.
Some people really enjoy participating in code reviews. Others find it worse than a visit to the dentist. I've been in both camps.
I have participated in many code reviews during my career, both as code author and reviewer. In the majority of those situations, it was a positive experience. I was fortunate enough to interact with reviewers that were supportive and encouraging. Often they provided constructive feedback on how I could improve the code. When that happened, I walked away from the process feeling more confident in myself and my skills because I learned something new that I would apply to my coding practice going forward.
In situations where I was reviewing someone else's code, the developer was receptive to the feedback, and appreciated the encouraging remarks I would make about his/her coding efforts as well. These positive experiences compounded over time which brought the team together, and strengthened the working relationships among team members. It resulted in a happy, cohesive, and productive team.
There have been the rare occasions where the process was mired in friction, creating a rift on the team. In some cases, code reviews were used as a tool for the reviewer to chastise developers, exert authority, or cater to an obsessive compulsive nature over code styles. In other scenarios, the code author was simply unwilling to participate in the code review process in a constructive manner.
Let me explain.
In one case, I worked on a team with an architect who used the code review process to scold developers for coding practices that did not align with his views. He decided to impose his will on the team if anyone disagreed or countered his code review suggestions, regardless of how sound the counter argument was. The more comments he added during the review process, the more his comments became aggressive in nature. Oftentimes, the comments were just repetitive pointing out the same "misdeeds" over and over again.
In this situation, there is no sense of collaboration, togetherness, team work, or respect for any other team member's views. Team members that are subject to this form of code shaming end up feeling deflated and their self-confidence shaken. This is a situation that eventually drives down the team morale, and overall productivity suffers. Eventually, the team may experience a high turnover rate.
In another scenario, a senior team member's obsessive compulsive nature resulted in busy work for his team members. His main pet peeves were the use of tabs instead of spaces, opening brackets being on the same line as the method or property signature, and other non-trivial items that did not contribute to code quality. I understand the need for uniformity, but these are areas that waste the developer's time. The good news here is that this problem is easily solved through the use of code formatting tools that will get the job done automatically when saving changes to your solution files.
If you are working with team members who strive for code formatting perfection, then I recommend that each member of the team make use of one of the many available IDE extensions available, such as Code Maid or Resharper.
As a code reviewer, I have also encountered negative experiences from a team member who was not open to receiving feedback. The code review process seemed to be a source of stress and annoyance for him. In one instance, I highlighted a potential audit issue as a result of his commit, and asked him to correct it.
What was the issue?
Rather than making a simple code change to an existing class, he decided it was more efficient to copy the code into a new class, make the necessary changes, and delete the original class. This resulted in the deletion of the source code history on that file. When I advised him that deleting source code history was a potential audit issue, he did not receive that feedback with an open mind.
Instead of participating in the code review process in a constructive manner, he shrugged off my feedback with responses like "Why does it matter?", "Nobody cares about keeping the history on that one class anyway", "You just want to be right", and so on and so forth.
Considering the work being done was for a large financial institution, where audit trails are a high priority, this was a red flag and I could not let this one slide. Eventually, he conceded to make the change, but this event was the catalyst for another situation I was not expecting.
On that same project, we were required to perform peer code reviews by commenting on each other's pull requests. Once the code passed the review process, the reviewer would be responsible for merging the pull request to master.
This was an opportunity that one team member leveraged to his advantage in order to place the burden of dealing with any merge conflicts on the remaining team members. He refused to merge other pull requests unless his pull request was merged first. There was an instance where he insisted on his pull request being merged first when he did not even have a pull request submitted at the time. When I pointed that out, he tried to save face with a reply of: "It's coming." A day and a half later, he finally had a pull request to review, while the other pull request sat in limbo.
As the project progressed, this type of behaviour drove the morale of the team down to an all-time low and productivity stagnated.
Yes, that's problems, with an "s". There isn't one factor that contributes to the Code Review Blues. It's a combination of many.
The main source of friction during the code review process stems from team members' differing expectations on the code review's intended purpose and end result. At a minimum, code reviewers should verify the code is functional, scalable, extensible, maintainable, and secure.
The following tweet from @bliss_ai is a good starting point on questions you should ask yourself, and discuss with your team, as both code author and reviewer:
When introducing a code review process to your organization, it is ideal to gather your development team into a room to discuss how this will impact the team. This is also an opportunity to educate the team on effective code review practices, and provide proper training on how the code review tool should be used.
This is also an excellent opportunity to answer the following questions:
This training should also be included in the new hire on-boarding process.
Senior members that are in a position of authority may have been promoted through the ranks due to strong technical skills, but they might be a little rough around the edges when it comes to communication and/or interpersonal skills. If code reviews with a specific member become a source of contention for the entire team, it might be time to recommend soft skills training for that team member.
If you're not convinced that soft skills are worth investing in, take the time to read this short article, "Why Soft Skills Matter – Making Your Hard Skills Shine" by MindTools.
It's never easy to critique someone else's work nor to be on the receiving end of the type of scrutiny code reviews require.
If the feedback you provided is valid and communicated with good intentions, but not well received by the code author, this may be the cause of a deeper, underlying issue. A team member may be resistant to feedback on their code changes because they perceive it to be a personal attack.
If you find yourself getting into a heated exchange with someone who takes offense to the feedback provided, take a step back and analyze the form of communication being used. Think about the following points before you proceed with the review:
In this situation, you may need to experiment with different communication and feedback styles to find an approach to which your colleague is open and receptive. If all else fails, seek advice from a senior level manager.
Code reviews are intended to start a conversation about code quality, where all parties emerge from the other side having learned something – whether it is about improving a section of code, adopting better coding practices, or reaching an understanding on the current approach taken.
Everyone should feel confident once the code review process has come to a close that the code submitted performs what it was intended while meeting a defined level of quality.
The code author and reviewer(s) should feel good about the work they are producing, should feel encouraged by the support they receive from each member on the team, and should come out of it with their self-respect and dignity intact.
*Special thanks to Donald Belcham and Shane Courtrille for reviewing and providing valuable feedback which contributed to the overall quality of this post.
]]>Although MacinCloud indicates that the VSTS Agent Plan setup only takes a few minutes, the process is not fully automated and requires some manual steps in order to get your CI Builds working as expected. The initial setup is fairly quick, but your Xamarin.iOS CI builds will fail until you install a Xamarin license on the MacinCloud CI Build Server. The catch? Unlike the other MacinCloud plans, the CI Build Agent Plan does not allow you to directly interact with the Build Server. Instead, you are required to contact both MacinCloud Support and Xamarin Support to complete the process. Set your expectations that it may take anywhere from 2 – 4 days before you can start using the CI Build Agent.
Let's take a look at what is involved, from start to finish, to successfully configure a CI Build Agent for your Xamarin.iOS projects.
In order to integrate Macincloud with Visual Studio Team Services, you need to register for a CI Build Agent plan at MacinCloud.com. The CI Build Agent cost is $29 US per month per build agent.
Once you are registered, you must setup your build agent through the Dashboard, as shown below.
MacinCloud Dashboard
Select the Edit button to configure your MacinCloud VSTS Agent.
In the Edit VSTS Agent dialog, enter a unique agent name and a pool name. Note that the pool name must match the name of an Agent Pool in Visual Studio Team Services.
MacinCloud Edit VSTS Agent Dialog
Enter your VSTS URL to associate this build agent with your Team Services account.
Next, you will need to provide the MacinCloud Build Agent access to your VSTS account, which requires that you generate a Microsoft Access Token from your VSTS profile.
To do this, open a new browser tab, log into your VSTS account and navigate to the security tab for your account profile. Alternatively you can click the "?" button situated to the right of the Microsoft Access Token entry field in the Edit VSTS Agent dialog, which will launch the "Create a personal access token" page in your VSTS Dashboard. Provide a Description, and then select an Expiry term as well as the desired VSTS Account. Ensure All scopes is selected for Authorized Scopes then click the Create Token button.
VSTS Dashboard – Create a personal access token
Copy the generated access token to the clipboard and paste it in the MacinCloud Microsoft Access Token field in the Edit VSTS Agent dialog.
Important Note: Be sure to save a copy of the generated access token in a safe location. You will not be able to retrieve the generated access token again once you navigate away from the Security page after it has been created.
If you wish, you can add your signing certificate and provisioning profile at this time, but it's not required in the initial setup.
Click Save to create your MacinCloud CI Build Agent.
Navigate to the Admin section within your VSTS Dashboard and select the Agent Pools tab. Select the Agent Pool that matches the Pool Name you entered in the MacinCloud Edit VSTS Agent dialog. If everything is configured properly, then the MacinCloud agent will appear in the Agents list, as shown below.
MacinCloud VSTS Agent associated with Default Agent Pool in VSTS
Last but not least, you will need to install a Xamarin license on the Mac server where your CI Build Agent is hosted. Unfortunately, MacinCloud does not provide you with interactive access to the server. This requires some back and forth correspondence with MacinCloud Support and Xamarin Support in order to finish the setup process.
First, you will need to submit a support request to MacinCloud to obtain the server information and system file that Xamarin will require in order to generate a license file for your CI Build Server.
Send an email to support@macincloud.com with the following request:
"I am setting up a CI Build Agent to configure continuous integration builds in Visual Studio Team Services for Xamarin.iOS applications. Please send me the system profile of my CI Build Agent, which I will need to forward to Xamarin support so they can generate a License file. To retrieve the system profile, perform the following steps:
– Go to: Macintosh HD -> Applications -> Utilities -> System Information.app
– Choose File > Save
– Select a location to save the file, such as the desktop, or Documents folder.
– Name and save the file.
– Please email the file to me when this is completed."
This initial email will generate a support ticket within the MacinCloud Support Portal. You will receive an email containing a link to the support request so you can view its status at any time.
Note that response time from MacinCloud Support will vary, with the expectation that it can take anywhere from a couple of hours to 1 full business day to receive a response depending on the time of day that you submit the request.
The generated system profile information file will simply be an xml file with a .spx extension.
Once you receive the system profile information file from MacinCloud Support, you will need to send it to Xamarin Support. Log into your Xamarin account, go to your Dashboard and select Xamarin.iOS to locate the support email address for your subscription.
Send an email to the Xamarin Support using the specified email address, requesting a License.V2 file to be generated for your MacinCloud CI Build Agent. Be sure to attach the spx file that you received from MacinCloud to this request.
Xamarin Support will provide you with the license file and instructions on where the file should be placed on the server. The Xamarin.iOS license file must be copied to the ~/Library/MonoTouch folder on the build server.
I found the turnaround time on this request to be relatively quick.
Forward the license file and relevant instructions to MacinCloud Support, and wait until they send a confirmation that the license has been installed on the server.
To Be Continued...
Now that you have the MacinCloud CI Build Agent properly configured, you will be able to setup continuous integration builds for your Xamarin.iOS projects! In the next post, we will walk through the necessary steps to create a Xamarin.iOS build definition in Visual Studio Team Services.
]]>
Well making the change was trivial. Next came the part that I dreaded, which I knew would take up the rest of my day. I walked over to the device cabinet, and grabbed a handful of devices varying in screen size, resolution and OS versions.
Seated at my desk, I attempted to power on the first device. Battery drain. I plugged it in, then attempted to power on the next device. Same thing. By the time I was able to get enough charge on a device to power it on, deploy to that device, and run through the necessary tests, 10 – 15 minutes had passed. Note that I have to repeat this process on 4 more devices. If the tests all pass the first time, that's about an hour of testing spent on a small fraction of devices for a single UI change. During my round of testing on the 4th device, I already noticed problems with the layout. This is going to be a really long day.
Even if all of my tests pass, QA will perform these tests on another set of devices at random which may uncover other issues. Even worse, what happens if the QA tests passed, and the application made it to market because there were issues on devices we hadn't covered? This wasn't the type of work I wanted to deliver. Ultimately, I want to be sure the layouts look good across as many devices as possible, including the most popular ones on the market.
Now what?
Being out of office for the next week, I wanted to get this change completed to ensure it wouldn't hold the team up in my absence, and I wanted to feel confident that it would look good on a broad range of devices. I knew this would be an impossible feat if I stuck with the manual testing route. I decided to put Xamarin Test Cloud to use to make short work of this.
Thanks to those Xamarin University's courses on creating Xamarin UI Tests and deploying to Test Cloud – which I had already taken as a requirement for the Xamarin Mobile Developer Certification exam – I knew exactly how to get started. I also had some Test Cloud time to burn which comes with being a Xamarin University student – 25 hours to be exact.
I created a new Xamarin UITest project, and used REPL to assist with scripting out the steps. I copied the script into my UITest, and I included commands to take screenshots at specific points in the script. This process took about 10 minutes to complete and test on a local device.
Once I was confident that the UITest I had scripted performed as I expected, I decided to run it in Xamarin Test Cloud, simply by right-clicking on the UITest project in Visual Studio and selecting "Run in Test Cloud…" from the context menu. I was able to quickly and easily select 25 devices to run the test on, all of varying screen sizes, resolutions and OS versions. I was even able to select from devices that were most popular on the market, thanks to a filter provided within Xamarin Test Cloud.
Within minutes, my test was deployed to the cloud, and 10 minutes later the test had been completed on all 25 devices. This consumed about 35 minutes of Xamarin Test Cloud device time usage (approx. 1.4 minutes per device). Based on the results, I had to tweak the layout and re-run the test two more times until the change looked good across the board, but this process was simple, fast and efficient. Now that I knew how fast it was to test on 25 devices, I decided to push it a little further. The next run was on 114 devices. Twenty minutes later my changes were ready to review. Again, the total device time used averaged out to 1.4 minutes per device.
Reviewing the UI change across all devices was easy, because they were laid out on a single page in grid format. It was easy to scroll down the page and quickly point out any nuances which needed to be addressed. I could even filter and sort the view to quickly see the devices of interest.
Test run results of the Xamarin Store Demo app
What could have been 1 – 2 days of effort for a simple UI change, was completed in less than 2 hours, and I had covered more ground in those 2 hours than I ever would have in manual testing.
In addition to that, Xamarin Test Cloud provided metrics on the application's CPU and memory usage, as well as device and test logs. The history of all tests run are maintained in my account so I can go back to review them at any time.
That was the scenario for the effort needed to test a simple UI change. Now compound that effort with a greenfield application, which requires the team to fully test each screen and feature on as many devices as possible. Expecting that a mobile development team and QA will be able to cover ground through manual device testing is pretty far-fetched. Not to mention the costs the company would have to absorb to continue to purchase new devices as they are released in order to be able to stay on top of a changing market.
Many companies balk at the price of Xamarin Test Cloud without considering how much money is being wasted on the current processes in place.
As the company's team continues to build out the organization's flagship mobile app and releases multiple versions, the QA Team becomes swamped and unable to test fast enough to cover ground on all those devices in that trusty cabinet. Developers barely have enough time in the schedule to fully develop the features needed, let alone allot the actual time needed to fully test across devices.
Eventually, the company considers hiring a new QA member to ease the work load. Do you think it is possible to hire someone into that role at $5/hour? No? Well, that's the cost of Xamarin Test Cloud – $5 per device hour when you break it down. Considering I was able to run a single UI test across 114 devices using about 2.5 hours of device time, that would work out to be the best $12.50 ever spent. Not to mention, that's also 1 full day of developer time that is reclaimed to focus on the actual development of the product, rather than fiddling around with device after device to run manual UI tests. Last but not least, your QA team will be more focused on testing the application's functionality rather than being bogged down with logging UI related issues.
If you're still skeptical at how Xamarin Test Cloud can help accelerate your mobile app testing time, make use of the free 60 minutes of Xamarin Test Cloud time you're given each month with your Xamarin Platform Subscription.
Spend a little, save a lot, and keep your mobile product team happy in the process.
]]>