Tuesday Tip Day – Debugging Failing Tests and Closed Browsers

Tuesday Tip Day – Debugging Failing Tests and Closed Browsers

Ok…so it’s not exactly Tuesday in the UK at the time of writing this, but in Australia, it is technically Tuesday already so I’m going with that!

This is a very simple tip, but one that might save people a lot of frustration. I’m sure you’ve been in this situation before, your test is failing and you want to debug it, but you’ve either forgot to put a breakpoint in, forgot to comment out a line of code or just even worse, ran the test instead of debugged it. So now you have to run it all again, and if it’s a particularly long test, that can be quite tedious.

This tip, however, will prevent your browser closing at the point of failure, so give you a chance to see the exact point of failure and the state of the application under test.

Let’s take a simple test along with a teardown method, and see where we might have a problem:

[Test]
public void ThisTestIsAlwaysFailing()
{
    driver = new ChromeDriver();
    driver.Navigate().GoToUrl(startUrl);

    var homePage = new HomePage(driver);
    homePage.GoToLoginPage
            .InsertLoginCredentials(credentials)
            .ClickLoginButton();
    
    Assert.IsTrue(driver.Url.Equals(expectedUrl));
}
[TearDown]
public void TestTearDown()
{
    driver.Quit();
}

Using the above example, one particular developer on our team just loves to refactor code on a whim, without telling anyone. Helpful I’m sure, in his own mind, but a nightmare for us as a side effect is our login button locator is forever changing, breaking our test.

When we run this test to find out where it’s failing, because our web application is so well optimised, as is our test code, the test executes so quickly that as soon as it hits the login page, it fails, instantly closing our browser window. DAMNIT!

We could put some extra code in there, which we might forget to delete and check-in. Oops! We could just remember to always use a breakpoint when running the test, but that may still cause headaches if we forget or we run it again and don’t want it to break there.

So what else can we do? For this solution, we need to use our app.config file. Now we’ve talked about this file in previous articles, talking about how it can be used to store values for things like environment URL’s or login credentials (although…passwords in plain text is never a good idea). We can also use it for situations like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <!-- other setting-->
    <add key="CloseOnFail" value="false"/>
  </appSettings>
</configuration>

But simply putting this value in the app.config isn’t much use on its own, we need to use it somehow.

public static bool CloseBrowserOnFail()
{
    return Convert.ToBoolean(ConfigurationManager.AppSettings["CloseOnFail"]);
}

With the above method, it simply reads the setting we have set in the app.config, and will return true or false depending on that value. Now we can update our test teardown to use this method.

[TearDown]
public void TestTearDown()
{
    if(GetCloseBrowserSetting())
    {
        driver.Quit();
    }
}

Now, when our test fails, if the setting is set to false in the app config, the driver will no longer quit in the tear down, and the browser will remain open at the point of failure.

Of course, you can argue that you may not want code like this entering a master branch in case the setting is left on false when checked in. This would make it no better than commenting out code, however, you could combine this with a build configuration check so that if the configuration is set to DEBUG, then this is automatically set. However you decide to use it, this simple tip will allow you to debug tests at the point of failure if you’re finding you forget breakpoints or commenting code too often.

I’m donning a flameproof suit once this tip gets published as I can see a lot of people disagreeing with it being the correct way to do it…