Raymond
Raymond

Reputation: 3462

running a set of unit tests for each 'implementation'

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

Answers (1)

driis
driis

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

Related Questions