CodedUI : The Browser gets closed as finish testing without keeping for testing further steps - c#

I'm working on a CodedUI project to check on a Web Solution.
There, when Im testing for launching the site (as in launching the web URL), I am facing an issue with closing the browser as it finish testing, where it wont allow to use the same browser instance for further testing, Unless if I keep open a instance of a browser (IE) prior manually before running the test.
Can anyone please assist me with this, where I was unable to find a suitable solution. I even went through articles in MSDN where I posted regarding this issue as a comment which I'm facing, since I tried various ways of Code Snippets so far.
(MSDN : http://blogs.msdn.com/b/visualstudioalm/archive/2012/11/08/using-same-applicationundertest-browserwindow-across-multiple-tests.aspx)
My written code is provided below.
---
-- common.cs
[TestMethod]
public void LoadLocalHost()
{
this.UIMap.LoadLocalHost();
}
---
-- UIMap.Designer.cs
public void LoadLocalHost()
{
this.UIMsnInternetExplorerWindow.LaunchUrl(new System.Uri("http://localhost:5500/"));
Console.WriteLine(UIMsnInternetExplorerWindow.CloseOnPlaybackCleanup);
UIMsnInternetExplorerWindow.CloseOnPlaybackCleanup = false;
}
Highly appreciate an assistance from some one who can.

If you launch the browser in a class Initialize method rather than a test initialize method, and don't close it in your test or in a test cleanup, it should remain open for the duration of your tests, provided they are all executed within the same test class.
[ClassInitialize]
public void classInitialize()
{
// Do some stuff, including launch the browser
// This is executed once per class.
}
[TestInitialize]
public void testInitialize()
{
// This is where you'd get the test back to a specific
// state, like bring your browser back to a home page or something.
// It would be executed at the beginning of each test.
}
....
[TestMethod]
public void myFirstTest()
{
// Do some more stuff specific to your test.
}
[TestMethod]
public void mySecondTest()
{
// Do things after the last test.
}
....
[ClassCleanup]
public void classCleanup()
{
// Finalize everything and close the browser.
}

Related

Selenium doesn't close any browsers until ALL tests are complete

I'm doing something like this (below) with multiple Test Classes but [ClassCleanup] is not called until ALL tests run.
Because of this each class starts up a browser and ALL of the browsers remain open until ALL of the tests are completed, and then they ALL close down.
Is this expected?
Could someone comment if their tests do the same thing?
Is there a way to force a browser to close when the test class is done?
[ClassCleanup]
public static void ClassCleanup()
{
driver.Quit();
I dont know if this is just how Selenium is supposed to work, or if I have some sort of hanging resource that doesn't allow the browser to close until the end?
I cannot use [TestCleanup] because then I cannot have multiple tests in the same test class (as it will close before the 2nd test will run)
I finally found an example that works :)
Simply replaced
[ClassCleanup]
with
[ClassCleanup(ClassCleanupBehavior.EndOfClass)]
you can use [TestInitialize] as setUp and [TestCleanup] as Teardown of each test case.
In your code, it runs after class(all test cases)
So full code:
Setup:
[TestInitialize()]
public void InitializeTest() {
//your driver initilazation code
}
and, Teardown:
[TestCleanup]
public void Cleanup() {
driver.Quit();
}

Unable to connect to the remote server - due to Driver.Close() and Driver.Quit(), but how to fix?

I've been using Selenium and NUnit to do some automated testing, and up until now everything has been fine. The change I made recently was adding more than one test to a test class.
I'm pretty certain the issue lies with the code in my "Teardown" function in the test class. When I comment out
BrowserFactory.CloseAllDrivers();
Things run just fine.
This is the code for my "FrontEndAddItemToCartTest":
class FrontEndAddItemToCartTest : PageTest
{
[SetUp]
public void Initialize()
{
SetBrowser(BrowserFactory.BrowserType.Chrome); // Not headless
SetServer("testUrlNotGivenForSecurityPurposes");
StartTest(TestType.FrontEnd);
SetSize(MobileSize.XXLarge);
}
[Test]
public void StandardQuantityTest()
{
OrderItem standardQuantity = new OrderItem(new Product("500", ".25"), 500);
FrontEndActions.AddItemToCart(standardQuantity);
}
[Test]
public void CustomQuantityTest()
{
OrderItem customQuantity = new OrderItem(new Product("482", ".25"), 225);
FrontEndActions.AddItemToCart(customQuantity);
}
[TearDown]
public void EndTest()
{
BrowserFactory.CloseAllDrivers();
}
}
This is the error I get:
Message: OpenQA.Selenium.WebDriverException : Unexpected error. System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it
with a bunch of other stuff that I don't believe is relevant.
That being said, I have code in "SetBrowser(...)" that initializes a
new ChromeDriver();
but that doesn't seem to be enough.
The methods at the top are there to avoid having to do too much Selenium-y looking stuff in each of the tests - to make things more maintainable by people other than just myself - but it's what you would expect from typical Driver setup. I'm not sure why the second test is what causes the issue, but since things work fine w/o the CloseAllDrivers() being run, I'm imagining it's that.
By the looks of the attributes, you're using MSTest? Is it executing tests in parallel?
I guess regardless, for good test isolation you would want to change the CloseAllDrivers method to only dispose the driver used in the test it's cleaning up. I'd recommend starting there and see if that has the same problem.
Also, is CloseAllDrivers calling driver.Quit() or driver.Dispose()? Either of those are the ones you want to use.
OK so the issue was a combination of things:
1. I had Drivers[driver].Close(); and Drivers[driver].Quit(); -- only having .Quit() resolved one issue. Not really sure why Close() was causing problems, to be quite honest. The other (window not properly closing in the end) was due to the following code in my BrowserFactory:
if (driver == null)
{
Driver = new ChromeDriver((ChromeOptions)options); // options created elsewhere
Drivers.Add("Chrome", Driver); // This adds the driver to the list of Drivers currently up.
}
else
{
Driver = new ChromeDriver((ChromeOptions)options); // same as before
Drivers["Chrome"] = Driver; // **this** wasn't here before. This was the issue. Essentially, I was calling ```Quit()``` on the first instance of the driver, not on the fresh one created by the second test.
}
Thanks for all the help, guys. A combination of me determined to figure this out and your responses got me to the solution :)

