Skip to content
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
2 changes: 1 addition & 1 deletion .cspell.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ words:
- Dema
- FileAssert
- fileassert
- mstest
- xunit
- Pandoc
- Qube
- reqstream
Expand Down
77 changes: 0 additions & 77 deletions .github/agents/repo-consistency.agent.md

This file was deleted.

6 changes: 3 additions & 3 deletions .github/standards/coding-principles.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ All code MUST follow literate programming principles:
matches design intent without reading the full codebase
- **Logical Separation**: Complex functions use block comments to separate and
describe logical steps within the implementation
- **Public Documentation**: All public interfaces have comprehensive documentation
because consumers and auditors rely on interface contracts for integration
and compliance verification
- **Full Symbol Documentation**: ALL symbols (public, protected, and private)
have comprehensive documentation because reviewers and auditors must verify
every implementation detail, not just the public interface
Comment thread
Malcolmnixon marked this conversation as resolved.
- **Clarity Over Cleverness**: Code should be immediately understandable by team members

## API Documentation
Expand Down
8 changes: 1 addition & 7 deletions .github/standards/csharp-language.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,12 @@ description: Follow these standards when developing C# source code.
globs: ["**/*.cs"]
---

# C# Language Development Standard

## Required Standards
# Required Standards

Read these standards first before applying this standard:

- **`coding-principles.md`** - Universal coding principles and quality gates

# File Patterns

- **Source Files**: `**/*.cs`

# API Documentation and Literate Coding Example

The example below demonstrates good XmlDoc API documentation combined with
Expand Down
120 changes: 38 additions & 82 deletions .github/standards/csharp-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,115 +4,71 @@ description: Follow these standards when developing C# tests.
globs: ["**/test/**/*.cs", "**/tests/**/*.cs", "**/*Tests.cs", "**/*Test.cs"]
---

# C# Testing Standards (MSTest)

This document defines standards for C# test development using
MSTest within Continuous Compliance environments.

## Required Standards
# Required Standards

Read these standards first before applying this standard:

- **`testing-principles.md`** - Universal testing principles and dependency boundaries
- **`csharp-language.md`** - C# language development standards

# C# AAA Pattern Implementation
# Package Reference

```csharp
[TestMethod]
public void ServiceName_MethodName_Scenario_ExpectedBehavior()
{
// Arrange: description of setup (omit if nothing to set up)
Every xUnit v3 test project requires the following package references for
`dotnet test` to discover and execute tests:

// Act: description of action (can combine with Assert when action occurs within assertion)
| Package | Purpose |
| ------- | ------- |
| `xunit.v3` | xUnit v3 framework (monolithic — includes assertions and fixtures) |
| `Microsoft.NET.Test.Sdk` | Required by the VSTest/`dotnet test` host for test discovery |
| `xunit.runner.visualstudio` | VSTest adapter that bridges xUnit v3 to `dotnet test` |
| `NSubstitute` | Mocking library |
Comment thread
Malcolmnixon marked this conversation as resolved.

// Assert: description of verification
}
```
Omitting `Microsoft.NET.Test.Sdk` or `xunit.runner.visualstudio` causes tests
to be silently undiscoverable by `dotnet test`.
Comment thread
Malcolmnixon marked this conversation as resolved.

# Test Naming Standards
# Test Style

Use descriptive test names because test names appear in requirements traceability matrices and compliance reports.
Test names appear in requirements traceability matrices — use the hierarchical
naming pattern, and follow AAA with labeled comments:

- **System tests**: `{SystemName}_{Functionality}_{Scenario}_{ExpectedBehavior}`
- **Subsystem tests**: `{SubsystemName}_{Functionality}_{Scenario}_{ExpectedBehavior}`
- **Unit tests**: `{ClassName}_{MethodUnderTest}_{Scenario}_{ExpectedBehavior}`
- **Descriptive Scenarios**: Clearly describe the input condition being tested
- **Expected Behavior**: State the expected outcome or exception

## Examples

