Using an abstract base test class with approval tests - c#

Assuming I had a very good reason to want to do the tests below, how could I setup approval tests to name the .approved files UnitTest1.Test1.approved instead of BaseTest.Test1.approved? Thanks
public abstract class BaseTest
{
[TestMethod]
public void Test1()
{
Approvals.Verify(1);
}
[TestMethod]
public void Test2()
{
Approvals.Verify(2);
}
}
[TestClass]
public class UnitTest1 : BaseTest
{
public UnitTest1()
{
// some initialization
}
}
[TestClass]
public class UnitTest2 : BaseTest
{
public UnitTest2()
{
// some initialization
}
}
=== UPDATE ===
Based on Llewellyn's suggestion I added the following code to the ctor of the base class:
public BaseTest()
{
NamerFactory.AdditionalInformation = GetType().Name;
}
Works as expected, I get separate .approved files for each test.

That is an interesting assumption. I am assuming you would want both UnitTest1.Test1.approved & UnitTest2.Test1.approved
The short answer is not exactly, but there are a few work arounds.
WorkAround #1 - NamerFactory (BaseTest.Test1.UnitTest1.approved.txt)
You could rewrite the test to be
[TestMethod]
public void Test2()
{
NamerFactory.AdditionalInformation = this.GetType().Name;
Approvals.Verify(2);
}
btw: this is better with the using statement if you are using the nightly builds from myget https://www.myget.org/gallery/approvaltests
using (NamerFactory.AsEnvironmentSpecificTest(() => this.GetType().Name))
{
Approvals.Verify(1);
}
WorkAround #2 - Call from OutsideClass (UnitTest1.Test1.approved.txt)
You can extract the bulk of the method and then Call it from outside test. There is a good chance you might want all the functionality of a method, but still want the test to be in the extending class. The Approvals call does not need to be in the topmost test method. For example:
public abstract class BaseTest
{
public void Verify1()
{
// other code to do stuff
Approvals.Verify(1);
}
}
[TestClass]
public class UnitTest1 : BaseTest
{
public UnitTest1()
{
// some initialization
}
[TestMethod]
public void Test1()
{
Verify1();
}
}

Related

Overriding method in TestInitialize of Ms Unit Test Framework not working

