1

I am having an issue running xUnit functional tests on a ASP.net core application. I am struggling to run these tests in parallel, as each test can open a 13 browser instance each and they do not complete as too much memory is consumed. Below is the FunctionalFixture class and have posted a test in this as well (apologies for the formatting of the test):

[Collection("Functional")]
public class FunctionalFixture : IDisposable
{
    public IWebHost Server;
    public IWebDriver Chrome;
    public readonly IWebDriver Firefox, Edge;
    public readonly string BaseUrl = "http://localhost:5000";
    public IConfiguration Configuration;
    public ClaimsPrincipal User;
    public const string TestingCookieAuthentication = "TestCookieAuthentication";
    public MultiTenantContext Context;
    public ChromeOptions chromeOptions;
    public int screenWait = 10;        

    public FunctionalFixture()
    {
        Server = WebHost.CreateDefaultBuilder()
                        .UseEnvironment("Development")
                        .UseWebRoot(Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.Parent.FullName + "/wwwroot")
                        .ConfigureAppConfiguration(ConfigConfiguration)
                        .UseContentRoot(Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.Parent.FullName)
                        .UseStartup<TestServerStartup>().Build();

        chromeOptions = new ChromeOptions();
        chromeOptions.AddArguments("--disable-extensions"); // disabling extensions
        chromeOptions.AddArguments("--disable-gpu"); // applicable to windows os only
        chromeOptions.AddArguments("--disable-dev-shm-usage"); // overcome limited resource problems
        chromeOptions.AddArguments("--no-sandbox");
        chromeOptions.AddArguments("--remote-debugging-port=9225");       
        chromeOptions.SetLoggingPreference(LogType.Driver, LogLevel.All);
        chromeOptions.AddAdditionalCapability("useAutomationExtension", false);
        Chrome = new ChromeDriver(ChromeDriverService.CreateDefaultService(), chromeOptions, TimeSpan.FromMinutes(3));

        var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme, ClaimTypes.Name, ClaimTypes.Role);
        var name = "Test User";
        var id = Configuration.GetConnectionString("UnitTestingGUID");
        ClaimsIdentity claimsIdentity = new ClaimsIdentity(new List<Claim>
        {
            new Claim(ClaimTypes.Name, name),
            new Claim(ClaimTypes.NameIdentifier, id),
            new Claim(ClaimTypes.Role, "ADMINISTRATOR")
        }, TestingCookieAuthentication);
        User = new ClaimsPrincipal(claimsIdentity);
        DbContextFactory DbContextFactory = new DbContextFactory(Configuration);
        Context = DbContextFactory.Create("App_Portal");
        Server.Start();
    }
    public void ForEachBrowser(Action<IWebDriver> action)
    {
        List<Task> tasks = new List<Task>();
        tasks.Add(Task.Run(() =>
        {
            try {  action(Chrome );
            }
            catch (UnhandledAlertException e)
            {
                Chrome.SwitchTo().Alert().Dismiss();
                throw e;
            }
        }));
        try
        {
            Task.WhenAll(tasks).Wait();
        }
        catch (AggregateException ae)
        {
            foreach (var e in ae.Flatten().InnerExceptions)
                throw e;
        }

    }
    public void ConfigConfiguration(WebHostBuilderContext ctx, IConfigurationBuilder config)
    {
        Configuration = config.SetBasePath(Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.Parent.FullName + @"\\MFS_Portal")
              .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
              .AddJsonFile($"appsettings.{ctx.HostingEnvironment.EnvironmentName}.json", optional: false, reloadOnChange: true).Build();
        ctx.HostingEnvironment.ApplicationName = typeof(HomeController).Assembly.GetName().Name;
    }
    //[IDisposable.Dispose]
    public void Dispose()
    {
        try
        {
            Chrome.Close();
        }
        catch
        {
            //in case chrome close fails

        }
        try
        {
            Chrome.Quit();
        }
        catch
        {
            //in case chrome Quit fails

        }
        //Firefox.Dispose();
        //Edge.Dispose();
        try
        {
            Server.Dispose();
        }
        catch
        {
            //in case dispose fails
        }
        //needed to close the Chrome Browsers after the tests have completed

        Process[] processes = Process.GetProcesses().Where(a => a.ProcessName.ToLower().Contains("chrome")).ToArray();
        foreach (var p in processes)
        {
            p.Kill();
        }
    }
}

[CollectionDefinition("Functional", DisableParallelization = true)]
public class FunctionalTestsCollection : ICollectionFixture<FunctionalFixture>
{
    // This class has no code, and is never created. Its purpose is simply
    // to be the place to apply [CollectionDefinition] and all the
    // ICollectionFixture<> interfaces.
}

//test method

[Collection("Functional")] public class Functional { private readonly FunctionalFixture Fixture;

    public Functional(FunctionalFixture testFixture)
    {
        Fixture = testFixture;
    }
    [Fact(DisplayName = "Contact Search GET has main table")]
    [Trait("Category", "Functional")]
    public void GetContactSearchGetHasForm()
    { // Browser Fetch
        Fixture.ForEachBrowser(browser =>
        {
            string BaseUrl = Fixture.BaseUrl;
            browser.Navigate().GoToUrl(BaseUrl + "/AMO/GetContactSearch");
            var form = browser.FindElement(By.Id("contact-search-table"));
            Xunit.Assert.Equal("table", form.TagName);
        });
    }
})
Michael Thompson
  • 83
  • 1
  • 1
  • 8

0 Answers0