28

When I write a test in Visual Studio, I check that it works by saving, building and then running the test it in Nunit (right click on the test then run).

The test works yay... so I Move on...

Now I have written another test and it works as I have saved and tested it like above. But, they dont work when they are run together.

Here are my two tests that work when run as individuals but fail when run together:

using System;
using NUnit.Framework;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium;

namespace Fixtures.Users.Page1
{
    [TestFixture]
    public class AdminNavigateToPage1 : SeleniumTestBase
    {
        [Test]
        public void AdminNavigateToPage1()
        {
            NavigateTo<LogonPage>().LogonAsCustomerAdministrator();
            NavigateTo<Page1>();
            var headerelement = Driver.FindElement(By.ClassName("header"));

            Assert.That(headerelement.Text, Is.EqualTo("Page Title"));
            Assert.That(Driver.Url, Is.EqualTo("http://localhost/Page Title"));
        }

        [Test]
        public void AdminNavigateToPage1ViaMenu()
        {
            NavigateTo<LogonPage>().LogonAsCustomerAdministrator();
            Driver.FindElement(By.Id("menuitem1")).Click();
            Driver.FindElement(By.Id("submenuitem4")).Click();
            var headerelement = Driver.FindElement(By.ClassName("header"));

            Assert.That(headerelement.Text, Is.EqualTo("Page Title"));
            Assert.That(Driver.Url, Is.EqualTo("http://localhost/Page Title"));
        }
    }
}

When the second test fails because they have been run together

Nunit presents this:

Sse.Bec.Web.Tests.Fixtures.ManageSitesAndUsers.ChangeOfPremises.AdminNavigateToChangeOfPremises.AdminNavigateToPageChangeOfPremisesViaMenu: OpenQA.Selenium.NoSuchElementException : The element could not be found

And this line is highlighted:

var headerelement = Driver.FindElement(By.ClassName("header"));

Does anyone know why my code fails when run together, but passes when run alone?

Any answer would be greatly appreciated!

Graeme Secondwave
  • 283
  • 1
  • 3
  • 6
  • 4
    Are you sure the tests aren't sharing state? Does the browser close down and re-open between the tests? Which test fails when they're run together? Do BOTH fail, or does one pass, and one fail? – Daniel Mann Jan 24 '12 at 13:06
  • The browser closes down and so does the command window.. they reopen again to process the following test... Its the first test that pass's then all following tests generally fail and they allways fail for the same reason posted above. – Graeme Secondwave Jan 24 '12 at 13:10
  • Doesn't help your specific question, but check out http://www.ncrunch.net/, it runs your tests in the background. Get rid of the whole "saving, building and then running the test" hassle. – Brad Boyce Jan 24 '12 at 13:37
  • This is happening to me all the time (though with a different error), although mine are hitting a database and running each test in a transaction.. I get non thread safe exceptions so when running through Visual Studio the next test must start before the previous test has finished (running command line does not seem to have the same problem) – PJUK Sep 12 '12 at 13:30

7 Answers7

7

Such a situation normally occurs when the unit tests are using shared resources/data in some way.

  1. It can also happen if your system under test has static fields/properties which are being leveraged to compute the output on which you are asserting.
  2. It can happen if the system under test is being shared (static) dependencies.
user3613932
  • 861
  • 11
  • 14
  • 2
    I'm having this situation with InMemory Database in .net core -- Just not sure how to fix it – IEnjoyEatingVegetables Jul 10 '18 at 13:01
  • *To avoid this issue, and to make sure the test is self-contained from a readability perspective*, I typically don't rely on shared objects between unit tests. I create separate objects inside each unit test. You can have separate methods for creating separate objects (to avoid rewriting the same code again and again). – user3613932 Jul 11 '18 at 00:29
2

Without knowing how Selenium works, my bet is on Driver which seems to be a static class so the 2 tests are sharing state. One example of shared state is Driver.Url. Because the tests are run in parallel, there is a race condition to set the state of this object.

That said, I do not have a solution for you :)