I have a child class that implements my base class and the base class has a [TestClass] decorator. I want to call a Setup method in the child class from the base class but while debugging, execution does not make it to the child class and I'm not sure why. This is what I have:
[TestClass]
public class BaseTestClass
{
[TestInitialize]
public virtual void Setup() { }
}
Then in the child class I have this:
public class Child : BaseTestClass
{
public override void Setup()
{
// A lot of setup code
}
}
The overrided Setup() method is never invoked. What am I doing wrong? Thanks
#KeithNicholas You're reply made me think about what I was doing and I think I was going about this in the wrong way. I changed it to be like this:
[TestClass]
public class Child : Base
{
// All tests go here
[TestMethod]
public void TestSomething()
{ }
public class Base
{
// declare variables
[TestInitialize]
public void Setup()
{
// Create test records
}
[TestCleanup]
public void Teardown()
{
// Delete test records
}
I don't know which way is better, but I was never able to get execution to step into the overrided Setup() method even when only putting the [TestInitialize] decorator on the that method only.

NUnit - Fails with TestFixtureSetUp method not allowed on a SetUpFixture

I am trying to re-organise some Integration Tests we have so that they use a common class for creating a Database and the Data required in the Database to Test against in other classes in the same assembly using [SetUpFixture] NUnit attribute.
I have :
namespace Tests;
public class TestBaseClass : SolutionBaseClass
{
public void Setup()
{
base.CreateDatabase();
base.CreateData();
}
public void Teardown()
{
base.DestroyDatabase();
}
}
[SetUpFixture]
public class Setup : TestBaseClass
{
[SetUp]
public void Setup()
{
base.Setup();
}
[TearDown]
public void Teardown()
{
base.Teardown();
}
}
then individual test fixture classes:
namespace Tests.Services;
[TestFixture]
public class LibraryTest : TestBaseClass
{
[TestFixtureSetUp]
public void SetupTests()
{
// I know am calling the same Setup twice once from SetUpFixture and TestFixture,
// I have handled it so that only one Database/Data gets set up once (for safety mostly!)
base.SetUp();
// Other class initialisations.
}
}
Any ideas what I am doing wrong, I figure it is a problem with the inheritance model being used, as you can tell I am inheriting this from someone else!!
Thanks.
In NUnit 3 one should use OneTimeSetUpAttribute and OneTimeTearDownAttribute on the static methods of the [SetUpFixture] class. Source: http://bartwullems.blogspot.nl/2015/12/upgrading-to-nunit-30-onetimesetup.html
In NUnit 2.0
[SetUpFixture]
class TestHost
{
[SetUp]
public static void AssemblyInitalize()
{
//Global initialization logic here
}
}
In NUnit 3.0
[SetUpFixture]
class TestHost
{
[OneTimeSetUp]
public static void AssemblyInitalize()
{
//Global initialization logic here
}
}
In NUnit 3.0 TestFixtureSetUp and TestFixtureTearDown has been renamed to OneTimeSetUp and OneTimeTearDown.
Here is the documentation link for above changes:
SetUp and TearDown Changes

MsTest ClassInitialize and Inheritance

I have a base class for my tests which is composed in the following way:
[TestClass]
public abstract class MyBaseTest
{
protected static string myField = "";
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
// static field initialization
myField = "new value";
}
}
Now I am trying to create a new test that inherits from the base, with the following signature:
[TestClass]
public class MyTest : MyBaseTest
{
[TestMethod]
public void BaseMethod_ShouldHave_FieldInitialized()
{
Assert.IsTrue(myField == "new value");
}
}
The ClassInitialize is never called by the child tests ... What is the real and correct way of using test initialization with inheritance on MsTest?
Unfortunately you cannot achieve this that way because the ClassInitializeAttribute Class cannot be inherited.
An inherited attribute can be used by the sub-classes of the classes that use it. Since the ClassInitializeAttribute cannot not be inherited, when the MyTest class is initialized the ClassInitialize method from the MyBaseTest class cannot be called.
Try to solve it with another way. A less efficient way is to define again the ClassInitialize method in MyTest and just call the base method instead of duplicating the code.
A potential workaround is to define a new class with AssemblyInitializeAttribute instead. It has a different scope, obviously, but for me it meets my needs (cross-cutting concerns, which just so happen to require exactly the same settings for every test class and test method.)
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MyTests
{
[TestClass]
public sealed class TestAssemblyInitialize
{
[AssemblyInitialize]
public static void Initialize(TestContext context)
{
...
}
}
}
Use a static constructor on a base class? It's executed only once, by design, and it doesn't have the weird limitation on inheritance, like the ClassInitializeAttribute.
There is a parameter for the ClassInitialize and ClassCleanup attributes:
[ClassInitialize(InheritanceBehavior.BeforeEachDerivedClass)]
public static void ClassInitialize(TestContext context)
{
// gets called once for each class derived from this class
// on initialization
}
[ClassCleanup(InheritanceBehavior.BeforeEachDerivedClass)]
public static void Cleanup()
{
// gets called once for each class derived from this class
// on cleanup
}
which will actually do what you want.
UPDATE: Added lock to avoid multi-threading issues...
We know that a new instance of the class is constructed for every [TestMethod] in the class as it gets run. The parameter-less constructor of the base class will be called each time this happens. Couldn't you simply create a static variable in the base class and test it when constructor runs?
This helps you to not forget to put the initialization code in the sub-class.
Not sure if there's any drawback to this approach...
Like so:
public class TestBase
{
private static bool _isInitialized = false;
private object _locker = new object();
public TestBase()
{
lock (_locker)
{
if (!_isInitialized)
{
TestClassInitialize();
_isInitialized = true;
}
}
}
public void TestClassInitialize()
{
// Do one-time init stuff
}
}
public class SalesOrderTotals_Test : TestBase
{
[TestMethod]
public void TotalsCalulateWhenThereIsNoSalesTax()
{
}
[TestMethod]
public void TotalsCalulateWhenThereIsSalesTax()
{
}
}

used in multiple [TestFixture]s

I'm in the process of setting up tests in NUnit and have a newbie question.
Is it possible to have a Test/s that could be used in multiple [TestFixture]s?
So
[Test]ValidateString(string bob)
Could be called in a series of different [TestFixture]?
That doesn't sound like a test to me. Tests are typically parameterless (unless you're using [TestCase]s) and running it within a context of a single fixture would typically be enough -- it either passes once and that's good or it doesn't and it's a broken test.
If you just have a method that does some validation on a string, you could set it up as a static method on some class (e.g. TestHelpers) and call it from whatever tests (in multiple test fixtures) need it.
Here's another idea: inheritance. You can have a base fixture that has all your tests, and then fixtures that inherit from it that set up whatever variables you need. The tests will run for each fixture. I'm not familiar with Selenium RC, but you should be able to adapt the code below to set up whatever variables you need in various fixtures.
[TestFixture]
public class BaseFixtureTests
{
protected IMyClass _myClass;
[TestFixtureSetUp]
public void FixtureSetup()
{
_myClass = ConfigureMyClass();
}
protected virtual IMyClass ConfigureMyClass()
{
// fixtures that inherit from this will set up _myClass here as they see fit.
}
[Test]
public void MyClassTest1()
{
// test something about _myClass;
}
}
[TestFixture]
public class MySpecificFixture1 : BaseFixtureTests
{
protected override IMyClass ConfigureMyClass()
{
return new MySpecificMyClassImplementation();
}
}
public class MySpecificMyClassImplementation : IMyClass
{
//some implementation
}
You can also add extra tests in each fixture as well that don't test common functionality and don't need to be reused across fixtures.
The newer version of NUnit supports generics. This is a great fit if what you are testing doesn’t need to be configured (only created) from your test code. Here is an example copied from http://nunit.net/blogs/:
[TestFixture(typeof(ArrayList))]
[TestFixture(typeof(List<int>))]
public class IList_Tests<TList> where TList : IList, new()
{
private IList list;
[SetUp]
public void CreateList()
{
this.list = new TList();
}
[Test]
public void CanAddToList()
{
list.Add(1); list.Add(2); list.Add(3);
Assert.AreEqual(3, list.Count);
}
}
I’ve also used Anna’s approach of inheritance. One possible refinement to her example (depending on personal preference): Don’t mark the base class as a TestFixture, only the child classes. Each class that you mark as a TestFixture will be displayed as a set of tests in the NUnit client. You will probably never want to run the base class methods directly because the child is providing all of the setup code. If you remove TestFixture from the base class, running invalid tests won’t be an option in the UI. This allows you to run all the tests and see all green… always a nice feeling.
You might be able to achieve what you want with inheritance.
using NUnit.Framework;
namespace ClassLibrary1
{
[TestFixture]
public class TestFixtureBase
{
[SetUp]
public virtual void Setup()
{
// setup code here
}
[Test]
public void CommonTest1()
{
Assert.True(true);
}
[Test]
public void CommonTest2()
{
Assert.False(false);
}
}
public class MyClassTests : TestFixtureBase
{
[SetUp]
public override void Setup()
{
base.Setup();
// additional setup code
}
[Test]
public void MyClassTest1()
{
Assert.True(true);
}
}
}
You can write a method to be called from multiple [Test] methods. But I don't think there is a way to have the same [Test] included in multiple [TestFixture]s.
[TestFixture]
public class TestsOne{
[Test] public void TryOne(){
Helpers.ValidateString("Work?");
}
}
[TestFixture]
public class TestsTwo{
[Test] public void TryTwo(){
Helpers.ValidateString("Work?");
}
}
public static class Helpers{
public static void ValidateString(string s){
Assert.IsNotNull(s);
}
}

