Scott Hanselman

Detecting that a .NET Core app is running in a Docker Container and SkippableFacts in XUnit

June 29, 2018 Comment on this post [3] Posted in Docker | DotNetCore | Open Source
Sponsored By

Container Ship by NOAA used under CCI have moved my podcast site over to ASP.NET Core 2.1 and I've got it running in a Docker container. Take a moment a check out some of the blog posts, as I've been blogging as I've been learning.

I've added Unit Tests as well as Selenium Tests that are also run with the XUnit Unit Test Runner. However, I don't want those Selenium Tests that automate Google Chrome to run within the context of Docker.

I tried to add an Environment Variable within my Dockerfile like this:

ENV INDOCKER=1

I figured I'd check for that variable and conditionally skip tests. Simple, right? Well, I decided to actually READ the Dockerfiles that my ASP.NET Core 2.1 app uses. Remember, Dockerfiles (and the resulting images) are layered, and with all things .NET, are Open Source. 

Looking at my own layers and exploring the source on Github, I see I'm using:

Nice, so I don't need to set anything to know I'm running .NET in a Container! I wouldn't have known any of this if I hadn't taken 15 minutes and exploring/asserted/confirmed my stack. Just because I'm running Docker containers doesn't mean it's not useful to take the time to KNOW what I'm running! Assert your assumptions and all that, right?

I added a little helper in my Tests:

private bool InDocker { get { return Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER") == "true";} }

Since I'm using XUnit, I decided to bring in the very useful helper Xunit.SkippableFact!

For example:

[SkippableFact]
public void LoadTheMainPageAndCheckTitle()
{
    Skip.If(InDocker, "We are in Docker, y'all!");
    Browser.Navigate().GoToUrl(Server.RootUri);
    Assert.StartsWith("Hanselminutes Technology Podcast - Fresh Air and Fresh Perspectives for Developers", Browser.Title);
}

SkippableFact lets me skip tests for basically any reason. I could help if I'm in Docker, as I'm doing here. Or, given that Selenium Tests will throw an "OpenQA.Selenium.WebDriverException" when it can't find the Selenium Web Driver, I could also do this, skipping because a specific Exception was through. Note this means it's a SKIP not a FAIL.

[SkippableFact(typeof(OpenQA.Selenium.WebDriverException))]
public void KevinScottTestThenGoHome()
{
   Browser.Navigate().GoToUrl(Server.RootUri + "/631/how-do-you-become-a-cto-with-microsofts-cto-kevin-scott");

   var headerSelector = By.TagName("h1");
   var link = Browser.FindElement(headerSelector);
   link.Click();
}

The results look like this:

Total tests: 22. Passed: 18. Failed: 0. Skipped: 4.
Test Run Successful.
Test execution time: 8.7878 Seconds

You could choose to Skip Tests if a backend, 3rd party API, or DB was down, but you still wanted to test as much as possible. I'm pretty happy with the results!


New Sponsor! Never type an invoice again! With DocSight OCR by ActivePDF, you’ll extract data from bills, invoices, PO’s & other documents using zonal data capture technology. Achieve Digital Transformation today!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
July 02, 2018 20:22
At my office, we do something similar using the XUnit native [Trait] attribute and the --filter argument on the commandline.


[Trait("Category", "Integration")]
public void LoadTheMainPageAndCheckTitle()
{
Browser.Navigate().GoToUrl(Server.RootUri);
Assert.StartsWith("Hanselminutes Technology Podcast - Fresh Air and Fresh Perspectives for Developers", Browser.Title);
}


Then for the test run, you do:


dotnet test --filter Category!=Integration


Running selective unit tests

SkippableFact looks like a cool project though, and has some extra functionality that you can't get from a pure filter by trait.
July 04, 2018 7:36
This is awesome! I had no idea DotNetCliToolReference was a thing. I have a project dotnet-docker-deploy for orchestrating the deployment of a Dockerfile that would benefit from this.
July 04, 2018 18:48
các tư thế quan hệ tình dục vợ chồng giúp nàng lên đỉnh sướng nhất nhanh chóng nhất mang lại nhiều điều gợi cảm nhất cho cuộc sống mang lại nhiều điều kiện đánh giá nhất mang lại hiệu quả cho cuộc sống mang lại

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.