Skip to content

Commit

Permalink
TEST-0007 Add stryker step (#271)
Browse files Browse the repository at this point in the history
<!--- Provide a general summary of your changes in the Title above -->

## Description 💬
<!--- Describe your changes in detail -->

## Motivation and Context 🥅
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->

## How has this been tested? 🧪
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, tests ran to see how
-->
<!--- your change affects other areas of the code, etc. -->
- [x] Local build ⚒️
- [x] Local tests 🧪
- [ ] (optional) Local run and endpoint tested in swagger 🚀

## Screenshots (if appropriate) 💻

## Types of changes 🌊
<!--- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)

## Checklist ☑️

<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're
here to help! -->
- [x] The pull request title starts with the jira case number (when
applicable), e.g. "TEST-1234 Add some feature"
- [x] The person responsible for following up on requested review
changes has been assigned to the pull request
- [x] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.

## Highly optional checks, only use these if you have a reason to do so
✔️

- [ ] This PR changes the database so I have added the *create-diagram*
label to assist reviewers with a db diagram
- [ ] This PR changes platform or backend and I need others to be able
to test against these changes before merging to dev, so I have added the
*deploy-azure* label to deploy before merging the PR

## Checklist for the approver ✅

- [ ] I've checked the files view for spelling issues, code quality
warnings and similar
- [ ] I've waited until all checks have passed (green check/without
error)
- [ ] I've checked that only the intended files are changed
  • Loading branch information
hwinther authored Sep 24, 2024
1 parent fe04193 commit 5a0c2e3
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 35 deletions.
45 changes: 34 additions & 11 deletions .github/workflows/backend-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -195,15 +195,38 @@ jobs:
comment-identifier: "${{ env.WORKFLOW_SHORT_NAME }}-CodeCoverageSummary"
comment-content: ${{ steps.code-coverage-summary.outputs.markdown }}

- name: Inspect code
uses: muno92/resharper_inspectcode@v1
if: ${{ github.event_name == 'pull_request' }}
- name: Stryker
id: stryker
run: |
dotnet stryker --reporter "html" --reporter "json" --reporter "markdown" --solution Backend.sln --output StrykerOutput
cp -r StrykerOutput/reports StrykerReports
cat StrykerReports/mutation-report.md >> $GITHUB_STEP_SUMMARY
echo "markdown<<EOF" >> $GITHUB_OUTPUT
cat StrykerReports/mutation-report.md >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- uses: actions/upload-artifact@v4
with:
workingDirectory: ${{ env.BACKEND_SOLUTION_PATH }}
solutionPath: Backend.sln
dotnetVersion: ${{ env.DOTNET_VERSION }}
failOnIssue: false
solutionWideAnalysis: true
include: |
**.cs
ignoreIssueType: PropertyCanBeMadeInitOnly.Global
name: StrykerReports
path: ${{ env.BACKEND_SOLUTION_PATH }}/StrykerReports

- name: "Create or Update PR Comment"
uses: im-open/update-pr-comment@v1.2.2
if: ${{ always() && github.event_name == 'pull_request' }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
comment-identifier: "${{ env.WORKFLOW_SHORT_NAME }}-Stryker"
comment-content: ${{ steps.stryker.outputs.markdown }}

# - name: Inspect code
# uses: muno92/resharper_inspectcode@v1
# if: ${{ github.event_name == 'pull_request' }}
# with:
# workingDirectory: ${{ env.BACKEND_SOLUTION_PATH }}
# solutionPath: Backend.sln
# dotnetVersion: ${{ env.DOTNET_VERSION }}
# failOnIssue: false
# solutionWideAnalysis: true
# include: |
# **.cs
# ignoreIssueType: PropertyCanBeMadeInitOnly.Global
24 changes: 24 additions & 0 deletions tests/backend/WebApi.Tests/Controllers/BloggingControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public async Task GetBlogs_ReturnsListOfBlogs()
var returnedBlogs = okResult.Value as IEnumerable<BlogDto>;
Assert.That(returnedBlogs, Is.Not.Null);
Assert.That(returnedBlogs.Count(), Is.EqualTo(2));
_loggerMock.VerifyLog(LogLevel.Information, Times.Once(), "GetBlogs was called");
_loggerMock.VerifyNoError();
}

