ict.ken.be

Delivering solid user friendly software solutions since the dawn of time.

Unit Testing with MSTest - Notes 

by Phani Tipparaju

Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll

[TestClass]

[TestMethod]
public void AnEmptyTest() {}

Arrange, Act, Assert (3 A's pattern)

Test Run Configuration:
.testsettings files
Test - Select Active Test Setting

\Common7\IDE\MSTest.exe
/testcontainer:[filename]
/test:[testname]
/testlist:[testlistpath]
/testsettings
http://msdn.microsoft.com/en-us/library/ms182489.aspx#test

Asserts and Testing Lifecycle

Configure a resource shared among your tests (db, object, log)

// once before and after each unit tests.
[TestInitialize]
public void TestInitialize() {}
[TestCleanup]
public void TestCleanUp() {}
//once before and after all tests in the class
[ClassInitialize]
public static void ClassInitialize(TestContext context) {}
[ClassCleanup]
public static void ClassCleanup() {}

//once before and after all tests in assembly
[AssemblyInitialize]
public static void AssemblyInitialize(TestContext context) {}
[AssemblyCleanup]
public static void AssemblyCleanUp() {}

Asserting

Assert.AreEqual(expected, actual, failMessage); // objectOne.Equals(objectTwo)
Assert.AreEqual(expected, actual, delta, failMessage);
Assert.AreEqual(expected, actual, true); // ignore case with strings
Assert.AreSame(a, b); // checks reference then value

CollectionAssert.AllItemsAreNotNull(collection, failMessage);
CollectionAssert.AllItemsAreUnique(collection, failMessage);
CollectionAssert.AreEqual(expected, actual); // compares element by element on reference base
CollectionAssert.AreEquivalent(expected, actual); // order of elements not important
CollectionAssert.IsSubsetOf(subset_collection, collection, failMessage);
StringAssert.Contains("string","find");
StringAssert.Matches("Search for whitespaces", new System.Text.RegularExpressions.Regex(@"\s"));
StringAssert.StartsWith("string","start string");
StringAssert.EndsWith("string","end string");

TestContext

  • Set by runtime
  • Provides information about the unit test run environment
  • Path to deployment directory
  • Test name
  • URL of the web service
  • Page object of asp.net apps
  • Access to data source with data rows
public TestContext TestContext { get; set; }
TestContext.WriteLine("TestRunDirectory: {0}", TestContext.TestRunDirectory);
TestContext.WriteLine("TestName: {0}", TestContext.TestName);
TestContext.WriteLine("Outcome: {0}", TestContext.CurrentTestOutcome);

Data driven unit-test

Test View - RightClick Properties - Data Connection String
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML"),
"|DataDirectory|\\UserDetails.xml", "User", DataAccessMethod.Sequential),
DeploymentItem("UserDetailsEntryTest\\UserDetails.xml"), TestMethod]

string email = Convert.ToString(TestContext.DataRow["email"]);

Web Performance Test 

(since it is not part of the standard visual studio I use Selenium)
Create Web App > Create a test project & add web test > Record the web test > Parameterize - Insert Rules - Dynamic Params - Loops > Run Web Test > Analyse results
Web Tests work at HTTP Layer
Microsoft.VisualStudio.TestTools.WebTesting.ExtractionRule
Microsoft.VisualStudio.TestTools.WebTesting.ValidationRule
public class MyCustomWebTest : WebTest {}

Unit Test Features

Ordered Tests

  • Appears as a single test in the Test Window (double click to see individual results)
  • Can execute one test many times
  • Used to group tests together, can contain other ordered tests but no load tests.

Generic Tests

  • Integrate Non-VS automated testing tools
  • Can be run from command line
  • Must return a value of Pass or Fail (return 0 is pass all else is fail)
  • Uses your credentials (trust the author and know what the program will do)

Test Attributes (will show up in .trx xml file)

[Owner("Ken")]
[Description("This is for testing")]
[TestProperty("MyCustomVersion","1.0.1.2")]
[TimeOut(1000)] // in milliseconds
[Priority(1)] // not used by the system, but you can use to sort them in the test list editor
[Ignore] // do not run test
[TestCategory("MyCategory")]
[ExpectedException(typeof(DivideByZeroException))]

Relate to Team Foundation Server
[CssIteration] // Classification.Iteration
[CssProjectStructure] // Classification.Area
[WorkItem] // User Story

WebServiceHelper

[Microsoft.VisualStudio.TestTools.UnitTesting.Web.AspNetDevelopmentServer("WcfService1", "path to service")]
public void TestMethod1()
{
var target = new WebServiceTesting.ServiceReference.ServiceClient();
var protocol = new System.Web.Services.Protocols.HttpGetClientProtocol();
protocol.Url = "http://myservice.svc";
Assert.IsTrue(WebServiceHelper.TryUrlRedirection(protocol, testContextInstance, "WcfService1"));
actual = target.GetData(1);
Assert.AreEqual(1,actual);
}

TestConfigurationSection

  • Instead of providing values in code, depend on configuration files
  • Allows flexibility for regions and file formats.

