Testing with Data

It’s not a coincidence that this is coming off the heels of Dave Paquette’s post on GenFu and Simon Timms’ post on source control for databases in the same way it was probably not a coincidence that Hollywood released three body-swapping movies in the 1987-1988 period (four if you include Big).

I was asked recently for some advice on generating data for use with integration and UI tests. I already have some ideas but asked the rest of the Western Devs for some elucidation. My tl;dr version is the same as what I mentioned in our discussion on UI testing: it’s hard. But manageable. Probably.

The solution needs to balance a few factors:

  • Each test must start from a predictable state
  • Creating that predictable state should be fast as possible
  • Developers should be able to figure out what is going on by reading the test

The two options we discussed both assume the first factor to be immutable. That means you either clean up after yourself when the test is finished or you wipe out the database and start from scratch with each test. Cleaning up after yourself might be faster but has more moving parts. Cleaning up might mean different things depending on which step you’re in if the test fails.

So given that we will likely re-create the database from scratch before each and every test, there are two options. My current favourite solution is a hybrid of the two.

Maintain a database of known data

In this option, you have a pre-configured database. Maybe it’s a SQL Server .bak file that you restore before each test. Maybe it’s a GenerateDatabase method that you execute. I’ve done the latter on a Google App Engine project, and it works reasonably well from an implementation perspective. We had a class for each domain aggregate and used dependency injection. So adding a new test customer to accommodate a new scenario was fairly simple. There are a number of other ways you can do it, some of which Simon touched on in his post.

We also had it set up so that we could create only the customer we needed for that particular test if we needed to. That way, we could use a step likeGiven I'm logged into 'Christmas Town' and it would set up only that data.

There are some drawbacks to this approach. You still need to create a new class for a new customer if you need to do something out of the ordinary. And if you need to do something only slightly out of the ordinary, there’s a strong tendency to use an existing customer and tweak its data ever so slightly to fit your test’s needs, other tests be damned. With these tests falling firmly in the long-running category, you don’t always find out the effects of this until much later.

Another drawback: it’s not obvious in the test exactly what data you need for that specific test. You can accommodate this somewhat just with a naming convention. For example,Given I'm logged into a company from India, if you’re testing how the app works with rupees. But that’s not always practical. Which leads us to the second option.

Create an API to set up the data the way you want

Here, your API contains steps to fully configure your database exactly the way you want. For example:

Given I have a company named "Christmas Town" owned by "Jack Skellington"
And I have 5 product categories
And I have 30 products
And I have a customer


You can probably see the major drawback already. This can become very verbose. But on the other hand, you have the advantage of seeing exactly what data is included which is helpful when debugging. If your test data is wrong, you don’t need to go mucking about in your source code to fix it. Just update the test and you’re done.

Also note the lack of specifics in the steps. Whenever possible, I like to be very vague when setting up my test data. If you have a good framework for generating test data, this isn’t hard to do. And it helps uncover issues you may not account for using hard-coded data (as anyone named D’Arcy O’Toole can probably tell you).

Loading up your data with a granular API isn’t realistic which is why I like the hybrid solution. By default, you pre-load your database with some common data, like lookup tables with lists of countries, currencies, product categories, etc. Stuff that needs to be in place for the majority of your tests.

After that, your API doesn’t need to be that granular. You can use something likeGiven I have a basic company which will create the company, add an owner and maybe some products and use that to test the process for creating an order. Under the hood, it will probably use the specific steps.

One reason I like this approach: it hides only the details you don’t care about. When you sayGiven I have a basic company and I change the name to "Rick's Place", that tells me, “I don’t care how the company is set up but the company name is important”. Very useful to help narrow the focus of the test when you’re reading it.

This approach will understandably lead to a whole bunch of different methods for creating data of various sizes and coarseness. And for that you’ll need to…

Maintain test data

Regardless of your method, maintaining your test data will require constant vigilance. In my experience, there is a tremendous urge to take shortcuts when it comes to test data. You’ll re-use a test company that doesn’t quite fit your scenario. You’ll alter your test to fit the data rather than the other way around. You’ll duplicate a data setup step because your API isn’t discoverable.