- `UserValidator_ValidateEmail_ValidFormat_ReturnsTrue`
- `UserValidator_ValidateEmail_InvalidFormat_ThrowsArgumentException`
- `PaymentProcessor_ProcessPayment_InsufficientFunds_ReturnsFailureResult`

# Mock Dependencies

Mock external dependencies using NSubstitute (preferred) because tests must run in isolation to generate
reliable evidence.

- **Isolate System Under Test**: Mock all external dependencies (databases, web services, file systems)
- **Verify Interactions**: Assert that expected method calls occurred with correct parameters
- **Predictable Behavior**: Set up mocks to return known values for consistent test results

# MSTest V4 Anti-patterns

Avoid these common MSTest V4 patterns because they produce poor error messages or cause tests to be silently ignored.

# Avoid Assertions in Catch Blocks (MSTEST0058)

Instead of wrapping code in try/catch and asserting in the catch block, use `Assert.ThrowsExactly<T>()`:

```csharp
var ex = Assert.ThrowsExactly<ArgumentNullException>(() => SomeWork());
Assert.Contains("Some message", ex.Message);
```

# Avoid Assert.IsTrue/IsFalse for Equality Checks

Use `Assert.AreEqual`/`Assert.AreNotEqual` instead, as they provide better failure messages:

```csharp
// ❌ Bad: Assert.IsTrue(result == expected);
// ✅ Good: Assert.AreEqual(expected, result);
```

# Avoid Non-Public Test Classes and Methods

Test classes and `[TestMethod]` methods must be `public` or they will be silently ignored:

```csharp
// ❌ Bad: internal class MyTests
// ✅ Good: public class MyTests
```

# Avoid Assert.IsTrue for Collection Count

