Free .Net Core Hosting on Heroku Through Docker and Github. Deploy With Unit-Tests

Logo_Upplabs
Upplabs
  • Date Published
  • Categories Blog
  • Reading Time 5-Minute Read

This guide is a follow up of the previous article about the deployment on free .net core hosting on Heroku through Docker and GitHub to configure continuous integration.

Today’s goal is to adjust the process, so that deployment occurs only when all unit tests have been passed. Also, the article raises the issue of monitoring the process of continuous integration. This article will be useful for startups and early-stage projects that seek for free hosting for their apps.


Looking for a digital agency? Post a Project


The Main Block

So, let’s go to the point and return to the project structure from the previous article.

The unit tests cover most of the code, and at the moment all tests are successful:

To add the unit test validation to your continuous integration process, you’ll need to correct the dockerfile a bit:

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src
COPY [“LimeHomeTest.Web/LimeHomeTest.Web.csproj”, “LimeHomeTest.Web/”]
COPY [“LimeHomeTest.Services/LimeHomeTest.Services.csproj”, “LimeHomeTest.Services/”]
COPY [“LimeHomeTest.Repository/LimeHomeTest.Repository.csproj”, “LimeHomeTest.Repository/”]
COPY [“LimeHomeTest.Dto/LimeHomeTest.Dto.csproj”, “LimeHomeTest.Dto/”]
COPY [“LimeHomeTest.Tests/LimeHomeTest.Tests.csproj”, “Tests/LimeHomeTest.Tests/”]
RUN dotnet restore “LimeHomeTest.Web/LimeHomeTest.Web.csproj”
COPY . .

# testing
WORKDIR /src/LimeHomeTest.Web
RUN dotnet build
WORKDIR /src/LimeHomeTest.Tests
RUN dotnet test

WORKDIR “/src/LimeHomeTest.Web”
RUN dotnet build “LimeHomeTest.Web.csproj” -c Release -o /app/build

FROM build AS publish
RUN dotnet publish “LimeHomeTest.Web.csproj” -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY –from=publish /app/publish .
CMD ASPNETCORE_URLS=http://*:$PORT dotnet LimeHomeTest.Web.dll

Compared to the previous version of dockerfile, here we can see that a copy of the project with tests was added to the image:

COPY [“LimeHomeTest.Tests/LimeHomeTest.Tests.csproj”, “Tests/LimeHomeTest.Tests/”]

As well as running the tests to check their transmission:

WORKDIR /src/LimeHomeTest.Web
RUN dotnet build
WORKDIR /src/LimeHomeTest.Tests
RUN dotnet test

Let’s run a local image creation through the PowerShell to make sure the image is created successfully:

docker build . -t lime-test -f Dockerfile

If the build was successful, you can make a commit and push it to the master branch.

That’s all the magic! The main work is done, but now, let’s take a break and make sure that everything works so smoothly like a Swiss watch.

Test

Case 1: All tests are successful

We’ve made all changes, all tests are still successful, so I make a push to the master branch and watch the deployment process. A push that has just been made should run the workflow (see the previous article) on GitHub.

And indeed, if you go to the repository on GitHub → Actions → commit → build,  you can see the  information about the image’s progress:

I wait for the process to be completed … and everything goes well! The next step is to deploy the image to Heroku. You can follow the process of deployment by the logs. To do this, go to your application – the More → View logs button.

So, in just a few clicks we have information about the deployment. We check the approximate time to understand whether our commit is currently processing to the log.

As you can see from the logs, the deployment has passed and now you can see the changes directly on the website.

Case 2: NOT all tests are successful

Everything is fine, but now we can make an experiment and break the unit tests a little bit just to check that the deployment will not happen.

One of my tests looks like this:

[TestMethod]
public void TestMethod_ParIsNull_ExpectedResult()
{
var ServiceMock = new Mock<IService>();
var LoggerMock = new Mock<ILogger<PropertiesController>>();
var sut = new PropertiesController(ServiceMock.Object, LoggerMock.Object);

var response = sut.TestMethod(null);

Assert.IsNotNull(response);
Assert.IsInstanceOfType(response, typeof(BadRequestObjectResult));
Assert.AreEqual((int)HttpStatusCode.BadRequest, (response as BadRequestObjectResult).StatusCode);
}

I will make some changes:

[TestMethod]
public void TestMethod_ParIsNull_ExpectedResult()
{
var ServiceMock = new Mock<IService>();
var LoggerMock = new Mock<ILogger<PropertiesController>>();
var sut = new PropertiesController(ServiceMock.Object, LoggerMock.Object);

var response = sut.TestMethod(null);

Assert.IsNotNull(response);
Assert.IsInstanceOfType(response, typeof(OkObjectResult));
Assert.AreEqual((int)HttpStatusCode.OK, (response as OkObjectResult).StatusCode);
}

This test will fail because in the Assert block we’ll expect to see OkObjectResult, whereas in fact with the input parameter null, we get   BadRequestObjectResult.

I do the usual procedure – a push to the master branch, then in the console on GitHub → Actions I follow the process of creating the image:

Build did not pass successfully. Why? Because it failed one test (yahoo!). If we look at the logs on Heroku, we will not see any records in the near term, which is quite logical: the image of the docker was not created, and therefore we didn’t reach the moment of its deployment on Heroku.

Win! The goal is achieved: if at least one test does not pass, deployment does not occur.

P.s. If you need any help with hosting your application or developing it and validating its idea or features – UppLabs is here to help!

P.p.s. Validate your startup idea and take a QUIZ to identify whether your business has some problems: Take a QUIZ

The original article was published here: https://upplabs.com/blog/free-net-core-hosting-on-heroku-through-docker-and-github-deploy-with-unit-tests/