Make no mistake, maintaining test data is work. It should be treated with the same respect and care as the rest of your code. Possibly more so since the underlying code (in whatever form it takes) technically won’t be tested. Shortcuts and bad practices should not be tolerated and let go because “it’s just test data”. Fight the urge to let things slide. Call it out as soon as you see it. Refactor mercilessly once you see opportunities to do so.

Don’t be afraid to flip over a table or two to get your point across.

– Kyle the Unmaintainable

Posted in Uncategorized | Leave a comment

Running a .NET app against a Postgres database in Docker

Some days/weeks/time ago, I did a presentation at MeasureUP called “Docker For People Who Think Docker Is This Weird Linux Thing That Doesn’t Impact Me”. The slides for that presentation can be found here and the sample application here.

Using the sample app with PostgreSQL

The sample application is just a plain ol’ .NET application. It is meant to showcase different ways of doing things. One of those things is data access. You can configure the app to access the data from SQL storage, Azure table storage, or in-memory. By default, it uses the in-memory option so you can clone the app and launch it immediately just to see how it works.


Quick summary: Calgary, Alberta hosts an annual event called the Calgary Stampede. One of the highlights of the 10-ish day event is the pancake breakfast, whereby dozens/hundreds of businesses offer up pancakes to people who want to eat like the pioneers did, assuming the pioneers had pancake grills the size of an Olympic swimming pool.

The sample app gives you a way to enter these pancake breakfast events and each day, will show that day’s breakfasts on a map. There’s also a recipe section to share pancake recipes but we won’t be using that here.

To work with Docker we need to set the app up to use a data access mechanism that will work on Docker. The sample app supports Postgres so that will be our database of choice. Our first step is to get the app up and running locally with Postgres without Docker. So, assuming you have Postgres installed, find the ContainerBuilder.cs file in the PancakeProwler.Web project. In this file, comment out the following near the top of the file:

// Uncomment for InMemory Storage

And uncomment the following later on:

// Uncomment for PostgreSQL storage

This configures the application to use Postgres. You’ll also need to do a couple of more tasks:

  • Create a user in Postgres
  • Create a Pancakes database in Postgres
  • Update the Postgres connection string in the web project’s web.config to match the username and database you created

The first two steps can be accomplished with the following script in Postgres:




Save this to a file. Change the username/password if you like but be aware that the sample app has these values hard-wired into the connection string. Then execute the following from the command line:

psql -U postgres -a -f "C:\path\to\sqlfile.sql"

At this point, you can launch the application and create events that will show up on the map. If you changed the username and/or password, you’ll need to update the Postgres connection string first.

You might have noticed that you didn’t create any tables yet but the app still works. The sample is helpful in this regard because all you need is a database. If the tables aren’t there yet, they will be created the first time you launch the app.

Note: recipes rely on having a search provider configured. We won’t cover that here but I hope to come back to it in the future.

Next, we’ll switching things up so you can run this against Postgres running in a Docker container.

Switching to Docker

I’m going to give away the ending here and say that there is no magic. Literally, all we’re doing in this section is installing Postgres on another “machine” and connecting to it. The commands to execute this are just a little less click-y and more type-y.

The first step, of course, is installing Docker. At the time of writing, this means installing Docker Machine.

With Docker Machine installed, launch the Docker Quickstart Terminal and wait until you see an ASCII whale:

Docker Machine

If this is your first time running Docker, just know that a lightweight Linux virtual machine has been launched in VirtualBox on your machine. Check your Start screen and you’ll see VirtualBox if you want to investigate it but the docker-machine command will let you interact with it for many things. For example:

docker-machine ip default

This will give you the IP address of the default virtual machine, which is the one created when you first launched the Docker terminal. Make a note of this IP address and update the Postgres connection string in your web.config to point to it. You can leave the username and password the same:

<add name="Postgres" connectionString="server=;user id=Matt;password=moo;database=Pancakes" providerName="Npgsql" />

Now we’re ready to launch the container:

docker run --name my-postgres -e POSTGRES_PASSWORD=moo -p 5432:5432 -d postgres`

Breaking this down:

docker run Runs a docker container from an image
--name my-postgres The name we give the container to make it easier for us to work with. If you leave this off, Docker will assign a relatively easy-to-remember name like “floral-academy” or “crazy-einstein”. You also get a less easy-to-remember identifier which works just as well but is…less…easy-to-remember
-e POSTGRES_PASSWORD=moo The -e flag passes an environment variable to the container. In this case, we’re setting the password of the default postgres user
-p 5432:5432 Publishes a port from the container to the host. Postgres runs on port 5432 by default so we publish this port so we can interact with Postgres directly from the host
-d Run the container in the background. Without this, the command will sit there waiting for you to kill it manually
postgres The name of the image you are creating the container from. We’re using the official postgres image from Docker Hub.

If this is the first time you’ve launched Postgres in Docker, it will take a few seconds at least, possibly even a few minutes. It’s downloading the Postgres image from Docker Hub and storing it locally. This happens only the first time for a particular image. Every subsequent postgres container you create will use this local image.

Now we have a Postgres container running. Just like with the local version, we need to create a user and a database. We can use the same script as above and a similar command:

psql -h -U postgres -a -f "C:\path\to\sqlfile.sql"

The only difference is the addition of -h You should use whatever IP address you got above from the docker-machine ip default command here. For me, the IP address was

With the database and user created, and your web.config updated, we’ll need to stop the application in Visual Studio and re-run it. The reason for this is that the application won’t recognize that we’ve changed database so we need to “reboot” it to trigger the process for creating the initial table structure.

Once the application has been restarted, you can now create pancake breakfast events and they will be stored in your Docker container rather than locally. You can even launch pgAdmin (the Postgres admin tool) and connect to the database in your Docker container and work with it like you would any other remote database.

Next steps

From here, where you go is up to you. The sample application can be configured to use Elastic Searchfor the recipes. You could start an Elastic Search container and configure the app to search against that container. The principle is the same as with Postgres. Make sure you open both ports 9200 and 9300 and update the ElasticSearchBaseUri entry in web.config. The command I used in the presentation was:

docker run --name elastic -p 9200:9200 -p 9300:9300 -d elasticsearch

I also highly recommend Nigel Poulton’s Docker Deep Dive course on Pluralsight. You’ll need access to Linux either natively or in a VM but it’s a great course.

There are also a number of posts right here on Western Devs, including an intro to Docker for OSX, tips on running Docker on Windows 10, and a summary or two on a discussion we had on it internally.

Other than that, Docker is great for experimentation. Postgres and Elastic Search are both available pre-configured in Docker on Azure. If you have access to Azure, you could spin up a Linux VM with either of them and try to use that with your application. Or look into Docker Compose and try to create a container with both.

For my part, I’m hoping to convert the sample application to ASP.NET 5 and see if I can get it running in a Windows Server Container. I’ve been saying that for a couple of months but I’m putting it on the internet in an effort to make it true.

Posted in ASP.NET MVC, Docker, PostgreSQL, Presenting | Tagged , , , | Leave a comment

Windows Server Containers are coming whether you like it or not

After posting giddily on Docker in the Windows world recently, Microsoft released Windows Server 2016 Technical Preview 3 with container support. I’ve had a chance to play with it a little so let’s see where this goes…

It’s a preview

Like movie previews, this is equal parts exciting and frustrating. Exciting because you get a teaser of things to come. Frustrating because you just want it to work now. And extra frustration points for various technical issues I’ve run into that, I hope, are due to the “technical preview” label.

For example, installing container support into an existing VM is mind-numbingly slow. Kudos to the team for making it easy to install but at the point where you run ContainerSetup.ps1, be prepared to wait for, by my watch, at least 45 minutes without any visual indication that something is happening. The only reason I knew something was happening is because I saw the size of the VM go up (slowly) on my host hard drive. This is on a 70Mbps internet connection so I don’t think this can be attributed to “island problems” either.

I’ve heard tell of issues setting up container support in a Hyper-V VM as well. That’s second-hand info as I’m using Fusion on a Mac rather than Hyper-V. If you run into problems setting it up on Hyper-V, consider switching to the instructions for setting up containers on non-Hyper-V VMs instead.

There’s also the Azure option. Microsoft was gracious enough to provide an Azure image for Windows Server 2016 pre-configured with container support. This works well if you’re on Azure and I was able to run the nginx tutorial on it with no issues. I had less success with the IIS 10 tutorial even locally. I could get it running but was not able to create a new image based on the container I had.

It’s also a start

Technical issues aside, I haven’t been this excited about technology in Windows since…ASP.NET MVC, I guess, if my tag cloud is to be believed. And since this is a technical preview designed to garner feedback, here’s what I want to see in the Windows container world

Docker client and PowerShell support

I love that I can use the Docker client to work with Windows containers. I can leverage what I’ve already learned with Docker in Linux. But I also love that I can spin up containers with PowerShell so I don’t need to mix technologies in a continuous integration/continuous deployment environment if I already have PowerShell scripts set up for other aspects of my process.

Support for legacy .NET applications

I can’t take credit for this. I’ve been talking with Gabriel Schenker about containers a lot lately and it was he who suggested they need to have support for .NET 4, .NET 3.5, and even .NET 2.0. It makes sense though. There are a lot of .NET apps out there and it would be a shame if they couldn’t take advantage of containers.

Smooth local development

Docker Machine is great for getting up and running fast on a local Windows VM. To fully take advantage of containers, devs need to be able to work with them locally with no friction, whether that means a Windows Container version of Docker Machine or the ability to work with containers natively in Windows 10.

ARM support

At Western Devs, we have a PowerShell script that will spin up a new Azure Linux virtual machine, install docker, create a container, and run our website on it. It goes without saying (even though I’m saying it) that I’d like to do the same with Windows containers.

Lots of images out of the gate

I’d like to wean myself off VMs a little. I picture a world where I have one base VM and I use various containers for the different pieces of the app I’m working on. E.g. A SQL Server container, an IIS container, an ElasticSearch container, possibly even a Visual Studio container. I pick and choose which containers I need to build up my dev environment and use just one (or a small handful) of VMs.

In the meantime, I’m excited enough about Windows containers that I hope to incorporate a small demo with them in my talk at MeasureUP in a few scant weeks so if you’re in the Austin area, come on by to see it.

It is a glorious world ahead in this space and it puts a smile on this hillbilly’s face to see it unfold.

Kyle the Barely Contained

Posted in Docker | Tagged , | 5 Comments

Docker on Western Devs

In a month, I’ll be attempting to hound my share of glory at MeasureUP with a talk on using Docker for people who may not think it impacts them. In it, I’ll demonstrate some uses of Docker today in a .NET application. As I prepare for this talk, there’s one thing we Western Devs have forgotten to talk about. Namely, some of us are already using Docker regularly just to post on the site.

Western Devs uses Jekyll. Someone suggested it, I tried it, it worked well, decision was done. Except that it doesn’t work well on Windows. It’s not officially supported on the platform and while there’s a good guide on getting it running, we haven’t been able to do so ourselves. Some issue with a gem we’re using and Nokogiri and lib2xml and some such nonsense.

So in an effort to streamline things, Amir Barylko create a Docker image. It’s based on the Ruby base image (version 2.2). After grabbing the base image, it will:

  • Install some packages for building Ruby
  • Install the bundler gem
  • Clone the source code into the /root/jekyll folder
  • Run bundle install
  • Expose port 4000, the default port for running Jekyll

With this in place, Windows users can run the website locally without having to install Ruby, Python, or Jekyll. The command to launch the container is:

docker run -t -p 4000:4000 -v //c/path/to/code:/root/jekyll abarylko/western-devs:v1 sh -c 'bundle install && rake serve'

This will:

  • create a container based on the abarylko/western-devs:v1 image
  • export port 4000 to the host VM
  • map the path to the source code on your machine to /root/jekyll in the container
  • run bundle install && rake serve to update gems and launch Jekyll in the container

To make this work 100%, you also need to expose port 4000 in VirtualBox so that it’s visible from the VM to the host. Also, I’ve had trouble getting a container working with my local source located anywhere except C:\Users\mysuername. There’s a permission issue somewhere in there where the container appears to successfully map the drive but can’t actually see the contents of the folder. This manifests itself in an error message that says Gemfile not found.

Now, Windows users can navigate to localhost:4000 and see the site running locally. Furthermore, they can add and make changes to their posts, save them, and the changes will get reflected in the browser. Eventually, that is. I’ve noticed a 10-15 second delay between the time you press Save to the time when the changes actually get reflected. Haven’t determined a root cause for this yet. Maybe we just need to soup up the VM.

So far, this has been working reasonably well for us. To the point, where fellow Western Dev, Dylan Smith has automated the deployment of the image to Azure via a Powershell script. That will be the subject of a separate post. Which will give me time to figure out how the thing works.


Posted in Docker | Tagged , | 2 Comments

Docker is coming whether you like it or not

I’m excited about Docker. Unnaturally excited, one might say. So much so that I’ll be talking about it at MeasureUp this September.

In the meantime, I have to temper my enthusiasm for the time being because Docker is still a Linux-only concern. Yes, you can run Docker containers on Windows but only Linux-based ones. So no SQL Server and no IIS.

But you can’t stop a hillbilly from dreaming of a world of containers. So with a grand assumption that you know what Docker is roughly all about, here’s what this coder of the earth meditates on, Docker-wise, before going to sleep.


Microservices are a hot topic these days. We’ve talked about them at Western Devs already and Donald Belcham has a good and active list of resources. Docker is an eerily natural fit for microservices so much so that one might think it was created specifically to facilitate the architecture. You can package your entire service into a container and deploy it as a single package to your production server.

I don’t think you can understate the importance of a technology like Docker when it comes to microservices. Containers are so lightweight and portable, you just naturally gravitate to the pattern through normal use of containers. I can see a time in the near future where it’s almost negligent not to use microservices with Docker. At least in the Windows world. This might already be the case in Linux.

Works On My Machine

Ah, the crutch of the developer and the bane of DevOps. You set it up so nicely on your machine, with all your undocumented config entries and custom permissions and the fladnoogles and the whaztrubbets and everything else required to get everything perfectly balanced. Then you get your first bug from QA: can’t log in.

But what if you could test your deployment on the exact same image that you deployed to? Furthermore, what if, when a bug came in that you can’t reproduce locally, you could download the exact container where it was occurring? NO MORE EXCUSES, THAT’S WHAT!

Continuous Integration Build Agents

On one project, we had a suite of UI tests which took nigh-on eight hours in TeamCity. We optimized as much as we could and got it down to just over hours. Parallelizing them would have been a lot of effort to set up the appropriate shared resources and configurations. Eventually, we set up multiple virtual machines so that the entire parallel test run could finish in about an hour and a half. But the total test time of all those runs sequentially is now almost ten hours and my working theory is that it’s due to the overhead of the VMs on the host machine.

Offloading services

What I mean here is kind of like microservices applied to the various components of your application. You have an application that needs a database, a queue, a search components, and a cache. You could spin up a VM and install all those pieces. Or you could run a Postgres container, a RabbitMQ container, an ElasticSearch container, and a Redis container and leave your machine solely for the code.

When it comes right down to it, Docker containers are basically practical virtual machines. I’ve used VMs for many years. When I first started out, it was VMWare WorkStation on Windows. People that are smarter than me (including those that would notice that I should have said, “smarter than I”) told me to use them. “One VM per client” they would say. To the point that their host was limited to checking email and Twitter clients.

I tried that and didn’t like it. I didn’t like waiting for the boot process on both the host and each client and I didn’t like not taking full advantage of my host’s hardware on the specific client I happened to be working on at that moment.

But containers are lightweight. Purposefully so. Delightfully so. As I speak, the overworked USB drive that houses my VMs is down to 20 GB of free space. I cringe at the idea of having to spin up another one. But the idea of a dozen containers I can pick and choose from, all under a GB? That’s a development environment I can get behind.

Alas, this is mostly a future world I’m discussing. Docker is Linux only and I’m in the .NET space. So I have to wait until either: a) ASP.NET is ported over to Linux, or b) Docker supports Windows-based containers. And it’s a big part of my excitement that BOTH of those conditions will likely be met within a year.

In the meantime, who’s waiting? Earlier, I mentioned Postgres, Redis, ElasticSearch, and RabbitMQ. Those all work with Windows regardless of where they’re actually running. Furthermore, Azure already has pre-built containers with all of these.

Much of this will be the basis of my talk at the upcoming MeasureUP conference next month. So…uhhh….don’t read this until after that.

Posted in Clear Measure, Continuous Integration, Docker, Microservices, Presenting, TeamCity, UI Testing | Tagged , , , , | 3 Comments