Use `Assert.HasCount` for count assertions:
/// <summary>
/// Validates that an invalid email format throws an ArgumentException.
/// </summary>
[Fact]
public void UserValidator_ValidateEmail_InvalidFormat_ThrowsArgumentException()
{
// Arrange: create a validator with default configuration
var validator = new UserValidator();

```csharp
// ❌ Bad: Assert.IsTrue(collection.Count == 3);
// ✅ Good: Assert.HasCount(3, collection);
// Act / Assert: email with no domain throws
Assert.Throws<ArgumentException>(() => validator.ValidateEmail("not-an-email"));
}
Comment thread
Malcolmnixon marked this conversation as resolved.
```

# Avoid Assert.IsTrue for String Prefix Checks
# xUnit v3 Specifics

Use `Assert.StartsWith` instead, as it produces clearer failure messages:
These are non-obvious v3 behaviors that differ from v2 or common assumptions:

```csharp
// ❌ Bad: Assert.IsTrue(value.StartsWith("prefix"));
// ✅ Good: Assert.StartsWith("prefix", value);
```
- **`IAsyncLifetime`**: Both `InitializeAsync` and `DisposeAsync` return `ValueTask`
in v3, not `Task` — using `Task` compiles but does not satisfy the v3 interface
- **`Assert.Multiple`**: Use to collect all assertion failures in a single test
rather than stopping at the first
- **`[Collection]` without `[CollectionDefinition]`**: Silently disables parallelism
without providing any shared fixture — always pair them or remove `[Collection]`

# Quality Checks

Before submitting C# tests, verify:

- [ ] All tests follow AAA pattern with clear section comments
- [ ] Test names follow hierarchical patterns defined in Test Naming Standards section
- [ ] Each test verifies single, specific behavior (no shared state)
- [ ] Test names follow hierarchical naming pattern above
- [ ] Each test verifies single, specific behavior (no shared state between tests)
- [ ] Both success and failure scenarios covered including edge cases
- [ ] External dependencies mocked with NSubstitute or equivalent
- [ ] External dependencies mocked with NSubstitute
- [ ] Tests linked to requirements with source filters where needed
- [ ] Test results generate TRX format for ReqStream compatibility
- [ ] MSTest V4 anti-patterns avoided (proper assertions, public visibility, etc.)
- [ ] Test results generated in TRX format for ReqStream compatibility (`dotnet test --logger trx`)
31 changes: 14 additions & 17 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Project Overview

> **Downstream customization required**: Replace the `TODO` values below with
> values specific to the target repository.

- **name**: TODO
- **description**: TODO
- **languages**: TODO
- **technologies**: TODO
Comment thread
Malcolmnixon marked this conversation as resolved.

# Project Structure

> **Downstream customization required**: Replace `{project}` and
> `{test-project}` with the actual source and test project folder names.

Comment thread
Malcolmnixon marked this conversation as resolved.
```text
├── docs/
│ ├── build_notes/
Expand Down Expand Up @@ -69,26 +82,10 @@ Delegate to specialized agents only for specific scenarios:
- **Formal feature implementation** (complex, multi-step) → Call the implementation agent
- **Formal bug resolution** (complex debugging, systematic fixes) → Call the implementation agent
- **Formal reviews** (compliance verification, detailed analysis) → Call the formal-review agent
- **Template consistency** (downstream repository alignment) → Call the repo-consistency agent

## Available Specialized Agents

- **lint-fix** - Pre-PR lint sweep agent that loops running `pwsh ./lint.ps1`,
fixing issues until the repository is lint-clean
- **developer** - General-purpose software development agent that applies appropriate
standards based on the work being performed
- **formal-review** - Agent for performing formal reviews using standardized review processes
- **implementation** - Orchestrator agent that manages quality implementations
through a formal state machine workflow
- **quality** - Quality assurance agent that grades developer work against project
standards and Continuous Compliance practices
- **repo-consistency** - Ensures downstream repositories remain consistent with
the TemplateDotNetLibrary template patterns and best practices

# Agent Reporting (Specialized Agents Must Follow)

Specialized agents (lint-fix, developer, quality, implementation,
formal-review, repo-consistency) MUST generate a completion report:
Specialized agents MUST generate a completion report:

1. Save to `.agent-logs/{agent-name}-{subject}-{unique-id}.md`
where `{subject}` is a kebab-case task summary (max 5 words) and
Expand Down
12 changes: 6 additions & 6 deletions docs/reqstream/ots/mstest.yaml → docs/reqstream/ots/xunit.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
---
# MSTest OTS Software Requirements
# xUnit v3 OTS Software Requirements
#
# Requirements for the MSTest testing framework functionality.
# Requirements for the xUnit v3 testing framework functionality.

sections:
- title: OTS Software Requirements
sections:
- title: MSTest Requirements
- title: xUnit v3 Requirements
requirements:
- id: Template-OTS-MSTest
title: MSTest shall execute unit tests and report results.
- id: Template-OTS-XUnit
title: xUnit v3 shall execute unit tests and report results.
justification: |
MSTest (MSTest.TestFramework and MSTest.TestAdapter) is the unit-testing framework used
xUnit v3 (xunit.v3 and xunit.runner.visualstudio) is the unit-testing framework used
by the project. It discovers and runs all test methods and writes TRX result files that
feed into coverage reporting and requirements traceability. Passing tests confirm the
framework is functioning correctly.
Expand Down
2 changes: 1 addition & 1 deletion requirements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ includes:
- docs/reqstream/template-dot-net-library/template-dot-net-library.yaml
- docs/reqstream/template-dot-net-library/demo.yaml
- docs/reqstream/template-dot-net-library/platform-requirements.yaml
- docs/reqstream/ots/mstest.yaml
- docs/reqstream/ots/xunit.yaml
- docs/reqstream/ots/reqstream.yaml
- docs/reqstream/ots/buildmark.yaml
- docs/reqstream/ots/versionmark.yaml
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<OutputType>Exe</OutputType>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand All @@ -22,6 +23,7 @@
<!-- Implicit Usings -->
<ItemGroup>
<Using Include="Polyfills" />
<Using Include="Xunit" />
</ItemGroup>

<!-- Test Framework Dependencies -->
Expand All @@ -35,8 +37,8 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.4.0" />
<PackageReference Include="MSTest.TestAdapter" Version="4.2.1" />
<PackageReference Include="MSTest.TestFramework" Version="4.2.1" />
<PackageReference Include="xunit.v3" Version="3.2.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
</ItemGroup>

<!-- Code Analysis Dependencies -->
Expand Down
Loading