Skip to content
This repository has been archived by the owner on Oct 11, 2022. It is now read-only.

Commit

Permalink
Formatting updates (#58)
Browse files Browse the repository at this point in the history
* code formatting

* small improvemens
  • Loading branch information
Styxxy authored and pvlakshm committed Oct 19, 2018
1 parent 44a1170 commit 9caffd8
Show file tree
Hide file tree
Showing 8 changed files with 390 additions and 384 deletions.
88 changes: 44 additions & 44 deletions RFCs/001-Framework-Extensibility-Trait-Attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
This details the MSTest V2 framework extensibility for attributes that are traits for a test.

## Motivation
It is a requirement for teams to have trait attributes which are strongly typed over a test method as opposed to just a KeyvaluePair<string,string>. This allows teams to have a standard across the team which is less error prone and more natural to specify. Users can also filter tests based on the values of these attributes.
It is a requirement for teams to have trait attributes which are strongly typed over a test method as opposed to just a `KeyvaluePair<string, string>`. This allows teams to have a standard across the team which is less error prone and more natural to specify. Users can also filter tests based on the values of these attributes.

## Detailed Design

Expand All @@ -15,64 +15,64 @@ It is a requirement for teams to have trait attributes which are strongly typed
4. This extensibility should also guarantee that attributes in MSTest V1 which are brought into MSTest V2 with this extensibility model should be source compatible.

### Proposed solution
The test framework currently has a TestProperty attribute which can be used to define custom traits as a KeyValuePair<string,string>. The definition of this attribute is as below:
The test framework currently has a TestProperty attribute which can be used to define custom traits as a `KeyValuePair<string, string>`. The definition of this attribute is as below:
```csharp
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public sealed class TestPropertyAttribute : Attribute
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public sealed class TestPropertyAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="TestPropertyAttribute"/> class.
/// </summary>
/// <param name="name">
/// The name.
/// </param>
/// <param name="value">
/// The value.
/// </param>
public TestPropertyAttribute(string name, string value)
{
/// <summary>
/// Initializes a new instance of the <see cref="TestPropertyAttribute"/> class.
/// </summary>
/// <param name="name">
/// The name.
/// </param>
/// <param name="value">
/// The value.
/// </param>
public TestPropertyAttribute(string name, string value)
{
this.Name = name;
this.Value = value;
}
this.Name = name;
this.Value = value;
}

/// <summary>
/// Gets the name.
/// </summary>
public string Name { get; }
/// <summary>
/// Gets the name.
/// </summary>
public string Name { get; }

/// <summary>
/// Gets the value.
/// </summary>
public string Value { get; }
}
/// <summary>
/// Gets the value.
/// </summary>
public string Value { get; }
}
```

This TestProperty is also filled into the TestPlatform's TestCase object which makes it available for reporting in the various loggers that can be plugged into the TestPlatform.

To provide extension writers with the ability to have strongly typed attributes to achieve what TestProperty above achieves, the proposal is to make TestProperty a non-sealed class allowing classes to extend it like below:
```csharp
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class CustomTraitPropertyAttribute : TestPropertyAttribute
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class CustomTraitPropertyAttribute : TestPropertyAttribute
{
/// <summary>
/// Initializes a new instance of the <see cref="CustomTraitPropertyAttribute"/> class.
/// </summary>
/// <param name="traitData">
/// Data associated with trait property
/// </param>
public CustomTraitPropertyAttribute(int traitData)
: base ("CustomTraitProperty", traitData.ToString())
{
/// <summary>
/// Initializes a new instance of the <see cref="CustomTraitPropertyAttribute"/> class.
/// </summary>
/// <param name="traitData">
/// Data associated with trait property
/// </param>
public CustomTraitPropertyAttribute(int traitData)
: base ("CustomTraitProperty", traitData.ToString())
{
}
}
}
```
And test methods would be decorated in a much more convenient form as below:
```csharp
[TestMethod]
[CustomTraitProperty(234)]
public void TestMethod()
{
}
[TestMethod]
[CustomTraitProperty(234)]
public void TestMethod()
{
}
```

Users can then filter tests in VS IDE Test Explorer based on this Test Property. The query string that would filter the test above would look like
Expand Down
53 changes: 27 additions & 26 deletions RFCs/002-Framework-Extensibility-Custom-Assertions.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,51 +16,52 @@ Often times, the default set of assertion APIs are not sufficient to satisfy a w
2. Users of custom assertions should be able to acquire and use them with ease.

### Proposed solution
Here is a solution that is both easily pluggable and acquirable:
Here is a solution that is both easily pluggable and acquirable:

The test frameworks Assertion class should be a non-static singleton with a C# Property('That') for accessing the instance:
```csharp
public class Assert{

public static Assert That{
get
{
// ...
}
The test frameworks Assertion class should be a non-static singleton with a C# Property('That') for accessing the instance:
```csharp
public class Assert
{
public static Assert That
{
get
{
// ...
}
}
}
```

Extension writers can then add C# extension methods for the Assertion class like below:
```csharp
public static class SampleAssertExtensions
public static class SampleAssertExtensions
{
public static void IsOfType<T>(this Assert assert, object obj)
{
public static void IsOfType<T>(this Assert assert, object obj)
if(obj is T)
{
if(obj is T)
{
return;
}
throw new AssertFailedException("Type does not match");
return;
}
throw new AssertFailedException("Type does not match");
}
}
```

And consumers of this extension can consume it in their test code with the below simple syntax:
```csharp
using SampleAssertExtensionsNamespace;
public void TestMethod
{
// ...
Assert.That.IsOfType<Dog>(animal);
}
using SampleAssertExtensionsNamespace;

public void TestMethod
{
// ...
Assert.That.IsOfType<Dog>(animal);
}
```

#### Benefits for custom assertion writers
1. Leverages the default C# constructs - No new interfaces/objects to understand and extend.
2. Extensions can be organized under a verb. For instance assertions expecting exceptions can be organized under the Throws verb like
```
```csharp
Assert.That.Throws.InnerException
Assert.That.Throws.SystemException
Assert.That.Throws.ExceptionWithMessage
Expand All @@ -75,4 +76,4 @@ Assert.That.IsNotNull(animal).And.IsOfType<Cat>(animal)
2. Readable - Using linq type expressions enhances readability.

## Open questions
1. How important are combined asserts in a single Assert statement (Assert.That.Something.And.Something) and how much of this should be available in-box?
1. How important are combined asserts in a single Assert statement (`Assert.That.Something.And.Something`) and how much of this should be available in-box?
Loading

0 comments on commit 9caffd8

Please sign in to comment.