C# How to hit a method in debug

Probably not a good title, and this question might be stupid, but I really have no idea how to do this.
I've created a project that connects to a DB with EF Core . I've created my DbContext class and my Repository class that does the actual querying .
Then I created another class , maybe I created it wrong, but I made it similar to a controller of an MVC project . This is my class:
public class ExtractCustomersToBeMarked
{
private ICampaignRepository _repository;
private ILogger<ExtractCustomersToBeMarked> _logger;
public ExtractCustomersToBeMarked(ILogger<ExtractCustomersToBeMarked> logger, ICampaignRepository repository)
{
_repository = repository;
_logger = logger;
}
public async Task ExtractCustomers()
{
IEnumerable<CampaignKnownCustomers> result = _repository.getCustomersGUID();
... I want to debug this code
}
}
Now I want to debug my program . I tried calling the method from my Main program , but with no success as I don't know what to pass to the constructor (MVC does that on its own) . That's what I tried :
public static void Main(string[] args)
{
var p = new Program();
p.Run().Wait();
}
private async Task Run()
{
ExtractCustomersToBeMarked ectm = new ExtractCustomersToBeMarked(?,?);
await ExtractCustomersToBeMarked.ExtractCustomers();
}
I know it doesn't look good, this structure is simply for debugging . If theres another way I'm open to hear about it..
How can I hit the debugger on ExtractCustomers?
I guess you have implemented a CampaignRepository class. Provided that you want to use this implementation when debugging the ExtractCustomers() method, you should simply create an instance of it and pass to the method:
static void Main(string[] args)
{
ExtractCustomersToBeMarked ectm = new ExtractCustomersToBeMarked(null, new CampaignRepository());
ectm.ExtractCustomers().Wait();
}
The same goes for the logger. Create an instance of a class that implements the ILogger<ExtractCustomersToBeMarked> if you use the logger in the method that you want to debug. Don't forget to pass it to the constructor of the ExtractCustomersToBeMarked class when you create an instance of it.
You may want to implement an integration test instead of modifying the Main() method of the application itself though but that's another story.
Summary I'd suggest writing Unit Tests against the code you want to debug.
Detail When you have Unit Tests in place you can run each individual test under Debug, allowing you to step through the code exactly like you do when debugging the application; but with the benefit that you get to define the scope and context of the test, for example you can test isolated parts of your system independently of others.
Once a test is in place, it can shorten the time taken by the code+debug iteration cycle, making you more productive. It achieves that because the test fires you straight into the relevant code with the test scenario already set up, rather than the whole application having to start up, and you navigating through to the relevant parts each time to get into the scenario you want.
Another benefit of these tests (if they are written the right way) is that you can make them run as part of an automated build which is triggered whenever someone changes some code. This means that if anyone breaks that code, the test will fail, and the build will fail.

