Today I ran XtUnit at a part of my unit testing framework to to rollback database changes created while running a test case. This is a skeleton of how I have used it. The Test case ran successfully but the database state changed as a result.
using NUnit.Framework;
using TeamAgile.ApplicationBlocks.Interception;
using TeamAgile.ApplicationBlocks.Interception.UnitTestExtensions;
namespace NameSpace.UnitTest
{
[TestFixture]
public class Test : InterceptableObject
{
[Test]
[DataRollBack]
public void CreateTest()
{
I use Nhibernate with Mysql. Am I missing something?
I think your test fixture needs to extend ExtensibleFixture, not InterceptableObject. In the XtUnit source, ExtensibleFixture itself inherits from InterceptableObject. The comments in ExtensibleFixture.cs state:
This is the base class for all the test fixtures you will
have in your project. You MUST inherit from this in order
for the custom attributes to work. No other special action is needed.
Database and your program must be run under WindowsXP SP2 oder Server 2003.
Related
I want to add a custom test reporter to NUnit. I already did it with NUnit2, but I now need to use NUnit3.
To implement the reporter, I need to get various events from the framework, like start, end and failure of tests.
In NUnit2 I used NUnitHook to register my EventListener and it worked pretty good.
In NUnit3 I need to use the extension point mechanism, but when I add the extension point to the project, VisualStudio (2012 ultimate) immediately fails to discover the NUnit tests.
[TypeExtensionPoint(Description = "Test Reporter Extension")]
public class MyTestEventListener : ITestEventListener
{
public void OnTestEvent(string report)
{
Console.WriteLine(report);
}
}
If I remove the ITestEventListener implementation declaration from the class, it rediscovers the tests perfectly.
[TypeExtensionPoint(Description = "Test Reporter Extension")]
public class MyTestEventListener //: ITestEventListener
{
public void OnTestEvent(string report)
{
Console.WriteLine(report);
}
}
Am I doing something wrong? is there a better way to achieve it?
You don't say where you are putting this code, but I am suspecting it's in your test assembly. If so, that's not where it belongs. NUnit engine extensions get installed into the NUnit engine, so they need to be in a separate assembly. Once you have a separate assembly, you need to tell the engine where it is. Currently, you do this by creating a file of type .addins in the same directory as the engine. (You could modify the existing file, but that introduces maintenance problems in the future)
A future release will have an easier way to install addins, but they will continue to be entirely separate from your tests.
A further problem is that you are using TypeExtensionPointAttribute. I didn't notice this originally in your code and it's probably the biggest error so I'm adding this info now.
An "ExtensionPoint" is the thing you are extending. NUnit defines ExtensionPoints, while you create Extenisons to extend them. TypeExtensionPointAttribute is used inside NUnit to define extension points. It's not used by you. You use the ExtensionAttribute to define your extension.
Your extension should be defined something like this:
[Extension(Description = "Test Reporter Extension", EngineVersion="3.4")]
public class MyTestEventListener : ITestEventListener
{
public void OnTestEvent(string report)
{
Console.WriteLine(report);
}
}
You don't say what version of NUnit you are running. Test Listeners are only supported beginning with version 3.4. The EngineVersion property above is purely documentary at this point, because 3.4 is also the first version to recognize it.
There is a new writeup in the NUnit docs that may be helpful: https://github.com/nunit/docs/wiki/Writing-Engine-Extensions
For years we have used the following code to setup databases in a base class for our functional tests for our DAL, and this has worked extremely well for us.
/// <summary>
/// Initializes the test class by creating the integration database.
/// </summary>
[TestInitialize]
public virtual void TestInitialize()
{
DataContext = new DataContext(ConnectionString);
CleanupPreviousTestRunDatabases();
if (DataContext.Database.Exists())
{
DataContext.Database.Delete();
}
DataContext.Database.Create();
DataContext.Database.ExecuteSqlCommand(String.Format(Strings.CreateLoginCommand, DatabaseUserName, DatabasePassword));
DataContext.Database.ExecuteSqlCommand(String.Format("CREATE USER {0} FOR LOGIN {0}", DatabaseUserName));
DataContext.Database.ExecuteSqlCommand(String.Format("EXEC sp_addrolemember 'db_owner', '{0}'", DatabaseUserName));
}
However, using Entity Framework does not setup all components of a database and we would like to catch discrepancies between our EF DAL model and the actual database.
We use the SSDT tools / Visual Studio Database Project for all of our database work, and I know you can write SQL unit tests, and in those SQL unit tests, I have seen the ability to setup and create a database based on the database project itself. This is what I would like to do, but from our other functional test libraries.
I can reference the libraries and write some of the setup code, but what I'm looking for is:
a) How do I provide which Database project to use to deploy?
b) How can I specify connection string in code rather than an app.config, such as using localdb instead with a dynamically named database?
namespace Product.Data.Tests
{
using Microsoft.Data.Tools.Schema.Sql.UnitTesting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class FunctionalTest
{
[TestInitialize]
public virtual void TestInitialize()
{
SqlDatabaseTestClass.TestService.DeployDatabaseProject();
SqlDatabaseTestClass.TestService.GenerateData();
}
}
}
The app.config in a SQL Unit Test Project doesn't contain any reference back to the original Database project used to create it, and decompiling some of the test code and seeing how it works, I don't see any indication. Does it assume there is only one database project in the solution?
With some direction from the links #Ed Elliott posted, I was able to make this happen. You will need to add Microsoft.SqlServer.Dac as a assembly reference from C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\120\Microsoft.SqlServer.Dac.dll (Visual Studio 2015). It is part of the SSDT tooling, so I'm sure the path may be different for earlier versions.
[TestClass]
public class DatabaseTest
{
protected string DatabaseConnectionString = $#"Data Source=(localdb)\v11.0; Integrated Security=True";
protected DatabaseContext DatabaseContext;
protected string DatabaseName = $"UnitTestDB_{Guid.NewGuid().ToString("N").ToUpper()}";
public TestContext TestContext { get; set; }
[TestInitialize]
public virtual void TestInitialize()
{
var instance = new DacServices(DatabaseConnectionString);
var path = Path.GetFullPath(Path.Combine(TestContext.TestDir,
#"..\..\..\Build\Database\Database.dacpac"));
using (var dacpac = DacPackage.Load(path))
{
instance.Deploy(dacpac, DatabaseName);
}
DatabaseContext = new DatabaseContext(DatabaseConnectionString);
}
[TestCleanup]
public virtual void TestCleanup()
{
DeleteDatabase(DatabaseName);
}
}
Then how it would be used for a functional test in a unit test project.
[TestClass]
public class CustomerTypeTests : DatabaseTest
{
private CustomerType customerType;
[TestInitialize]
public override void TestInitialize()
{
base.TestInitialize();
customerType = new CustomerType
{
Name = "Customer Type"
};
}
[TestMethod]
public void AddOrUpdateCustomerType_ThrowExceptionIfNameIsNull()
{
ExceptionAssert.Throws<ArgumentNullException>(() => DatabaseContext.AddOrUpdateCustomerType(customerType));
}
}
Just a note to others, you should also setup your Build Dependencies so that your unit test project depends on the database project, ensuring it is built first and produces the correct dacpac file.
What this solves for us, is this gives us a true database, not one just based on Entity Framework's model, which lacks quite a lot of SQL constructs (to be expected), especially default constraints, indexes, and other important elements of a database. At our DAL layer, this is essential for us.
I think the process you have is a little over complicated (if I understand it correctly which I might not have!).
What I do for unit testing in ssdt is to:
Build the solution
Deploy each dacpac that I need to my dev instance
Run the tests
To deploy a project there are a few ways, you can:
Create a "Publish Profile" for each project and run that
Right click on the project and choose publish
Use a powershell script (or do it in code in your test initialize) to do a publish of the dacpac.
Once it is deployed run your tests, doing a publish of a dacpac (project) is pretty simple from code or a script, you can either:
call sqlpackage.exe to do it for you
use the dacfx api's to do the deploy (http://blogs.msmvps.com/deborahk/deploying-a-dacpac-with-dacfx-api/)
If you control the publish yourself then it gives you a lot more control plus when you deploly using this you are testing the same deployment system that you will use in other environments (assuming you use dacpac's to deploy).
ed
I have the following code:
[TestFixture]
public class LexicalTests
{
[Test]
public void LexicalTest1()
{
TestContext.CurrentContext.TestDirectory;
}
}
CurrentContext throws an exception while attempting to get TestDirectory or WorkingDirectory property.
How can I solve this problem?
P.S.: On my home PC tests work perfectly (without strange exceptions).
It seems that some applications that offer the functionality to run NUnit unit tests have a problem with the TestContext class.
The test in class below should pass:
using NUnit.Framework;
namespace UnitTests
{
[TestFixture]
public class UnitTests
{
[Test]
public void CurrentContextTest()
{
Assert.IsNotNull(TestContext.CurrentContext);
Assert.IsNotNull(TestContext.CurrentContext.TestDirectory);
Assert.IsNotNull(TestContext.CurrentContext.WorkDirectory);
}
}
}
If the test doesn't pass then, as Dmitry wrote in his comment above, change the NUnit version in the ReSharper menu. From within Visual Studio, go to ReSharper -> Options -> Tools -> NUnit. Click the Specified NUnit installation radio button and ensure that a folder with nunit.core.dll, nunit.core.interfaces.dll and nunit.util.dll is specified. An error will be displayed if the listed files cannot be found.
Once the NUnit version has been changed, re-run the test and it should pass.
Has anyone got a strategy for unit testing heiarchies in Resharper?
I typically use both TestDriven.Net and Resharper's test runner, with NUnit tests. TestDriven is awesome for everything but quickly finding a bad test out of a batch run (which could be thousands), which is where Resharper's runner comes in.
I typically use a pattern with an abstract base class (like the code below) of test cases overridden to get the right subclass, which works great in TestDriven, but Resharper just ignores them! I had thought as of v5.0 Resharper was using NUnit's code base, which means this should work but it doesn't.
Cheers,
Berryl
[TestFixture]
public class AdminAccountTests : AccountTests
{
protected override Account _GetAccount() { return new AdminAccount(_idScheme, _description); }
}
[TestFixture]
public class LeaveTimeAccountTests : AccountTests
{
protected override Account _GetAccount() { return new LeaveTimeAccount(_idScheme, _description); }
}
public abstract class AccountTests
{
protected abstract Account _GetAccount();
[SetUp]
public void SetUp()
{
_account = _GetAccount();
}
[Test]
public void OnCreation_Blah() {
Assert.That(_account.IdScheme, Is.EqualTo(_idScheme));
}
}
Make your abstract class a TestFixture. I do this same thing with R#.
EDIT: I just noticed that R# (I'm using 5.1 with NUnit 2.6) will mark a class as a test fixture if it has Tests in it, regardless of whether the subclass or the base class are attributed with TestFixture. So that may not solve your problem.
I have the same issue with MbUnit and Gallio with resharper 5.1.3000.12. If i try to launch the test through visual studio plugin, the test is ignored. With external gallio test runner, it works fine.
JetBrains ReSharper 5.1 C# Edition
Build 5.1.3000.12 on 2011-01-28T05:05:56
Plugins:
1. “Gallio Test Runner” v3.2.0.0 by Gallio
Visual Studio 9.0.30729.1.
Copyright © 2003–2011 JetBrains s.r.o.. All rights reserved.
Banging my head against a wall trying to get a really simple testing scenario working.
I'm sure I'm missing something really simple!
Whatever I do, I seem to get the following error from the NUnit gui when running a test against my DLL:
System.TypeLoadException : Type 'Castle.Proxies.ITestProxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is attempting to implement an inaccessible interface.
Now I've seen reference to this error in heaps of places when looking in Stack Overflow and elsewhere, but the solution I keep finding doesn't seem to help. And I'm not even using an internal interface at this stage! The solution I see around the place is too put the following line in AssemblyInfo.cs
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
I'm using:
Visual Studio 2010 Professional
c# 4.0
Moq 4.10810.8 Beta (bin deployed)
NUnit 2.5.5 (Installed in GAC)
To recreate this error, all I need to do is:
Create a new class library project
Reference Moq and Unit (as above)
Create an interface. I've called my interface ITest, made it public, and it has one method which is 'string TestMethod();'. Am doing this in the local project for simplicity.
Create a class called 'Testing', decorated with [TextFixture] and a test method called 'TestMethod' decorated with [Test]
Build the project, then run NUnit against the resulting dll in the Debug folder.
Here's the contents of my test class
namespace MoqTest {
[TestFixture]
public class Testing {
[Test]
public void TestMethod() {
var testMock = new Mock<ITest>();
testMock.Setup(x => x.TestMethod()).Returns("String val");
var xyz = testMock.Object;
Assert.AreEqual(1, 1);
}
}
}
---- UPDATE ---
After changing Moq version from 4.10810.8 to 4.0.10501.6 everything works fine!
The following test passes for me:
public interface ITest { string TestMethod(); }
public class Testing
{
[Test]
public void TestMethod()
{
var testMock = new Mock<ITest>();
testMock.Setup(x => x.TestMethod()).Returns("String val");
var xyz = testMock.Object;
Assert.AreEqual(1, 1);
}
}
If your interface is public and in the same assembly, there really should be no problem. I suspect that you just missed an accessibility keyword somewhere, as a non-public interface does provoke a runtime error because the proxying assembly will be unable to instantiate a type based on it.
Probably the best thing to do is start with the code I've provided and change one thing at a time until it matches your failing code. If you run your test in between each change, I presume you'll find what was missing.
If you do go back to an internal interface, note that your InternalsVisibleTo statement must be in the same assembly as your internal interface, not your test assembly. Also note that if your assembly is strongly named you may need to add a public key fingerprint to your InternalsVisibleTo statement as described in MSDN.
Yeah I had the same issue with Moq.4.0.10810.8 for NET40... When I downgraded to version 4.0.10531.7 everything went green again!
I'm using 4.10.1 now, and I got this same issue. I tried downgrading to 4.10.0, but to no avail.
I finally found that, although the interface I was using was marked as public, it was in a class without a modifier. I found 2 things got it to work:
1) Pull the interface outside of the class. Because the class was no longer making the interface internal, it became accessible to the assembly.
2) Mark the class public. With all parts of the path to the interface being marked public, the assembly had no trouble accessing.
These strategies worked in both 4.10.0 and 4.10.1.