NUnit executes with alternate constructor

I have a class which has some unit tests, but when I am running tests I would like the class to be created with a different constructor. Something like this:
[TestFixture]
public class MyClass
{
public MyClass() { /* set up for production */ }
[TestFixtureConstructor]
public MyClass() { /* set up for testing */ }
[Test]
public void FirstTest()
{
// assert some values
}
}
Is this even possible?
I have considered using a static factory method for creating the class in production (with a private constructor), and a public constructor for the testing framework.
Does anyone have any other solutions?
You don't do this.
You do not have your tests written inside the class that you use in real code; you write your tests external to the classes. I believe most testing suites have the concept of 'Teardown' and the opposite; to set up the test environment for a given execution.
To give a quick example of silky's correct approach:
public class MyClass
{
// ...
}
// In a different assembly:
[TestFixture]
public class TestMyClass
{
[SetUp]
public void SetUp()
{
_myClass = new MyClass();
}
[Test]
public void FooReturnsTrue()
{
Assert.That(_myClass.Foo(), Is.True);
}
// more tests
private MyClass _myClass;
}
If you really really want this you can take a look at TestFixtureSetUp.
Here's the introduction:
This attribute is used inside a TestFixture to provide a single set of functions that are performed once prior to executing any of the tests in the fixture. A TestFixture can have only one TestFixtureSetUp method. If more than one is defined the TestFixture will compile successfully but its tests will not run.
Example:
namespace NUnit.Tests
{
using System;
using NUnit.Framework;
[TestFixture]
public class SuccessTests
{
[TestFixtureSetUp] public void Init()
{ /* ... */ }
[TestFixtureTearDown] public void Dispose()
{ /* ... */ }
[Test] public void Add()
{ /* ... */ }
}
}
But you should use this with care, or else it defeats the purpose of unit test.

Categories

Resources