safary
safary

Reputation: 325

How to use variables between unit tests? c# webdriver

Im begginer in webdriver and c#. I want to use variable, from first test in another tests, how do I do that? I got to this point with some examples, but it does not work. I see that first test gets the login right, but when I start the second test and try to sendkeys, I get that loginName is null. (code is in short version, only to give you an idea of what Im trying to do)

[TestFixture]
public class TestClass
{
    private IWebDriver driver;
    private StringBuilder verificationErrors;
    private string baseURL;
    private bool acceptNextAlert = true;
    static public String loginName;
    static public String loginPassword;

    [SetUp]
    public void SetupTest()...

    [TearDown]
    public void TeardownTest()...

    [Test]
    public void GetLoginAndPassword()
    {
        loginName = driver.FindElement(By.XPath("...")).Text;
        loginPassword = driver.FindElement(By.XPath("...")).Text;
        Console.WriteLine(loginName);
    }
    [Test]
    public void Test1()
    {
        driver.FindElement(By.Id("UserNameOrEmail")).SendKeys(loginName);
        driver.FindElement(By.Id("Password")).SendKeys(loginPassword);
    }

Upvotes: 0

Views: 1607

Answers (3)

Harald Coppoolse
Harald Coppoolse

Reputation: 30454

The purpose of unit testing is to test if a specific unit (meaning a group of closely related classes) works as specified. It is not meant to test if your complete elaborate program works as specified.

Test driven design has the advantage that you are more aware what each function should do. Each function is supposes to transform a pre-condition into a specified post-condition, regardless of what you did before or after calling the function.

If your tests assume that other tests are run before your test is run, then you won't test the use case that the other functions are not called, or only some of these other required functions are called.

This leads to the conclusion that each test method should be able to be run independently. Each test should set up the precondition, call the function and check if the postcondition is met.

But what if my function A only works correctly if other function B is called?

In that case the specification of A ought to describe what happens if B was called before A was called, as well as what would happen if A was called without calling B first.

If your unit test would first test B and then A with the prerequisite that B was called, you would not test whether A would react according to specification without calling B.

Example.

Suppose we have a divider class, that will divide any number by a given denominator that can be set using a property.

public class Divider
{
    public double Denominator {get; set;}

    public double Divide(double numerator)
    {
        return numerator / this.Denominator;
    }
}

It is obvious that in normal usage one ought to set property Denominator before calling Divide:

Divider divider = new divider(){Denominator = 3.14};
Console.WriteLine(divider.Divide(10);

Your specification ought to describe what happens if Divide is called without setting Denominator to a non-zero value. This description would be like:

If method Divide is called with a parameter value X and the value of Denominator is a non-zero Y, then the return value is X/Y. If the value of Denominator is zero, then the System.DivideByZeroException is thrown.

You should create at least two tests. One for the use case that Denominator was set at a proper non-zero value, and one for the use case that the Denominator is not set at all. And if you are very thorough: a test for the use case that the Denominator is first set to a non-zero value and then to a zero value.

Upvotes: 0

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37000

The problem is that the methods marked with TestAttribute do not run sequentially in the same order you implemented them. Thus it might be possible that Test1 runs long before GetLoginAndPassword). You have to either call that method once from within the constructor or during test-initialization, or before every test-run.

[Test]
public void Test1()
{
    GetLoginAndPassword();
    driver.FindElement(By.Id("UserNameOrEmail")).SendKeys(loginName);
    driver.FindElement(By.Id("Password")).SendKeys(loginPassword);
}

Probably your GetLoginAndPassword isn´t even a method to test but a method used from your tests (unless you actually have a method within your system under test called GetLoginAndPassword. However since there are no asserts at all your tests are somewhat weird.

Upvotes: 0

Tim Bee
Tim Bee

Reputation: 2230

You cannot (and should not) send variables between tests. Tests methods are independent from another... and should actually Assert() something.

Your first method GetLoginAndPassword() isn't a test method per se but a utility method. If you use a Selenium PageObject pattern, this is probably a method of your PageObject class that you can run at the begining of your actual Test1() method.

Upvotes: 2

Related Questions