Reputation: 3462
My unit tests (MSTest, using Resharper to run manually) has a number of tests against a particular implementation of an FtpClient. I started off with an implementation of AlexFTP and then switched over to WinSCP when I needed to support SFTP (not just FTP and FTPS). I have a common interface, IFtpClient that all my test cases are based off of.
My question, which has nothing to do with Ftp, is how can I run my suite of test cases for each implementation of an interface?
My code structure looks something like this, and I currently uncomment/comment out the the implementation I want to test
public IFtpClient GetFtpClient()
{
return new AlexPilottiFtpClient();
// return new WinScpFtpClient();
}
and then I have my test code
[TestMethod]
public void Should_connect_with_valid_credentials()
{
IFtpClient client = base.GetFtpClient();
client.Connect(....)
Assert(....)
}
[TestMethod]
public void Another_Test2()
{
IFtpClient client = base.GetFtpClient();
...
}
[TestMethod]
public void Another_Test3()
{
IFtpClient client = base.GetFtpClient();
...
}
Anyone have ideas how I can run both (or multiple) implementations as part of my run? Some ideas I can think of include:
1) for loop of each implementation, inside each TestMethod e.g.
[TestMethod]
public void Another_Test4()
{
foreach (IFtpClient client in _clientList)
{
...
}
}
2) duplicate the test methods - one for each implementation and maybe a base method common to all e.g.
[TestMethod]
public void Another_Test5_AlexFtp()
{
_client = new AlexPilottiFtpClient();
this.Another_Test5_Base();
}
[TestMethod]
public void Another_Test5_WinScp()
{
_client = new WinScpFtpClient();
this.Another_Test5_Base();
}
private void Another_Test5_Base()
{
_client.Conect(...);
Assert(...);
}
3) reside myself that I can't do it (manually) and rely on automated builds to run through all implementations, e.g. via configuration / dependency injection
??? Suggestions would be greatly appreciated. Thanks.
Upvotes: 2
Views: 174
Reputation: 164331
I would most likely make an abstract base class defining all the tests, with a single abstract method that returns the implementation of IFtpClient
to test.
Then make concrete test classes for each implementation you need to test.
So you would have:
public abstract class FtpBaseTest
{
public abstract IFtpClient GetClient();
[TestMethod]
public void TestOne()
{
IFtpClient client = GetClient();
// do test on client ...
}
[TestMethod]
public void TestTwo()
{
IFtpClient client = GetClient();
// another test on client ...
}
}
[TestClass]
public class AlexFtpTest
{
public override IFtpClient GetClient() { return new AlexFtpClient(..); }
}
[TestClass]
public class AnotherFtpTest
{
public override IFtpClient GetClient() { return new AnotherFtpClient(..); }
}
This would make the tests appear in the runner as separate test cases in different test classes, even though you only have the implementation once.
Upvotes: 2