# Run all tests
dotnet test
# Run with coverage
dotnet test --collect:"XPlat Code Coverage"
# Run specific test
dotnet test --filter "FullyQualifiedName~GlobalVarTests"
# Run in watch mode (auto-rerun on changes)
dotnet watch test- Open Test Explorer (beaker icon in sidebar)
- Click "Run All Tests" or run individual tests
- View results inline
# Install report generator (one-time)
dotnet tool install -g dotnet-reportgenerator-globaltool
# Run tests with coverage
dotnet test --collect:"XPlat Code Coverage" --results-directory ./TestResults
# Generate HTML report
reportgenerator -reports:"./TestResults/**/coverage.cobertura.xml" -targetdir:"coveragereport" -reporttypes:Html
# Open report
start coveragereport/index.html # Windows- Target: 70%+ overall coverage
- Critical code: 90%+ (GlobalVar utilities, Settings parsing)
- UI code: 50%+ (forms are harder to test)
[TestMethod]
public void MethodName_Scenario_ExpectedBehavior()
{
// Arrange - Set up test data
var input = "test data";
// Act - Execute the method
var result = MyClass.MyMethod(input);
// Assert - Verify the result
result.Should().Be("expected");
}// Better readability than Assert.AreEqual
result.Should().NotBeNull();
result.Should().Be(expected);
result.Should().Contain("substring");
result.Should().HaveCount(5);
list.Should().ContainInOrder("a", "b", "c");// Mock file system operations
var mockFileSystem = new Mock<IFileSystem>();
mockFileSystem.Setup(fs => fs.ReadAllText(It.IsAny<string>()))
.Returns("mock content");GlobalVar utility methods:
-
SplitWords()- string parsing -
IsInField()- rectangle collision detection -
GetSetting()- settings file parsing -
Log()- logging functionality -
SendRemoteCommand()- TCP communication (with mocks) -
UpdateColors()- color conversion -
SetCentered()- screen positioning calculations
Data Classes:
-
Combinationrecord - keyword/filepath pairs -
WwwBrowserrecord - browser configurations -
WebCombovalidation - website combo validation
Settings:
-
Settings.ScanSettings()- parsing settings.ini -
Settings.WriteSettings()- writing settings - Color conversion (hex to Color)
File Operations (use temp files):
-
PopulateCombos()- reading shortcuts.txt -
PopulateWebSites()- reading websites.txt - Settings file I/O
Command Processing:
-
HardCodedCombos()- command regex matching - Web search URL building
UI/Forms (requires UI testing framework):
- Timer-based animations
- Form visibility logic
- Mouse cursor detection
- Multi-monitor support
System Integration:
- Process launching (
GlobalVar.Run()) - TCP server communication
- Sound playback
[TestClass]
public class GlobalVarTests
{
[TestMethod]
public void GetSetting_ValidLineNumber_ReturnsSettingValue()
{
// Arrange
string tempFile = TestHelpers.CreateTempSettingsFile(
TestHelpers.GetSampleSettingsContent()
);
try
{
// Act
string? result = GlobalVar.GetSetting(0);
// Assert
result.Should().NotBeNull();
result.Should().Contain("=");
}
finally
{
TestHelpers.CleanupTempFile(tempFile);
}
}
[TestMethod]
public void SendRemoteCommand_ValidCommand_SendsSuccessfully()
{
// Arrange
var mockSocket = new Mock<Socket>();
// ... setup mock
// Act & Assert
// Test TCP sending without actual network
}
}[TestClass]
public class SettingsTests
{
[TestMethod]
public void ScanSettings_ValidFile_ParsesCorrectly()
{
// Test color parsing
// Test boolean parsing
// Test path parsing
}
[TestMethod]
[DataRow("#FF0000", 255, 0, 0)]
[DataRow("#00FF00", 0, 255, 0)]
[DataRow("#0000FF", 0, 0, 255)]
public void ColorParsing_ValidHex_ConvertsCorrectly(
string hex, int r, int g, int b)
{
var color = ColorTranslator.FromHtml(hex);
color.R.Should().Be(r);
color.G.Should().Be(g);
color.B.Should().Be(b);
}
}The .github/workflows/dotnet-ci.yml file runs automatically on:
- Every push to
master/main/develop - Every pull request
What it does:
- ✅ Builds the project
- ✅ Runs all tests
- ✅ Generates code coverage report
- ✅ Comments coverage % on PRs
- ✅ Uploads to Codecov (if configured)
-
Codecov (optional, free for public repos):
- Sign up at https://codecov.io with GitHub
- Add your repo
- Get token from Settings → Copy token
- Add to GitHub: Settings → Secrets → New secret
- Name:
CODECOV_TOKEN - Value: (paste token)
- Name:
-
Coverage Badge: Add to README.md:
[](https://codecov.io/gh/YOUR_USERNAME/DesktopShell)
# .git/hooks/pre-commit
#!/bin/sh
dotnet test --no-build
if [ $? -ne 0 ]; then
echo "Tests failed. Commit aborted."
exit 1
fi- GlobalVar static methods
- Settings parsing
- Data records validation
- Regex matching
- URL building
- File parsing
- End-to-end command flows
- File I/O with temp files
- Mock process launching
- Form visibility logic (without actual UI)
- Animation state machine
- Mock timer callbacks
- Test naming:
MethodName_Scenario_ExpectedResult - One assert per test: Focus on one behavior
- Use test helpers: Reduce duplication
- Clean up resources: Use
finallyblocks - Mock external dependencies: File system, network, processes
- Test edge cases: null, empty, negative values
- Test error conditions: Exceptions, invalid input