Software I enhancements, part 2 – CI and testing

I’ve always been interested in automated testing ever since I learned about it. However, it’s really hard to do, and the difficulty has always been a barrier to doing things right. I wanted to remove those barriers with this project so I decided I’d start right this time and go with TDD and CI at the start. I started looking into CI providers for open-source projects, and decided to start with Appveyor.

Appveyor is the self-proclaimed “#1 Continuous Delivery service for Windows”, and it wasn’t hard to get started working with their service. All I had to do was sign in with Github and give it access to my repositories, then I could start running builds on their servers. It was so easy, in fact, that a build was kicked off just a few minutes after I committed the boilerplate from the last part in this series. Surprisingly, the build failed with the message that it couldn’t decide which solution to use when building. That was easy enough to fix with an appveyor.yml file:

  project: C482.sln

That satisfied the valid solution requirement, but after another build was kicked off it complained about the csproj file not being properly formatted for MSBuild 2003. That made sense to me since I was using dotnetcore 1.1 instead of .NET framework. So I added a build environment variable for Visual Studio 2017 hoping that it would use dotnetcore by default:

image: Visual Studio 2017

  project: C482.sln

Sure enough, my project started to use dotnetcore to build the solution. However, I was getting missing reference errors left and right. After researching it a little bit I found a blog that showed how to use appveyor to build dotnetcore apps. I’m going to be honest and tell you that I did what no programmer should really ever do and just copied and pasted the solution without taking the time to really understand it:

version: 1.0.{build}
os: Windows Server 2012 R2
image: Visual Studio 2017
  project: C482.sln
  verbosity: minimal
 - cmd: nuget sources add -Name -Source
 - ps: "&{$Branch='dev';iex ((new-object net.webclient).DownloadString(''))}"
 - ps: dnvm install 1.0.0-rc1-update1
 - ps: dnvm use 1.0.0-rc1-update1
 - ps: dnu restore

Okay, okay, I did go back and figure it out eventually. It sets up a nuget repo, downloads dnvm (something to look into in the future for sure), installs dotnetcore v.1.0.0-rc1-update1 and sets it as the default version to use. Then, before building the project, it runs a package restore from nuget. It’s pretty straightforward, but ultimately didn’t work in my case. I realized that most of my builds were happening in Docker containers anyway, and Appveyor didn’t have support for Docker (at least not first class support) at the time I was writing this. Appveyor is great for .NET framework apps, but Microsoft seems to be moving to a Linux first model for dotnetcore. I decided to move to instead for it’s docker first support as detailed here and here.

Upon closer inspection of the boilerplate, I realized that a docker-compose file had been written for CI in the dotnet/Docker boilerplate. I initially tried to use it in a stock manner, but I had a little bit of trouble remembering/learning the compose syntax. I decided to use docker-compose up instead of pulling the container before running docker-compose start. I could see building a container before calling docker-compose up, but in this case we’re just pulling Microsoft’s dotnet container. Here’s what my final .travis.yml file looked like:

sudo: required

language: csharp

 - docker

 - docker-compose -f up

The docker-compose file looks like this:

version: '2'

    image: microsoft/aspnetcore-build:1.0-1.1
      - .:/src
    working_dir: /src
    command: /bin/bash -c "dotnet restore ./C482.sln && dotnet publish ./C482.sln -c Release -o ./obj/Docker/publish"

It passed! A programmer’s favorite symbol is the green checkmark.

This compose file doesn’t actually do much, and it seems to be more for deployment than testing. So, in the next post I’m going to detail installing xUnit and writing our first tests.