[Test]
Expand All @@ -66,6 +68,9 @@ public async Task GetBlog_ValidId_ReturnsBlog()
Assert.That(returnedBlog.Title, Is.EqualTo(MockBlog.Title));
Assert.That(returnedBlog.Url, Is.EqualTo(MockBlog.Url));
});

_loggerMock.VerifyLog(LogLevel.Information, Times.Once(), "GetBlog was called with id 1");
_loggerMock.VerifyNoError();
}

[Test]
Expand All @@ -80,6 +85,8 @@ public async Task GetBlog_InvalidId_ReturnsNotFound()

// Assert
Assert.That(result.Result, Is.InstanceOf<NotFoundResult>());
_loggerMock.VerifyLog(LogLevel.Information, Times.Once(), "GetBlog was called with id 1");
_loggerMock.VerifyNoError();
}

[Test]
Expand Down Expand Up @@ -113,6 +120,9 @@ public async Task PostBlog_NoId_StoresBlog()
Assert.That(returnedBlog.Title, Is.EqualTo(MockBlog.Title));
Assert.That(returnedBlog.Url, Is.EqualTo(MockBlog.Url));
});

_loggerMock.VerifyLog(LogLevel.Information, Times.Once(), "PostBlog was called");
_loggerMock.VerifyNoError();
}

[Test]
Expand All @@ -127,6 +137,8 @@ public async Task PostBlog_InvalidId_ReturnsNotFound()

// Assert
Assert.That(result.Result, Is.InstanceOf<NotFoundResult>());
_loggerMock.VerifyLog(LogLevel.Information, Times.Once(), "PostBlog was called");
_loggerMock.VerifyNoError();
}

[Test]
Expand All @@ -152,6 +164,8 @@ public async Task GetPosts_ReturnsListOfPosts()
var returnedPosts = okResult.Value as IEnumerable<PostDto>;
Assert.That(returnedPosts, Is.Not.Null);
Assert.That(returnedPosts.Count(), Is.EqualTo(2));
_loggerMock.VerifyLog(LogLevel.Information, Times.Once(), "GetPosts was called with id 1");
_loggerMock.VerifyNoError();
}

[Test]
Expand All @@ -175,6 +189,9 @@ public async Task GetPost_ValidId_ReturnsPost()
Assert.That(returnedPost.BlogId, Is.EqualTo(MockPost.BlogId));
Assert.That(returnedPost.Content, Is.EqualTo(MockPost.Content));
});

_loggerMock.VerifyLog(LogLevel.Information, Times.Once(), "GetPost was called with id 1");
_loggerMock.VerifyNoError();
}

[Test]
Expand All @@ -189,6 +206,8 @@ public async Task GetPost_InvalidId_ReturnsNotFound()

// Assert
Assert.That(result.Result, Is.InstanceOf<NotFoundResult>());
_loggerMock.VerifyLog(LogLevel.Information, Times.Once(), "GetPost was called with id 1");
_loggerMock.VerifyNoError();
}

[Test]
Expand Down Expand Up @@ -223,6 +242,9 @@ public async Task PostPost_NoId_StoresPost()
Assert.That(returnedPost.BlogId, Is.EqualTo(MockPost.BlogId));
Assert.That(returnedPost.Content, Is.EqualTo(MockPost.Content));
});

_loggerMock.VerifyLog(LogLevel.Information, Times.Once(), "PostPost was called");
_loggerMock.VerifyNoError();
}

[Test]
Expand All @@ -237,5 +259,7 @@ public async Task PostPost_InvalidId_ReturnsNotFound()

// Assert
Assert.That(result.Result, Is.InstanceOf<NotFoundResult>());
_loggerMock.VerifyLog(LogLevel.Information, Times.Once(), "PostPost was called");
_loggerMock.VerifyNoError();
}
}
23 changes: 7 additions & 16 deletions tests/backend/WebApi.Tests/Controllers/ServiceControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public async Task Version_ReturnsOkResult()
// Assert
Assert.That(result, Is.InstanceOf<ActionResult<VersionInformation>>());
Assert.That(result.Result, Is.InstanceOf<OkObjectResult>());
_loggerMock.VerifyLog(LogLevel.Information, Times.Once(), "Version was called");
_loggerMock.VerifyNoError();
}

