MSTest v2: Exploring asserts
This post is part of the series 'MSTest v2'. Be sure to check out the rest of the blog posts of the series!
- MSTest v2: Setup a test project and run tests
- MSTest v2: Exploring asserts (this post)
- MSTest v2: Data tests
- MSTest v2: Test lifecycle attributes
- MSTest v2: Create new asserts
- MSTest v2: Customize test execution
- MSTest v2: Execute tests in parallel
- MSTest v2: Testing against multiple frameworks
In the previous post, we created a simple test and run it. You write a test to assert your code behaves as expected. This means, assertions are central to unit testing in any framework, and MSTest is no exception. MSTest provides a rich set of assertions. So, today we'll explore the Assert
classes.
An assertion method is a method that takes parameters and ensures a condition is met. For instance, AreEqual
takes 2 values and check they are equal. If an assertion fails, the method call does not return and an error is reported. The method throws an exception with a formatted message. If a test contains multiple assertions, any that follow the one that failed will not be executed.
[TestMethod]
public void Test()
{
Assert.AreEqual(10, 5 + 5); // Success
Assert.AreEqual(10, 1 + 2); // 10 ≠ 3 => Error.
Assert.AreEqual(20, 1 + 2); // Not executed
}
Now, we can explore the different assert methods of the framework.
#Assertion on a single value
The following assert methods validate a value meets a specific condition. I won't explain all of them because the usage is pretty clear.
Assert.AreEqual(object expected, object actual)
: Tests whether the specified values are equal. Different numeric types are treated as unequal even if the logical values are equal. 42L is not equal to 42.Assert.AreNotEqual(object expected, object actual)
: Tests whether the specified values are unequal. Same as AreEqual for numeric values.Assert.AreSame(object expected, object actual)
: Tests whether the specified objects both refer to the same objectAssert.AreNotSame(object expected, object actual)
: Tests whether the specified objects refer to different objectsAssert.IsTrue(bool condition)
: Tests whether the specified condition is trueAssert.IsFalse(bool condition)
: Tests whether the specified condition is falseAssert.IsNull(object value)
: Tests whether the specified object is nullAssert.IsNotNull(object value)
: Tests whether the specified object is non-nullAssert.IsInstanceOfType(object value, Type type)
: Tests whether the specified object is an instance of the expected typeAssert.IsNotInstanceOfType(object value, Type type)
: Tests whether the specified object is not an instance of the wrong typeStringAssert.Contains(string value, string substring)
: Tests whether the specified string contains the specified substringStringAssert.StartsWith(string value, string substring)
: Tests whether the specified string begins with the specified substringStringAssert.Matches(string value, Regex regex)
: Tests whether the specified string matches a regular expressionStringAssert.DoesNotMatch(string value, Regex regex)
: Tests whether the specified string does not match a regular expression
I'll only provide an example of AreEqual
and AreSame
because the difference is more subtle.
var expected = "a";
var actual = "a";
Assert.AreEqual(expected, actual); // success
Assert.AreSame(expected, actual); // fail
Assert.AreNotEqual(expected, actual); // fail
Assert.AreNotSame(expected, actual); // success
Assert.AreEqual(42, 42); // success
Assert.AreEqual(42, 42L); // fail
#Assertion on collections
CollectionAssert.AreEqual(ICollection expected, ICollection actual)
: Tests whether the specified collections have the same elements in the same order and quantity.CollectionAssert.AreNotEqual(ICollection expected, ICollection actual)
: Tests whether the specified collections does not have the same elements or the elements are in a different order and quantity.CollectionAssert.AreEquivalent(ICollection expected, ICollection actual)
: Tests whether two collections contain the same elements.CollectionAssert.AreNotEquivalent(ICollection expected, ICollection actual)
: Tests whether two collections contain different elements.CollectionAssert.AllItemsAreInstancesOfType(ICollection collection, Type expectedType)
: Tests whether all elements in the specified collection are instances of the expected typeCollectionAssert.AllItemsAreNotNull(ICollection collection)
: Tests whether all items in the specified collection are non-nullCollectionAssert.AllItemsAreUnique(ICollection collection)
: Tests whether all items in the specified collection are uniqueCollectionAssert.Contains(ICollection collection, object element)
: Tests whether the specified collection contains the specified elementCollectionAssert.DoesNotContain(ICollection collection, object element)
: Tests whether the specified collection does not contain the specified elementCollectionAssert.IsSubsetOf(ICollection subset, ICollection superset)
: Tests whether one collection is a subset of another collectionCollectionAssert.IsNotSubsetOf(ICollection subset, ICollection superset)
: Tests whether one collection is not a subset of another collection
Here's an example to show the difference between AreEqual
and AreEquivalent
:
CollectionAssert.AreEqual(new [] { 1, 2 }, new [] { 1, 2 }); // success
CollectionAssert.AreEqual(new [] { 1, 2 }, new [] { 1, 2, 3 }); // fail
CollectionAssert.AreEqual(new [] { 1, 2 }, new [] { 2, 1 }); // fail
CollectionAssert.AreEquivalent(new [] { 1, 2 }, new [] { 1, 2 }); // success
CollectionAssert.AreEquivalent(new [] { 1, 2 }, new [] { 1, 2, 3 }); // fail
CollectionAssert.AreEquivalent(new [] { 1, 2 }, new [] { 2, 1 }); // success
#Test an exception is thrown
Assert.ThrowsException<T>(Action action)
: Tests whether the code specified by delegate throws an exception of typeT
(and not of derived type)Assert.ThrowsExceptionAsync<T>(Func<Task> action)
: Same asThrowsException
with async code
// success
Assert.ThrowsException<ArgumentNullException>(() => new Regex(null));
// fail
Assert.ThrowsException<ArgumentException>(() => new Regex(null));
#Other asserts
The following assert methods are special. The first one Fail
immediately change the status of the test to "error". This can be useful to write your assert method. The second one, Inconclusive
, indicates that the test could not be completed. In this case, the test is neither a success nor a failure.
Assert.Fail(string message)
Assert.Inconclusive(string message)
Here's an example of an inconclusive test
[TestMethod]
public void Sample8()
{
if (DateTime.Now.Hour != 12)
Assert.Inconclusive("Must be executed at noon");
// actual tests...
}
In the test explorer, inconclusive tests are grouped into "Skipped Tests":
#Conclusion
MSTest v2 comes with more than 30 assert methods. This should help you writing your tests. In a future blog post, we'll see how to extend the list of assert methods with your methods.
Do you have a question or a suggestion about this post? Contact me!