Jodi
  • 900
  • 6
  • 14
2

look into the TestFixtureSetup, Setup, TestFixtureTearDown and TearDown.
These attributes allow you to setup the testenvironment once, instead of once per test.

Default
  • 10,565
  • 8
  • 60
  • 99
  • what do you recommend i can clean up in the TestFixtureTearDown? – Graeme Secondwave Jan 24 '12 at 13:34
  • @GraemeSecondwave Unfortunately I do not know Selenium. I do however know that when I have run tests together they fail and when I add the common instructions to the setup it works. For instance, what happends if you add `NavigateTo().LogonAsCustomerAdministrator();` to a TestFixtureSetup? – Default Jan 24 '12 at 13:41
  • If the `var headerelement...` line is highlighted it is probably the line before it that is throwing an exception. Make sure that submenuitem4 exists. Have you tried debugging it? (Right click your test, choose Test With -> Debugger) – Default Jan 24 '12 at 13:43
2

Two things you can try

  1. put the break point between the following two lines. And see which page are you in when the second line is hit
  2. Introduce a slight delay between these two lines via Thread.Sleep

    Driver.FindElement(By.Id("submenuitem4")).Click(); var headerelement = Driver.FindElement(By.ClassName("header"));

chandmk
  • 3,456
  • 3
  • 19
  • 26
  • tried the thread.sleep function where you suggested. before i added it, when i run the tests it was always the second test that failed, but with the command sleep it was always the second test that past and the first one failed? strange! – Graeme Secondwave Jan 24 '12 at 13:35
  • So this might mean that you need the thread.sleep above that "header" element finder, to give enough time for the browser to load the page before your drive look for that element. Try the same in first test too. – chandmk Jan 24 '12 at 13:44
  • ok i added the sleep function to both tests and they have passed! strange i tried it before but never added them to both.. not sure why they pass now but im chuffed nether the less! thanks for your help. – Graeme Secondwave Jan 24 '12 at 14:08
  • thread.sleep may not be the answer to 'why this is happening' question. My experience with css based menu clicks with selenium drivers is not that predictable. Thread.Sleep seem to be the only way I was able to reliably process those clicks – chandmk Jan 24 '12 at 15:45
1

If none of the answers above worked for you, i solved this issue by adding Thread.Sleep(1) before the assertion in the failing test...

Looks like tests synchronization is missed somewhere... Please note that my tests were not order dependant, that i haven't any static member nor external dependency.

Loul G.
  • 790
  • 9
  • 24
0

I think you need to ensure, that you can log on for the second test, this might fail, because you are logged on already?

-> putting the logon in a set up method or (because it seems you are using the same user for both tests) even up to the fixture setup -> the logoff (if needed) might be put in the tear down method

     [SetUp]
     public void LaunchTest()
     {
        NavigateTo<LogonPage>().LogonAsCustomerAdministrator();
     }

     [TearDown]
     public void StopTest()
     {
        // logoff
     }
     [Test]
     public void Test1()
     {...}
     [Test]
     public void Test2()
     {...}

If there are delays in the DOM instead of a thread.sleep I recommend to use webdriver.wait in combination with conditions. The sleep might work in 80% and in others not. The wait polls until a timeout is reached which is more reliable and also readable. Here an example how I usually approach this:

    var webDriverWait = new WebDriverWait(webDriver, ..);
    webDriverWait.Until(d => d.FindElement(By.CssSelector(".."))
        .Displayed))
0

Are you sure that after running one of the tests the method

NavigateTo<LogonPage>().LogonAsCustomerAdministrator();

is taking you back to where you should be? It'd seem that the failure is due to improper navigation handler (supposing that the header element is present and found in both tests).

Amar Palsapure
  • 9,262
  • 1
  • 25
  • 46
casals
  • 343
  • 4
  • 10
  • well watching the driver navigate through my test it loads up all the pages and navigates to the page as intended. and the page title im looking for displays. it doesnt like the 'Header element' as the test as it is passes when run by it self? – Graeme Secondwave Jan 24 '12 at 13:18