Supercharging Web Apps by Testing and Debugging in Production

Supercharge WebApps by Testing and Debugging in Production - Ozcode
Two ways your web application can break are UI bugs and deep-down logical bugs in the server. You can detect and resolve both types with Selenium Test Automation and debugging in Production.

This post is co-authored by Himanshu Sheth, Senior Manager, Technical Content Marketing at LambdaTest.

“Move fast and break things,” goes the famous saying by Mark Zukerberg. But developers know that there’s a delicate balance between your release velocity and how robust your application is going to be. When bugs slip through Staging and get to Production, they start affecting your customers. When that happens (and it certainly does), it’s going to get everybody’s attention and become your top priority. Two ways your web application can break are UI bugs and deep-down logical bugs in the server.

In this post, I’ll show how you can detect and resolve both these types of Production bugs, hopefully before your customers notice them. First, I’ll show how to use Selenium test automation using LambdaTest Cloud Grid to run a web app simultaneously on multiple browsers to catch UI glitches.

With a cloud-based Selenium Grid, you can catch UI issues way ahead of time by testing the features across a range of browser and platform combinations. The fierce battle of quality vs. time can be won by testing on a cloud-based Selenium Grid!

Then I’ll show how Ozcode Live Debugger’s time-travel debugging digs deep into your live server code to help you debug exceptions and logical errors in Production. My reference application is this mock eCommerce site where you can purchase all sorts of goodies related to .NET.

Selenium test automation is a necessity, not a luxury

One of the biggest challenges faced by web developers is uniformity of the UI across different browsers, devices, and platform combinations. Cross-browser compatibility issues can create a huge bottleneck on the user experience, especially if you have not tested the UI on browsers & platforms that are widely used by your target audience. You do not want to irk your customers with misplaced buttons, overlapping texts, and other such usability issues that would drive them away from your website (or web application). However, it is impossible to cover the entire gamut of browsers and operating systems since the list can be an endless one. Did you know that despite the dominance of Chrome and Firefox, Internet Explorer is still relevant, even today? Free up your IT team from the unnecessary burden of constantly maintaining an in-house Selenium Grid that is high on maintenance and yields lower returns. Instead, prioritize the browser & OS combinations on which you intend to perform testing and kick-start with testing on a reliable & scalable cloud-based Selenium Grid by LambdaTest.

How to get started with Automated Browser Testing using a Selenium Grid On-Cloud

If you’re not already familiar with Selenium and how it works, I would recommend reading the “What is Selenium” guide by LambdaTest.

If you’ve worked with Selenium before and prefer it for automating browser interactions, you should give LambdaTest a spin. It helps to overcome existing infrastructure issues with your automation testing script.

To run your existing Selenium test script over LambdaTest Grid, you will need to change the Hub URL from your local machine to LambdaTest cloud. You can do that by declaring your username and access key in the remote Hub URL to successfully authenticate your access to the LambdaTest cloud servers. Your LambdaTest username & access key can be obtained from the Profile Page.

Here are the brief set of steps to perform Automation testing on LambdaTest:

You can monitor the status of the tests run on LambdaTest Grid by navigating to the Automation Dashboard.

Now that you have set up the account on LambdaTest, it’s time to port the working existing test implementation to LambdaTest. Suppose you have used the NUnit framework in Selenium C# for writing the automation tests. The change will be majorly involved in the method implemented under the [SetUp] annotation. This is where you have to instantiate the browser on which the test needs to be performed.

Here is the code snippet which showcases the instantiation of the Chrome browser on a local Selenium Grid:

				
					using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Reflection;
using System.Threading;
using System.Collections.Generic;
using System.Web;

namespace NUnitTest
{
    public class NUnitTest
    {
        String test_url = "test_url";
        public IWebDriver driver;

        [SetUp]
        public void start_Browser()
        {
            /* Local Selenium WebDriver */
            driver = new ChromeDriver();
            driver.Url = test_url;
            driver.Manage().Window.Maximize();
        }
        /* Tests follow here */
    }
}

				
			

As seen above, the start_browser() method instantiates the Chrome browser, after which the URL under test is set. The test(s) would be implemented in method(s) that are under the [Test] annotation.

Before running the tests, generate the desired browser capabilities using the LambdaTest Capabilities Generator. As shown below, select the appropriate browser, browser version, and platform on which you intend to perform the test:

So, how do we port this implementation such that the existing tests run on cloud-based Selenium Grid from LambdaTest? Well, the changes are only involved in the method implemented under the [SetUp] annotation. Instead of a local Selenium WebDriver, we use the Remote WebDriver that passes the test request to the LambdaTest Hub [@hub.lambdatest.com/wd/hub].

				
					using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Collections.Generic;
using System.Web;

namespace NUnitTest
{
    public class NUnitTest
    {
        String test_url = "test_url";
        public IWebDriver driver;

        /* LambdaTest Credentials and Grid URL */
        String username = "user-name";
        String accesskey = "access-key";
        String gridURL = "@hub.lambdatest.com/wd/hub";

