| name | test |
| description | Add or modify tests following project conventions. Use when asked to write tests, add test coverage, or fix failing tests.
|
| disable-model-invocation | true |
| argument-hint | <class or method to test> |
You are tasked with adding or modifying tests for: $ARGUMENTS
Follow this workflow in order:
-
Read existing tests to understand patterns. Good references:
PhotoManager.Tests/ directory structure
- Look for
*Tests.cs files matching the class you are testing
-
Follow this exact test structure:
[TestFixture]
public class ClassNameTests
{
private string? _assetsDirectory;
private string? _databaseDirectory;
private TestLogger<ClassName> _testLogger = new();
[OneTimeSetUp]
public void OneTimeSetUp()
{
_assetsDirectory = Path.Combine(TestContext.CurrentContext.TestDirectory, Directories.TEST_FILES);
_databaseDirectory = Path.Combine(_assetsDirectory, Directories.DATABASE_TESTS);
}
[SetUp]
public void SetUp()
{
_testLogger = new TestLogger<ClassName>();
}
[TearDown]
public void TearDown()
{
_testableAssetRepository?.Dispose();
TearDownHelper.DeleteTempDbDirectories(_databaseDirectory!);
_testLogger.LoggingAssertTearDown();
}
[Test]
public void MethodName_Situation_ExpectedResult()
{
_testLogger.AssertLogExceptions([], typeof(ClassName));
}
}
For static methods, use TestLogger<ClassNameTests> instead.
-
Using directives (NON-NEGOTIABLE):
- Check
PhotoManager.Tests/GlobalUsings.cs BEFORE adding any using
- Only add if the namespace is NOT already in global usings
- Unnecessary usings cause warnings and violate the zero-warnings policy
-
Use existing helpers (NEVER duplicate):
TestLogger<T> — for all logging verification
DirectoryHelper — for directory access control tests
ImageHelper — for creating invalid test images
- Constants in
PhotoManager.Tests.Unit.Constants namespace
-
Always verify log output in assertions:
_testLogger.AssertLogInfos(messages, typeof(Service))
_testLogger.AssertLogErrors(messages, typeof(Service))
_testLogger.AssertLogExceptions(exceptions, typeof(Service))
-
Always cleanup resources with finally blocks:
try
{
Directory.CreateDirectory(testDir);
}
finally
{
Directory.Delete(testDir, true);
}
-
Test naming (NON-NEGOTIABLE): MethodName_Situation_ExpectedResult
- Do NOT use BDD-style naming (Given/When/Should)
- Examples:
CalculateHash_ValidFile_ReturnsHashValue, DeleteAsset_AssetExists_RemovesAssetFromDatabase
-
100% coverage required for all new code — every branch, exception path, and edge case must be tested.
-
Cross-platform (NON-NEGOTIABLE): tests run on Windows, Linux, and macOS CI and must pass on all three.
On Linux/macOS \ is not a path separator and C:\... paths are not rooted, so Path.* calls diverge from Windows (e.g. Path.GetFileName(@"C:\a\b.png") returns the whole string).
- Never assert on a Windows-only absolute path routed through a
Path API.
Wrap it with PathHelper.ToPlatformAbsolutePath(@"C:\Dir"), or use PathHelper.ToResolvedConfigPath(...) for a path resolved by UserConfigurationService.
- Build expected paths with
Path.Combine exactly as production does — never Path.GetFullPath(@"...\name").
Reference test files with their exact on-disk case (Linux is case-sensitive).
- Opaque path strings (stored/returned verbatim and asserted against the same literal — config values, sync definitions) are portable as-is.
-
Build: Run dotnet build PhotoManager/PhotoManager.slnx and ensure zero warnings.
-
Run tests: Run dotnet test --filter "FullyQualifiedName~ClassName" PhotoManager/PhotoManager.slnx
using the appropriate class name filter.
Return a summary of tests added/modified with test results.