Load testing Visual Studio, start up script / setup

I was wondering if it was possible to have a start-up script before running any load tests? For example, perhaps to seed some data or clear anything down prior to the tests executing.
In my instance I have a mixed bag of designer and coded tests. Put it simply, I have:
Two coded tests
A designer created web test which points to these coded tests
A load test which runs the designer
I have tried adding a class and decorating with the attributes [TestInitialize()], [ClassInitialize()] but this code doesn't seem to get run.
Some basic code to show this in practice (see below). Is there a way of doing this whereby I can have something run only the once before test run?
[TestClass]
public class Setup : WebTest
{
[TestInitialize()]
public static void Hello()
{
// Run some code
}
public override IEnumerator<WebTestRequest> GetRequestEnumerator()
{
return null;
}
}
Probably should also mention that on my coded tests I have added these attributes and they get ignored. I have come across a workaround which is to create a Plugin.
EDIT
Having done a little more browsing around I found this article on SO which shows how to implement a LoadTestPlugin.
Visual Studio provides a way of running a script before and also after a test run. They are intended for use in deploying data for a test and cleaning up after a test. The scripts are specified on the "Setup and cleanup" page in the ".testsettings" file.
A load test plugin can contain code to run before and after any test cases are executed, also at various stages during test execution. The interface is that events are raised at various points during the execution of a load test. User code can be called when these events occur. The LoadTestStarting event is raised before any test cases run. See here for more info.
If you are willing to use NUnit you have SetUp/TearDown for a per test scope and TestFixtureSetUp/TestFixtureTearDown to do something similar for a class (TestFixture)
Maybe a bit of a hack, but you can place your code inside the static constructor of your test class as it will automatically run exactly once before the first instance is created or any static members are referenced:
[TestClass]
public class Setup : WebTest
{
static Setup()
{
// prepare data for test
}
public override IEnumerator<WebTestRequest> GetRequestEnumerator()
{
return null;
}
}

How to use ApprovalTests on Teamcity?