[Test]
Expand All @@ -50,6 +52,9 @@ public async Task Version_ReturnsVersionWithCorrectProperties()
Assert.That(version.EnvironmentName, Is.InstanceOf<string>());
Assert.That(version.InformationalVersion, Is.InstanceOf<string>());
});

_loggerMock.VerifyLog(LogLevel.Information, Times.Once(), "Version was called");
_loggerMock.VerifyNoError();
}

[Test]
Expand All @@ -65,21 +70,7 @@ public async Task Ping_ReturnsOkResult()
Assert.That(okResult.Value, Is.Not.Null);
Assert.That(okResult.Value, Is.AssignableFrom<GenericValue<string>>());
Assert.That(okResult.Value is GenericValue<string> {Value: "Ok"});
}

[Test]
public async Task Ping_LogsInformationMessage()
{
// Act
await _controller.Ping();

// Assert
_loggerMock.Verify(static logger => logger.Log(
It.Is<LogLevel>(static logLevel => logLevel == LogLevel.Information),
It.Is<EventId>(static eventId => eventId.Id == 0),
It.Is<It.IsAnyType>(static (@object, type) => @object.ToString() == "Ping was called" && type.Name == "FormattedLogValues"),
It.IsAny<Exception>(),
It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
Times.Once);
_loggerMock.VerifyLog(LogLevel.Information, Times.Once(), "Ping was called");
_loggerMock.VerifyNoError();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public async Task Get_ReturnsFiveWeatherForecasts()
var okResult = (OkObjectResult) result.Result;
Assert.That(okResult.Value, Is.Not.Null);
Assert.That(okResult.Value, Is.AssignableFrom<WeatherForecast[]>());
Assert.That(((WeatherForecast[]) okResult.Value).Count(), Is.EqualTo(5));
Assert.That(((WeatherForecast[]) okResult.Value).Length, Is.EqualTo(5));
}

[Test]
Expand All @@ -56,11 +56,19 @@ public async Task Get_ReturnsWeatherForecastsWithCorrectProperties()
var okResult = (OkObjectResult) result.Result;
Assert.That(okResult.Value, Is.Not.Null);
Assert.That(okResult.Value, Is.AssignableFrom<WeatherForecast[]>());
var expectedValueRange = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

foreach (var weatherForecast in (WeatherForecast[]) okResult.Value)
{
Assert.That(weatherForecast.Date, Is.InstanceOf<DateOnly>());
Assert.That(weatherForecast.TemperatureC, Is.InstanceOf<int>());
Assert.That(weatherForecast.TemperatureC, Is.LessThan(56));
Assert.That(weatherForecast.TemperatureC, Is.GreaterThan(-19));
Assert.That(weatherForecast.Summary, Is.InstanceOf<string>());
Assert.That(expectedValueRange, Contains.Item(weatherForecast.Summary));
}
}

Expand All @@ -71,12 +79,6 @@ public async Task Get_LogsInformationMessage()
await _controller.Get();

// Assert
_loggerMock.Verify(static logger => logger.Log(
It.Is<LogLevel>(static logLevel => logLevel == LogLevel.Information),
It.Is<EventId>(static eventId => eventId.Id == 0),
It.Is<It.IsAnyType>(static (@object, type) => @object.ToString() == "GetWeatherForecast was called" && type.Name == "FormattedLogValues"),
It.IsAny<Exception>(),
It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
Times.Once);
_loggerMock.VerifyLog(LogLevel.Information, Times.Once(), "GetWeatherForecast was called");
}
}
2 changes: 2 additions & 0 deletions tests/backend/WebApi.Tests/MockHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ public static void VerifyLog<T>(this Mock<ILogger<T>> loggerMock, LogLevel level
It.IsAny<Exception?>(),
It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
times);

public static void VerifyNoError<T>(this Mock<ILogger<T>> loggerMock) => loggerMock.VerifyLog(LogLevel.Error, Times.Never());
}

0 comments on commit 5a0c2e3

Please sign in to comment.