1. Create a app.config
2. Define "TestConfigurationSection"
<configSections>
<section name="microsoft.visualstudio.testtools" type="..." />
</configSections>
3. Define connectionstrings
<connectionStrings>
<add name="MyExcel" connectionstring="Dsn=Excel ..." providerName="System.Data.Odbc" />
</connectionStrings>
4. Define data source
<microsoft.visualstudio.testtools>
<dataSources>
<add name="MyExcelDataSource" connectionstring="MyExcel" dataTable="Sheet1$" dataAccessMethod="Sequential" />
</dataSources>
</microsoft.visualstudio.testtools>
5. Use the "DataSourceAttribute" for the test method
[DataSource("MyExcelDataSource")] instead of using [DataSource]

AutoMocking 

Categories: Testing

AutoMocking using StructureMap
http://doc.structuremap.net

var autoMocker = new RhinoAutoMocker<StudentRegistrationService>();
var mockStudentValidator = autoMocker.Get<IStudentValidator>();
mockStudentValidator.Stub(x => x.ValidateStudent(Arg<Student>.Is.Anything)).Return(true);

autoMocker.ClassUnderTest.RegisterNewStudent( ... );
autoMocker.Get<IStudentRepository>().AssertWasCalled(x => x.Save(Arg<Student>.Matches( ... )));

AutoMocking using Windsor Castle

public abstract class TestBase
{
static readonly WindsorContainer _mockWindsorContainer;

static TestBase()
{
_mockWindsorContainer = new WindsorContainer();
_mockWindsorContainer.Register(Component.For<LazyComponentAutoMocker>());
}

protected static T MockOf<T>() where T : class
{
return _mockWindsorContainer.Resolve<T>();
}

protected static T Create<T>()
{
_mockWindsorContainer.Register(Component.For<T>());
return _mockWindsorContainer.Resolve<T>();
}
}

public class LazyComponentAutoMocker : ILazyComponentLoader
{
public IRegistration Load(string key, Type service, IDictionary arguments)
{
return Component.For(service).Instance(MockRepository.GenerateStub(service));
}
}

AutoMocking with Ninject
http://trycatchfail.com/blog/post/The-Right-Way-to-Do-Automocking-with-Ninject.aspx

AutoMocking with Moq
http://moqcontrib.codeplex.com/

Rhino Mocks Fundamentals - Notes 

Categories: Notes Testing

by Jim Cooper

codesimply.blogspot.com

A good unit test

  • Atomic
  • Deterministic (it should pass or fail)
  • Repeatable
  • Order Independent & Isolated
  • Fast
  • Easy to setup
var mockStudentRepository = MockRepository.GenerateMock<IStudentRepository>();
var student = new Student() { ... };
studentService.RegisterNewStudent(student);
mockStudentRepository.AssertWasCalled(x => x.Save(student));

//using mocks to verify property setters
var mockStudentView = MockRepository.GenerateMock<IStudentView>();
mockstudentView.AssertWasCalled(x => x.WasStudentSaved = true);

//using stubs to control the program flow
var mockStudentValidator = MockRepository.GenerateMock<IStudentValidator>();
mockStudentValidator.Stub(x => x.ValidateStudent(Arg<Student>.Is.Anything)).Return(true);
mockStudentView.Stub(x => x.ShouldSaveStudent).Return(true);

//do not use GenerateStub cause it will not work for read-only properties
var mockStudentView = MockRepository.GenerateStub<IStudentView>();
mockstudentView.ShouldSaveStudent = true;
  • It's much easier to always use GenerateMock, you might need it anyway
  • Actualy generatemock actually is a generatetestdouble
  • Use Arrange,Act,Assert instead of Record,Replay (legacy: Record, Playback, Expect.Call, ReplayAll, VerifyAll, DynamicMocks vs StrictMocks)
//constraints
Arg<Student>.Is.Anything,NotNull,Same,...
Arg<Student>.Matches(y => y.Id == expectedStudentId && y.FirstName == expectedFirstName)
Arg<Student>.Matches(y => IsCustomerMatching(student, expectedStudentId, expectedFirstName)
Arg<List<Student>>.List.ContainsAll(new List<Student> {student1, student2, student3})
Arg<List<Student>>.List.Count(Rhino.Mocks.Constraints.Is.Equal(3))
Arg<List<Student>>.List.IsIn(student1)
Text.Contains("one"),EndsWidth,StartWith,Like,...
//example custom constraint
mockStudentRepository.AssertWasCalled(x => x.Save(Arg<Student>.Matches(new StudentConstraint(expectedStudent))));
public class StudentConstraint : AbstractConstraint
{
public StudentContraint(Student expectedStudent) {}
public override bool Eval(object actual) {}
public override string Message { get; set; } //called if eval is false
}

Avoid using out & ref parameters
out Arg<Student>.Out(new Student()).Dummy
ref Arg<Student>.Ref(Rhino.Mocks.Constraints.Is.Anything, new Student()).Dummy

Page 25 of 43 << < 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 40 > >>