I am using Approval Tests. On my dev machine I am happy with DiffReporter that starts TortoiseDiff when my test results differ from approved:
[UseReporter(typeof (DiffReporter))]
public class MyApprovalTests
{ ... }
However when the same tests are running on Teamcity and results are different tests fail with the following error:
System.Exception : Unable to launch: tortoisemerge.exe with arguments ...
Error Message: The system cannot find the file specified
---- System.ComponentModel.Win32Exception : The system cannot find the file
specified
Obviously it cannot find tortoisemerge.exe and that is fine because it is not installed on build agent. But what if it gets installed? Then for each fail another instance of tortoisemerge.exe will start and nobody will close it. Eventually tons of tortoisemerge.exe instances will kill our servers :)
So the question is -- how tests should be decorated to run Tortoise Diff on local machine
and just report errors on build server? I am aware of #IF DEBUG [UseReporter(typeof (DiffReporter))] but would prefer another solution if possible.
There are a couple of solutions to the question of Reporters and CI. I will list them all, then point to a better solution, which is not quite enabled yet.
Use the AppConfigReporter. This allows you to set the reporter in your AppConfig, and you can use the QuietReporter for CI.
There is a video here, along with many other reporters. The AppConfigReporter appears at 6:00.
This has the advantage of separate configs, and you can decorate at the assembly level, but has the disadvantage of if you override at the class/method level, you still have the issue.
Create your own (2) reporters. It is worth noting that if you use a reporter, it will get called, regardless as to if it is working in the environment. IEnvironmentAwareReporter allows for composite reporters, but will not prevent a direct call to the reporter.
Most likely you will need 2 reporters, one which does nothing (like a quiet reporter) but only works on your CI server, or when called by TeamCity. Will call it the TeamCity Reporter. And One, which is a multiReporter which Calls teamCity if it is working, otherwise defers to .
Use a FrontLoadedReporter (not quite ready). This is how ApprovalTests currently uses NCrunch. It does the above method in front of whatever is loaded in your UseReporter attribute. I have been meaning to add an assembly level attribute for configuring this, but haven't yet (sorry) I will try to add this very soon.
Hope this helps.
Llewellyn
I recently came into this problem myself.
Borrowing from xunit and how they deal with TeamCity logging I came up with a TeamCity Reporter based on the NCrunch Reporter.
public class TeamCityReporter : IEnvironmentAwareReporter, IApprovalFailureReporter
{
public static readonly TeamCityReporter INSTANCE = new TeamCityReporter();
public void Report(string approved, string received) { }
public bool IsWorkingInThisEnvironment(string forFile)
{
return Environment.GetEnvironmentVariable("TEAMCITY_PROJECT_NAME") != null;
}
}
And so I could combine it with the NCrunch reporter:
public class TeamCityOrNCrunchReporter : FirstWorkingReporter
{
public static readonly TeamCityOrNCrunchReporter INSTANCE =
new TeamCityOrNCrunchReporter();
public TeamCityOrNCrunchReporter()
: base(NCrunchReporter.INSTANCE,
TeamCityReporter.INSTANCE) { }
}
[assembly: FrontLoadedReporter(typeof(TeamCityOrNCrunchReporter))]
I just came up with one small idea.
You can implement your own reporter, let's call it DebugReporter
public class DebugReporter<T> : IEnvironmentAwareReporter where T : IApprovalFailureReporter, new()
{
private readonly T _reporter;
public static readonly DebugReporter<T> INSTANCE = new DebugReporter<T>();
public DebugReporter()
{
_reporter = new T();
}
public void Report(string approved, string received)
{
if (IsWorkingInThisEnvironment())
{
_reporter.Report(approved, received);
}
}
public bool IsWorkingInThisEnvironment()
{
#if DEBUG
return true;
#else
return false;
#endif
}
}
Example of usage,
[UseReporter(typeof(DebugReporter<FileLauncherReporter>))]
public class SomeTests
{
[Test]
public void test()
{
Approvals.Verify("Hello");
}
}
If test is faling, it still would be red - but reporter would not came up.
The IEnvironmentAwareReporter is specially defined for that, but unfortunatelly whatever I return there, it still calls Report() method. So, I put the IsWorkingInThisEnvironment() call inside, which is a little hackish, but works :)
Hope that Llywelyn can explain why it acts like that. (bug?)
I'm using CC.NET and I do have TortoiseSVN installed on the server.
I reconfigured my build server to allow the CC.NET service to interact with the desktop. When I did that, TortiseMerge launched. So I think what's happening is that Approvals tries to launch the tool, but it cant because CC.NET is running as a service and the operating system prevents that behavior by default. If TeamCity runs as a service, you should be fine, but you might want to test.

Categories