12

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...

2
  • 3
    I think if you do this you will have trouble running your tests automatically in a CI (Continuous Itegration) environment. Commented Sep 5, 2009 at 4:08
  • You're absolutely right. However, it's a small community project, so CI is not really an issue, at least for now. Commented Sep 5, 2009 at 12:28

5 Answers 5

22

Use the TestCase attribute.

[TestCase("User1", "")]
[TestCase("", "Pass123")]
[TestCase("xxxxxx", "xxxxxx")]
public void TestLogin(string userName, string password)
{
    // ...
}
Sign up to request clarification or add additional context in comments.

3 Comments

+1. This is far better than the chosen answer by handling dependency injection right in the TestCase() parameters instead of parroting off "no arguments in the method". unfortunately, I don't think MS Unit Test has anything like this, just Nunit
This is the correct and short answer. It doesn't matter if this is a good or bad practice.
Please mark this as the correct answer. This answers the question and for me is not bad practice to use params in general. For passwords i'd be less inclined.
2

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

MS Unit tests don't allow the passing of parameters to tests. Instead you need to create Datadriven Unit tests. Try the link, it may help you.

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


Update: I was young :). Consider Sarfraz's answer instead on how to pass parameters to NUnit tests.

6 Comments

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...
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?
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: stackoverflow.com/questions/1257560/…
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 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).
|
2

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);
 }
} 

2 Comments

Thanks for your answer. I think this plugin is made obsolete by the TestCaseAttribute new in NUnit 2.5 (nunit.org/index.php?p=testCase&r=2.5). Anyway, it doesn't solve my problem : I don't want to hard-code my credentials. I want a prompt to enter it manually when the test is run
Ah ok. I misunderstood. Nice to know about TestCaseAttribute though :)
0

I agree with the other answers that passing arguments may not be best practise, but neither is hard coding credentials or server addresses that may change at some point.

Inspired by the suggested solution in question, I simply read console input instead of using input boxes. The arguments are saved in a file. When starting a the tests, the file is redirected and to be read from some initialization function that should be called before any test cases run.

nunit tests.dll < test.config

This avoids user interaction and should be runnable by any automation script. Downside is that the password still has to be saved somewhere, but at least it can be saved local on the testers machine and is easy to change.

This was for a project, where excel sheets containing the tests (not unit tests by definition) were used to let others create test cases for a bigger server side project without changing any code. It would have been bad if all test cases had to be forced in a single giant excel sheet. Also there was no CI, just many testing environments on different servers.

Comments

0

Create a class and store the details of the required variable in const. Note: If you create variable as static then it won't work in the Nunit framework.

public Class Credential
{
    public const string PUBLIC_USER = "[email protected]";
    public const string PASSWORD= "password123";
}

[Test]
[TestCase(Credential.PUBLIC_USER, Credential.PASSWORD)]
public void VerifyLogin(string username, string password)
 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.