2

I am beginning to look into using White UI testing with XUnit.

The basic structure for my tests is

  • Open the application
  • Test Something
  • Close the application

This works really well when test passes. However, when a test fails, the application is not closed. If multiple tests fail, this leads to lots of opened instances of my application.

To get around this, I use try and finally blocks but it is not very nice.

Is there an alternate option which achieves the same cleanup behaviour but looks a bit nicer? Like a "RunOnAssertFail" method?

[Fact]
public void MainWindowCreated()
{
    bool testFailed = false;

    Application application = Application.Launch(@"C:\Program\Program.exe");
    Window mainWindow = GetWindow(application, "MainWidndow", 500);

    try
    {
        testFailed = true;
        mainWindow.Should().NotBe(null, ". Main Widndow could not be found");
        testFailed = false;
    }
    finally
    {
        if (testFailed)
        {
            application.Close();
        }
    }

    /*
     * Rest of test case
     */

    application.Close();
}

private static Window GetWindow(Application application,
    string windowName,
    int timeoutAfterMilliseconds)
{
    Window window = null;

    try
    {
        window = Retry.For(
            () => application.GetWindows().First(
                windowX => windowX.Title.Trim().Equals(windowName.Trim())),
            TimeSpan.FromMilliseconds(timeoutAfterMilliseconds));
    }
    catch (InvalidOperationException)
    {

    }

    return window;
}

Requires xUnit, White and Fluent Assertions to run.

Dan
  • 7,286
  • 6
  • 49
  • 114

2 Answers2

1

After playing around I realised the assertions were it was throwing an exception and not actually asserting.

Therefore to help tidy it up, a try catch block is more appropriate

try
{
    mainWindow.Should().NotBeNull("because this window is required for the rest of the test");
}
catch(XunitException)
{
    application.Close();
    throw;
}

However, this is still not ideal.

Dan
  • 7,286
  • 6
  • 49
  • 114
  • 2
    A try... finally block may also be useful. Cleanup code can be ensured to run regardless of particular exceptions. – C Perkins Jan 28 '22 at 18:13
0

What about implementing IDisposable on your test class and use that to clean up?

Dennis Doomen
  • 8,368
  • 1
  • 32
  • 44
  • I thought about this, my issue is that depending where the test is, the cleanup might be different. For example, if the test involves adding information to a database, to see if it is listed, then something goes wrong before the data is removed, the cleanup would involve removing that data. This would be done in the test normally but it stops before it gets there. Using IDisposable would assume the cleanup is the same for each test and unfortunately this is often not the case. – Dan Apr 14 '19 at 17:32
  • You can also consider trying https://chillbdd.com/. It's a little BDD-style framework that makes it a lot easier to clean-up your tests. Check out the getting started at https://chillbdd.com/documentation/#before-and-after – Dennis Doomen Apr 25 '19 at 18:36