        [SetUp]
        public void start_Browser()
        {
            DesiredCapabilities capabilities = new DesiredCapabilities();

            capabilities.SetCapability("user", username);
            capabilities.SetCapability("accessKey", accesskey);
            capabilities.SetCapability("build", "[C#] Demo of LambdaTest Grid");
            capabilities.SetCapability("name", "[C#] Demo of LambdaTest Grid");
            capabilities.SetCapability("platform", "Windows 10");
            capabilities.SetCapability("browserName", "Chrome");
            capabilities.SetCapability("version", "latest");

            driver = new RemoteWebDriver(new Uri("https://" + username + ":" + accesskey + gridURL), capabilities, TimeSpan.FromSeconds(600));
            driver.Url = test_url;
            driver.Manage().Window.Maximize();
        }
        /* Tests follow here */
    }
}

				
			

With this, you are all set to run your tests on the LambdaTest Selenium Grid. On execution, you can visit the Automation Dashboard to keep a watch on the status of the tests.

Have a look at how your website (or web app) can render differently on different browsers (and browser versions):

Shown below is a cross-browser test performed on IE 8 (running on Windows 7).  Not only is the rendering messed up, but the “Next” button (which is in the SVG format) is also displayed incorrectly.

Compare this with a working test that is run on Chrome 89 + Windows 10 combination. There are no issues whatsoever in the rendering of the web page.

The key takeaway is that cross-browser testing at scale should feature in your automation testing checklist. With this, your customers would be greeted with an ever-lasting product experience that works like a charm on browsers and devices that they love to use!

Online Selenium Grid such as LambdaTest has made it super-easy for us to ensure a cross-browser compatible experience without having to worry much about the infrastructure limitations that curtail browser and test coverage. LambdaTest offers much-needed scalability and reliability so that cross-browser tests can be performed at scale!

Debugging logic in Production with Time-Travel Fidelity

Let’s now look at that other type of bug which I earlier mentioned – a logical bug. Our mock eCommerce site offers a Buy 2 Get 1 FREE deal with some bugs built-in. When I chose 2 of those nifty sweatshirts, the site automatically gave me a third one. Well, they’re cool, but not that cool, so I decided to bag it. But when updating the quantity to 0, the site throws an exception.

Watch this.

Ozcode automatically catches the exception and displays it in the dashboard. We can see it’s an ArgumentOutOfRangeException.

To debug the exception, I click the Debug button.

Ozcode shows where the exception was thrown in the code, and you immediately understand why. There’s an OutOfRange Guard clause, and the value of Input is -1.

Now let’s climb up the call stack a bit and look at method AdjustQuantity where we implemented the Buy2 Get 1 Free deal.

First off, from the red/green color coding, we see exactly which parts of this method were executed in this error flow. The first “if” statement handles the Buy 2 Get 1 Free.

				
					if (newQuantity == 2)
{
	newQuantity = 3
}

				
			

But that handles the case when a customer modifies the number of items from 1 to 2.

In this case, I’ve changed my mind and updated the quantity back to 0, so the second “if” statement is executed (as we can easily see because it’s green).

				
					if (currentQuantity > 2 && newQuantity < 2)
{
	newQuantity--
}

				
			

But someone has not considered an input value of 0 to newQuantity, so we get our exception.

Now, there are any number of APMs or error monitoring tools that will show you that ArgumentOutOfRangeException with the invalid input of -1. None of those will show you the code across the whole call stack and the values of all locals, variables, and method parameters and return values that show you exactly HOW you got to that invalid input. It’s only once you have that data that the fix for this bug becomes trivial.

Now, you may be thinking, “this was a simple example; real life is more complicated.” You may be right, but even for an example like this, you may have found yourself guessing at the solution, adding log entries to validate it, and rebuilding to test. This kind of observability into the code along the whole execution flow of the error is what makes it easy (or at least much easier) to fix any bug, whether it’s in a monolithic application, a redundant microservice, or a serverless function that runs for a microsecond and is then gone – let’s see you reproduce that. With Ozcode, there’s no need to reproduce it. It’s all recorded for you.

Testing and debugging in production, better together

Testing and debugging are two inseparable facets of delivering robust, working software. For Dev/QA collaboration to be frictionless, developers need as much information about errors as possible, and it’s up to QA to provide it. A while ago, I maintained that a perfect bug report could be provided as a single shareable link, and that’s true for server-side logic bugs. If we now consider UX, we need a bit more data, and that’s what LambdaTest provides to complete the picture. LambdaTest can simultaneously test your UI across a large matrix of OSs and browser versions. If one of those combinations generates an exception, data about the exact scenario, configurations, and versions can be provided to Ozcode Production Debugger, where you can take the analysis down to code level. Being able to debug errors connected to specific OS/browser combinations at a code level will drastically cut down the time it takes to understand where the problem is and fix your code. This is truly end-to-end error resolution.

Rami Honig

Comments

Keep your code in good shape!

Subscribe to our blog and follow the latest news in the .NET debugging industry

Ready to Dive into Your Prod Code?

Easy debugging with full time-travel data

The Exception

A Quarterly Roundup

Subscribe to our quarterly newsletter and hear all about what’s happening around debugging with Ozcode

Share on facebook
Share on twitter
Share on linkedin
Share on email

Recent Posts

Follow Us

Join Ozcode YouTube Channel

Let’s start debugging, it’s free!

Thanks for downloading the OzCode trial!

You’re well on your way to making C# even sharper.

If your download doesn’t start automatically , please use this direct link.

If you’d like to install OzCode but don’t have
administrative privileges on your machine, please contact us.

Get Started for FREE!

Ozcode Logo

This website uses cookies to ensure you get the best experience on our website.