Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TEST-0007 Add stryker step #271

Merged
merged 8 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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/[email protected]
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
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();
}
}
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());
}