views:

562

answers:

3

Hi,

I'm writing unit tests with NUnit and the TestDriven.NET plugin. I'd like to provide parameters to a test method like this :

[TestFixture]
public class MyTests
{
    [Test]
    public void TestLogin(string userName, string password)
    {
        // ...
    }

    ...
}

As you can see, these parameters are private data, so I don't want to hard-code them or put them in a file. Actually I don't want to write them anywhere, I want to be prompted each time I run the test.

When I try to run this test, I get the following message in the output window :

TestCase 'MyProject.MyTests.TestLogin' not executed: No arguments were provided

So my question is, how do I provide these parameters ? I expected TestDriven.NET to display a prompt so that I can enter the values, but it didn't...

Sorry if my question seems stupid, the answer is probably very simple, but I couldn't find anything useful on Google...


EDIT: I just found a way to do it, but it's a dirty trick...

    [Test, TestCaseSource("PromptCredentials")]
    public void TestLogin(string userName, string password)
    {
        // ...
    }

    static object[] PromptCredentials
    {
        get
        {
            string userName = Interaction.InputBox("Enter user name", "Test parameters", "", -1, -1);
            string password = Interaction.InputBox("Enter password", "Test parameters", "", -1, -1);
            return new object[]
            {
                new object[] { userName, password }
            };
        }
    }

I'm still interested in a better solution...

A: 

Hi, I think you can solve this problem by using the RowTest plugin for NUnit found here http://www.andreas-schlapsi.com/2008/01/29/rowtest-extension-120/

You can create simple Data-Driven Tests where the test data is provided by [Row] attributes. So here is an example of a test that is run over and over again with different parameters:

[TestFixture]
public class RowTestSample
{
 [RowTest]
 [Row( 1000, 10, 100.0000)]
 [Row(-1000, 10, -100.0000)]
 [Row( 1000, 7, 142.85715)]
 [Row( 1000, 0.00001, 100000000)]
 [Row(4195835, 3145729, 1.3338196)]
 public void DivisionTest(double numerator, double denominator, double result)
 {
  Assert.AreEqual(result, numerator / denominator, 0.00001);
 }
}
Roberto Sebestyen
Thomas Levesque
Ah ok. I misunderstood. Nice to know about TestCaseAttribute though :)
Roberto Sebestyen
+2  A: 

Unit Tests should normally not take any parameters. You create the necessary data within the test itself.

  • The expected value
  • You call your method you want to test passing the necessary arguments
  • You compare the result with the expected value and the returned value from your tested method

This is how you usually proceed. MS Unit tests provide a handy way for automating this. They call it Datadriven Unit testing. Try the link, it may help you.

As I mentioned. I wouldn't declare passing arguments to unit tests itself good practice.

Juri
Thanks, but again, it doesn't solve my problem... How am I supposed to run a test which requires credentials ? I don't want to put my personal username and password in a code that will be shared with others...
Thomas Levesque
In such a case use dummy credentials. What kind of logic is your unit test supposed to cover s.t. you need credential handling etc?
Juri
Oh, I now read your edited post. Couldn't you just use some dummy credentials. A test-user + pass which has the right to access what you need to achieve? Although I'm not quite sure whether the kind of thing you want to reach is really what should be tested by a unit test. Check this: http://stackoverflow.com/questions/1257560/when-is-a-test-not-a-unit-test/1369982#1369982
Juri
The component I'm testing connects to VBulletin forum to retrieve authentication cookies. Maybe I could create a dummy account... or perhaps you're right and this shouldn't even be a unit test ;)
Thomas Levesque
Understand...well it's always a bit "discussable" what is and what isn't a unit test. In your case I'd say this isn't really what I would capture with a unit test. What I would do is to provide a Dummy authentication cookie and inject it somehow to fake a call to VBulletin. In this way I would test what my logic does with a correct cookie and what with a wrong one. That's in my eye what should be captured with a unit test.
Juri
Juri and J.R. Garcia are correct. You want unattended, automated tests - that way you can run them from a build server, etc. The way to do this is to use dependency injection with a dummy (stub) object that handles your authentication. In the actual app, you inject the true authentication scheme (implementing the same interface).
TrueWill
+1  A: 

No .NET testing frameworks allow you to write unit tests with parameters. Each individual test should be able to be run without any interaction. You should be faking credentials. If you need access to another service you should be faking that service if possible. Also, remember that you should only be testing code that you have written and not a third-party providers.

J.R. Garcia
Thomas Levesque