Using C# 4.0. I have a unit test where I need to create a temporary database. This is done during class initialization:
[ClassInitialize()]
public static void MyClassInitialize(TestContext testContext)
{
// Create database!
}
[ClassCleanup()]
public static void MyClassCleanup()
{
// Remove database IF CurrentTestOutcome == UnitTestOutcome.Passed
}
Q: How can I read the CurrentTestOutcome value from my ClassCleanup method?
I'd suggest that you create a static flag that you can access from your MyClassCleanup and set it during test cleanup when you get an error. Something like the following on your class:
[TestClass]
public class MyTests {
static bool _testFailed;
[ClassInitialize()]
public static void MyClassInitialize(TestContext testContext)
{
// Create database!
_testFailed = false;
}
[ClassCleanup()]
public static void MyClassCleanup()
{
if(_testFailed == false) {
// Remove database IF CurrentTestOutcome == UnitTestOutcome.Passed
}
}
[TestCleanup()]
public void MyTestCleanup() {
if (TestContext.CurrentTestOutcome != UnitTestOutcome.Passed) {
_testFailed = true;
}
}
public TestContext TestContext { get; set; }
}
I'm suggesting the above approach because my understanding is that in your class cleanup, referring to CurrentTestOutcome wouldn't really make much since. It would simply contain the state of the last test to run, not the combined outcome from all of the tests in the class.
I'm considering the following solution. Not sure if this may be considered good practice or not.
private static IList<TestContext> testResults;
public TestContext TestContext
{
get
{
return testContext;
}
set
{
testContext = value;
testResults.Add(testContext);
}
}
[ClassInitialize()]
public static void MyClassInitialize(TestContext testContext)
{
testResults = new List<TestContext>();
}
[ClassCleanup()]
public static void MyClassCleanup()
{
if (testResults.All(t => t.CurrentTestOutcome == UnitTestOutcome.Passed ||
t.CurrentTestOutcome == UnitTestOutcome.Inconclusive))
{
// Perform conditional cleanup!
}
}
Related
I have a set of unit tests that require TestInitialize to run for them to work... however, there is one specific test that i'd love to be able to run without running TestInitialize. Is there a way to do that?
It might look like this:
[TestClass]
public class BingBangBoom
{
[TestInitialize]
public void Setup()
{
// ...
}
[TestMethod]
public void Bing()
{
// ...
}
[TestMethod]
public void Bang()
{
// ...
}
[TestMethod(PreventInitialize)]
public void Boom
{
// ...
}
}
No worries if not, I can come up with an alternative solution
Edit - RE DavidG:
It seems a shame to have this:
[TestClass]
public class BingBangBoom
{
[TestInitialize]
public void Setup()
{
// ...
}
// 10 very related methods
}
[TestClass]
public class BingBangBoom2
{
// 1 method, even though it's entirely related to BingBangBoomin'
}
I guess it is what it is.
That's not immediately obvious, but surely doable.
Assuming you have attribute like this:
public class SkipInitializeAttribute : Attribute { }
The thing you need is public property inside your test class to be injected by testing framework:
public TestContext TestContext { get; set; }
And then just branch your initialization like this:
[TestInitialize]
public void Initialize()
{
bool skipInitialize = GetType().GetMethod(TestContext.TestName)
.GetCustomAttributes<SkipInitializeAttribute>().Any();
if (!skipInitialize)
{
// Initialization code here
}
}
Working sample as self-tested solution:
using System;
using System.Linq;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTestProject1
{
public class SkipInitializeAttribute : Attribute
{
}
[TestClass]
public class UnitTest1
{
public TestContext TestContext { get; set; }
private bool IsInitializationDone { get; set; }
[TestInitialize]
public void Initialize()
{
bool skipInitialize = GetType().GetMethod(TestContext.TestName).GetCustomAttributes<SkipInitializeAttribute>().Any();
if (!skipInitialize)
{
// Initialization code here
IsInitializationDone = true;
}
}
[TestMethod]
public void TestMethod1()
{
Assert.IsTrue(IsInitializationDone);
}
[TestMethod]
[SkipInitialize]
public void TestMethod2()
{
Assert.IsFalse(IsInitializationDone);
}
[TestMethod]
public void TestMethod3()
{
Assert.IsTrue(IsInitializationDone);
}
}
}
And results:
Starting test execution, please wait...
Passed TestMethod1
Passed TestMethod2
Passed TestMethod3
Total tests: 3. Passed: 3. Failed: 0. Skipped: 0.
Test Run Successful.
Having this general idea in mind you can play with base class / helpers etc.
So I have production code, compiled against production dlls. They access the real architecture of the system.
I'm working on a simulator that will simulate this architecture. All the classes in the simulation are named the same and belong to the same namespaces as the production classes.
People can use my simulation dlls to do a rough draft test of their code.
However, if they call existing production business logic that was compiled against the production classes, it will load the existing production dlls and use the real architecture.
If people want to use my simulation, but call existing business logic, I'd have to use some kind of injection to overwrite the dll that loads the production classes.
Is this possible?
For an example:
I have a dll called Production.dll
In it there is a class like so.
namespace Production
{
public class A { public void Do(); }
}
Now, I have a dll called Simulation.dll with the same class and code.
Someone wrote a program called DoA.exe
public static class Program
{
public static Main()
{
var a = new Production.A();
a.Do();
}
}
I want to make DoA.exe load my simulation dll, but I may not be able to remove Production.dll from its search path. How can I force it to use Simulation.dll instead.
I think I understand better your problem. While I think my original solution is cleaner, this is how to do it "dirty".
Assuming your class schema is like this (simplified):
// assembly: Production.dll (no dependencies)
namespace Production {
public class Test {
public void Do() {
Console.Out.WriteLine("Production");
}
}
}
// assembly: Simulation.dll (no dependencies)
namespace Production {
public class Test {
public void Do() {
Console.Out.WriteLine("Simulation");
}
}
}
// assembly: Usage.dll (dependency on Production.dll)
namespace Usage {
public class TestUsage {
public void Do() {
new Production.Test().Do();
}
}
}
And finally code that will perform the override:
// Console application ConsoleApplication.exe
// dependency on Production.dll, Usage.dll and Simulation.dll
namespace ConsoleApplication {
internal class AssemblyResolver : MarshalByRefObject {
static internal void Register(AppDomain domain) {
var resolver = domain.CreateInstanceFromAndUnwrap(
Assembly.GetExecutingAssembly().Location,
typeof(AssemblyResolver).FullName) as AssemblyResolver;
resolver.RegisterDomain(domain);
}
private void RegisterDomain(AppDomain domain) {
domain.AssemblyResolve += ResolveAssembly;
}
private Assembly ResolveAssembly(object sender, ResolveEventArgs args) {
var assemblyName = new AssemblyName(args.Name);
string name = assemblyName.Name;
// comment out line below and you'll load "Production" instead
if (name == "Production") {
name = "Simulation";
}
var fileNames = new[] { name + ".dll", name + ".exe" };
foreach (string fileName in fileNames) {
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
if (File.Exists(path)) {
return Assembly.Load(File.ReadAllBytes(path));
}
}
return null;
}
}
class Program {
static void Main(string[] args) {
var domain = AppDomain.CreateDomain("Doable", null, new AppDomainSetup {
DisallowApplicationBaseProbing = true
});
AssemblyResolver.Register(domain);
domain.DoCallBack(() => {
// writes out "Simulation"
new Usage.TestUsage().Do();
});
}
}
}
I'm using Dependency Injection to handle problems like this:
Suppose you have interface like
public interface IDoable {
void Do();
}
in Interfaces.dll
and than you have Production.dll with class like:
namespace Production {
internal class Doable : IDoable {
public void Do() { Console.Out.WriteLine("Production"); }
}
public static class Bootstrapper {
static void Init(IServiceLocator locator) {
locator.AddSingleton<IDoable, Doable>();
}
}
}
and then you have Simulation.dll with class like
namespace Simulation {
internal class Doable : IDoable {
public void Do() { Console.Out.WriteLine("Simulation"); }
}
public static class Bootstrapper {
static void Init(IServiceLocator locator) {
locator.AddSingleton<IDoable, Doable>();
}
}
}
Then in your MainAssembly you can reference both, and resolve what implementation you want to use via configuration (naive example below). Except for the configuration line, you don't really have to care from which assembly the IDoable came from - you just use it.
public static Main()
{
Production.Bootstrapper.Init(ServiceLocator.Instance);
// or you can use
// Simulation.Bootstrapper.Init(ServiceLocator.Instance);
IDoable doable = ServiceLocator.Instance.Resolve<IDoable>();
doable.Do();
}
Utility classes (using Microsoft Unity Container from Enterprise Library):
public interface IServiceLocator {
void Add<TFrom, TTo>() where TTo : TFrom;
void BuildUp<T>(T instance);
void BuildUp(Type type, object instance);
void AddSingleton<TFrom, TTo>() where TTo : TFrom;
void AddSingleton<TFrom, TTo>(string name) where TTo : TFrom;
void AddSingleton(Type from, Type to, string name);
void AddInstance<T>(T instance);
T Resolve<T>();
T Resolve<T>(string name);
}
public class ServiceLocator : IServiceLocator {
private IUnityContainer m_Container = new UnityContainer();
public void Add<TFrom, TTo>() where TTo : TFrom {
m_Container.RegisterType<TFrom, TTo>();
}
public void BuildUp<T>(T instance) {
m_Container.BuildUp<T>(instance);
}
public void BuildUp(Type type, object instance) {
m_Container.BuildUp(type, instance);
}
public void AddSingleton<TFrom, TTo>() where TTo : TFrom {
m_Container.RegisterType<TFrom, TTo>(new ContainerControlledLifetimeManager());
}
public void AddSingleton<TFrom, TTo>(string name) where TTo : TFrom {
m_Container.RegisterType<TFrom, TTo>(name, new ContainerControlledLifetimeManager());
}
public void AddSingleton(Type from, Type to, string name) {
m_Container.RegisterType(from, to, name, new ContainerControlledLifetimeManager());
}
public void AddInstance<T>(T instance) {
m_Container.RegisterInstance<T>(instance);
}
public T Resolve<T>() {
return m_Container.Resolve<T>();
}
public T Resolve<T>(string name) {
return m_Container.Resolve<T>(name);
}
private static IServiceLocator s_Instance;
public static IServiceLocator Instance {
get { return s_Instance; }
}
static ServiceLocator() {
var instance = new ServiceLocator();
instance.AddInstance<IServiceLocator>(instance);
s_Instance = instance;
}
}
I am new to testing please help.
I have the following class
public delegate void OnInvalidEntryMethod(ITnEntry entry, string message);
public class EntryValidator
{
public event OnInvalidEntryMethod OnInvalidEntry;
public bool IsValidEntry(ITnEntry entry, string ticker)
{
if (!IsFieldValid(entry, ticker.Trim().Length.ToString(), "0"))
return false;
return true;
}
private bool IsFieldValid(ITnEntry entry, string actual, string invalidValue)
{
if (actual == invalidValue)
{
RaiseInvalidEntryEvent(entry);
return false;
}
return true;
}
private void RaiseInvalidEntryEvent(ITnEntry entry)
{
if (OnInvalidEntry != null)
OnInvalidEntry(entry, "Invalid entry in list: " + entry.List.Name + ".");
}
}
I have written the test case so far but am struggling with the event and delegate as shown below
[TestFixture]
public class EntryValidatorTests
{
private EntryValidator _entryValidator;
private FakeTnEntry _selectedEntry;
private string _ticker;
[SetUp]
public void Setup()
{
_entryValidator = new EntryValidator();
_ticker = "BOL";
}
private FakeTnEntry MakeEntry(string ticker)
{
return new FakeTnEntry { Ticker = ticker};
}
[Test]
public void IsValidEntry_WithValidValues()
{
_selectedEntry = MakeEntry(_ticker);
Assert.IsTrue(_entryValidator.IsValidEntry(_selectedEntry, _selectedEntry.Ticker));
}
[Test]
public void IsValidEntry_WithInValidTicker()
{
_selectedEntry = MakeEntry("");
Assert.IsFalse(_entryValidator.IsValidEntry(_selectedEntry, _selectedEntry.Ticker));
}
}}
Please can someone help? Thanks..
It's probably simplest just to subscribe to the event using an anonymous method:
[Test]
public void IsValidEntry_WithValidValues()
{
_selectedEntry = MakeEntry(_ticker);
_entryValidator.OnInvalidEntry += delegate {
Assert.Fail("Shouldn't be called");
};
Assert.IsTrue(_entryValidator.IsValidEntry(_selectedEntry, _selectedEntry.Ticker));
}
[Test]
public void IsValidEntry_WithInValidTicker()
{
bool eventRaised = false;
_selectedEntry = MakeEntry("");
_entryValidator.OnInvalidEntry += delegate { eventRaised = true; };
Assert.IsFalse(_entryValidator.IsValidEntry(_selectedEntry, _selectedEntry.Ticker));
Assert.IsTrue(eventRaised);
}
In the second test you might want to validate that the event arguments were as expected too.
Also note that "invalid" is one word - so your test should be IsValidEntry_WithInvalidTicker. I'd also not bother with the setup - I'd just declare new local variables in each test.
I would restructure your class to make the RaiseInvalidEntryEvent virtual so it can be mocked in your IsValidEntry_WithInValidTicker and then verified it was called when the ticket was invalid.
Then I would have another test that verified RaiseInvalidEntryEvent called the anon delegate separately.
Unit tests should be as atomic as possible, and you would want to verify both of these behaviors in different tests.
public delegate void OnInvalidEntryMethod(ITnEntry entry, string message);
public class EntryValidator
{
public event OnInvalidEntryMethod OnInvalidEntry;
public bool IsValidEntry(ITnEntry entry, string ticker)
{
if (!IsFieldValid(entry, ticker.Trim().Length.ToString(), "0"))
return false;
return true;
}
private bool IsFieldValid(ITnEntry entry, string actual, string invalidValue)
{
if (actual == invalidValue)
{
RaiseInvalidEntryEvent(entry);
return false;
}
return true;
}
public virtual void RaiseInvalidEntryEvent(ITnEntry entry)
{
if (OnInvalidEntry != null)
OnInvalidEntry(entry, "Invalid entry in list: " + entry.List.Name + ".");
}
}
// Had to reverse engineer the following since they were not available in the question
public interface ITnEntry
{
Ticket List { get; set; }
string Ticker { get; set; }
}
public class TnEntry : ITnEntry
{
public Ticket List { get; set; }
public string Ticker { get; set; }
}
public class Ticket
{
public string Name { get; set; }
}
NOTE: Some OOP evangalists have fits when things are declared public instead of private, basically unit testing and TDD have some requirements that pure OOP is at odds with. I've made RaiseInvalidEntryEvent public for simplicity, but normally I would make this internal and then expose the assembly to the unit test via InternalsVisibleTo. I've been doing TDD for the last 4 years now and rarely use private anymore.
And the unit tests would quickly be (note, this is using the MSTEST framework from VS2012)
[TestClass]
public class UnitTest1
{
#region TestHelpers
private ITnEntry MakeEntry(string ticker)
{
return new TnEntry {Ticker = ticker, List = new Ticket()};
}
#endregion
[TestMethod]
public void IsValidEntry_WithValidValues_ReturnsTrue()
{
// ARRANGE
var target = new EntryValidator();
var selectedEntry = MakeEntry("BOL");
// ACT
bool actual = target.IsValidEntry(selectedEntry, selectedEntry.Ticker);
// ASSERT
Assert.IsTrue(actual);
}
[TestMethod]
public void IsValidEntry_WithInValidTicker_ReturnsFalse()
{
// ARRANGE
var target = new EntryValidator();
var selectedEntry = MakeEntry("");
// ACT
bool actual = target.IsValidEntry(selectedEntry, selectedEntry.Ticker);
// ASSERT
Assert.IsFalse(actual);
}
[TestMethod]
public void IsValidEntry_WithInvalidTicker_RaisesEvent()
{
// ARRANGE
// generate a dynamic mock which will stub all virtual methods
var target = Rhino.Mocks.MockRepository.GenerateMock<EntryValidator>();
var selectedEntry = MakeEntry("");
// ACT
bool actual = target.IsValidEntry(selectedEntry, selectedEntry.Ticker);
// ASSERT
// assert that RaiseInvalidEntryEvent was called
target.AssertWasCalled(x => x.RaiseInvalidEntryEvent(Arg<ITnEntry>.Is.Anything));
}
[TestMethod]
public void RaiseInvalidEntryEvent_WithValidHandler_CallsDelegate()
{
// ARRANGE
var target = new EntryValidator();
var selectedEntry = MakeEntry("");
bool delegateCalled = false;
// attach a handler to set delegateCalled to true
target.OnInvalidEntry += delegate
{
delegateCalled = true;
};
// ACT
target.IsValidEntry(selectedEntry, selectedEntry.Ticker);
// ASSERT
Assert.IsTrue(delegateCalled);
}
}
Your test should subscribe to the event OnInvalidEntry with a dummy method, call IsValidEntry and check the result.
Is there a way to add arguments to an nunit setup method like this: public void SetUp(Point p = null) { /*code*/ }.
I tried it and got the following exception SetUp : System.Reflection.TargetParameterCountException : Parameter count mismatch
I think that your point is to avoid code duplication.
Try to extract base class with overriten method used in SetUp().
All derived class will execute tests from base class, with objects prepared in overriten OnSetUp()
[TestFixture]
public class BaseTestsClass
{
//some public/protected fields to be set in SetUp and OnSetUp
[SetUp]
public void SetUp()
{
//basic SetUp method
OnSetUp();
}
public virtual void OnSetUp()
{
}
[Test]
public void SomeTestCase()
{
//...
}
[Test]
public void SomeOtherTestCase()
{
//...
}
}
[TestFixture]
public class TestClassWithSpecificSetUp : BaseTestsClass
{
public virtual void OnSetUp()
{
//setup some fields
}
}
[TestFixture]
public class OtherTestClassWithSpecificSetUp : BaseTestsClass
{
public virtual void OnSetUp()
{
//setup some fields
}
}
Using parametrised TestFixture also can be usefull. Tests in class will be lunched per TestFixture, SetUp method also.
But remember that
Parameterized fixtures are (as you have discovered) limited by the fact that you can only use arguments that are permitted in attributes
Usage:
[TestFixture("some param", 123)]
[TestFixture("another param", 456)]
public class SomeTestsClass
{
private readonly string _firstParam;
private readonly int _secondParam;
public WhenNoFunctionCodeExpected(string firstParam, int secondParam)
{
_firstParam = firstParam;
_secondParam = secondParam;
}
[Test]
public void SomeTestCase()
{
...
}
}
I keep the test data for specific test method in folder named the same as function. I previously had the same function call in each [TestMethod], ClearAllAndLoadTestMethodData() which determined the method name via StackTrace. Now, I moved this function to [TestInitialize]. How can I find the name of the method that is about to be executed?
I thought TestContext provide this. I have access to it via [AssemblyInitialize()] and on first run its property Name is set to name of the testmethod. However, later this doesn't change (if I save the object in static field).
The AssemblyInitialize method is executed only once before all your tests.
Use the TestContext inside the TestInitialize method:
[TestClass]
public class TestClass
{
[TestInitialize]
public void TestIntialize()
{
string testMethodName = TestContext.TestName;
}
[TestMethod]
public void TestMethod()
{
}
public TestContext TestContext { get; set; }
}
[TestClass]
public class MyTestClass
{
private static TestContext _testContext;
[ClassInitialize]
public static void TestFixtureSetup(TestContext context)
{
_testContext = context;
}
[TestInitialize]
public void TestIntialize()
{
string testMethodName = MyTestClass._testContext.TestName;
switch (testMethodName)
{
case "TestMethodA":
//todo..
break;
case "TestMethodB":
//todo..
break;
default:
break;
}
}
[TestMethod]
public void TestMethodA()
{
}
[TestMethod]
public void TestMethodB()
{
}
}