Scott Hanselman

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

June 29, '18 Comments [5] 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
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb
Monday, 02 July 2018 16:22:17 UTC
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.
Joe G
Wednesday, 04 July 2018 03:36:06 UTC
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.
Wednesday, 04 July 2018 14:48:57 UTC
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
Tuesday, 10 July 2018 12:23:46 UTC
收藏了,赞赞。
Tuesday, 10 July 2018 12:24:27 UTC
感谢楼主的分享,赞赞。
Comments are closed.

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