-
-
Notifications
You must be signed in to change notification settings - Fork 353
Writing & Running Unit Tests
Phil Haack wrote a blog post in Jan 2012 introducing a really clever way of structuring your unit tests. We thought it was a great fit for our needs, so we're adopting it as well.
The gist of this structuring technique is to set up a single test class to contain all tests for any other class you might need to test. Let's assume we have a Foo
class we need to test. We'll call our container test class FooTests
. Inside FooTests
there can be many child classes. Each child class would typically represent a method or property of our Foo
class. So our FooTests
class might have a child class called TheBarMethod
. Our TheBarMethod
class could contain as many individual test cases about the Bar
method of the Foo
class.
using Nunit.Framework;
[TestFixture]
public class FooTests
{
public class TheBarMethod
{
[Test]
public void ShouldReturnBar()
{
// Arrange
var foo = new Foo();
// Act
var result = foo.Bar();
// Assert
Assert.AreEqual(result, "bar");
}
}
public class TheBazMethod
{
// TODO: Individual test cases for the `Baz` method will go in here...
}
}
Note: If you decorate each class with the [Microsoft.VisualStudio.TestTools.UnitTesting.TestClass]
attribute and each test with the [Microsoft.VisualStudio.TestTools.UnitTesting.TestCategory( "YOUR_TRAIT_HERE" )]
test-category attribute then the NUnit adapter in Visual Studio will allow you to categorize your tests by "Traits".
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Assert = NUnit.Framework.Assert;
[TestFixture]
public class DeviceTests
{
[TestClass]
public class TheGeoFenceProperty
{
[Test]
[TestMethod]
[TestCategory( "Rock.Model.Device" )]
public void ShouldFallWithinGeoFence()
{
// ...
- Keep them short and sweet.
- Break common/repetitive setup/teardown code out into helper methods.
- Limit them to 1-2 assertions per test. Unit tests are meant to test a single specific behavior. If you have many assertions in your tests, it could probably be broken out into multiple tests.
- Structuring a Unit Test
- Arrange - Set up the expectations of the test, hydrate objects with mock data, etc.
- Act - Execute the code being tested (usually a method call).
- Assert - Compare the result of running the code to the requirements/expectations.
NOTE: We focused on the NUnit Test Adapter and the Nunit client here simply because they are the lowest common denominator, with possibly the lowest learning curve to get developers running their tests.
- In Visual Studio, select TOOLS -> Extensions and Updates...
- Search for "NUnit Tets Adapter" and then install it (restart Visual Studio if necessary).
- In Visual Studio, select TEST -> Windows -> Test Explorer
- Click the "Run All" button to run your tests. Tests can be run one all at once, one at a time, or in groups by selecting the tests.
You can also debug a test by right clicking it and selecting "Debug Selected Tests".
- Go to nunit.org's download page and download the latest MSI installer.
- Run the installer.
- Rebuild the Rock solution in Visual Studio.
- In the NUnit client open the
Rock.Tests.dll
under\Rock.Tests\bin\debug
. - Once it's loaded, click the green "Play" button to run your tests. Tests can be run one at a time, or in groups by selecting the relevant parent or child class, or run all at once by selecting the entire project.
There's not really a very good obvious way of debugging your unit tests if you're using the Nunit client. You can, however, manually invoke the System.Diagnostics.Debugger
in your setup methods.
[TestFixture]
public class FooTests
{
[SetUp]
public void SetUp()
{
System.Diagnostics.Debugger.Launch();
}
public class TheBarMethod
{
// Tests go in here...
}
}
When the test runner hits this line, the debugger in Visual Studio will launch giving you a list of instances of Visual Studio to use. Make sure to select the project you're currently working on and hit OK
. You'll begin debugging the tests at the call to Debugger.Launch()
. You can go ahead and set a breakpoint as needed and hit the green "Play" button inside Visual Studio to jump to the line of code where you need to begin debugging.
This step is most likely not necessary if you're running an external runner/debugger VS plugin like TDD.NET or ReSharper.