Showing posts with label CodedUI. Show all posts
Showing posts with label CodedUI. Show all posts

Tuesday, 13 December 2016

Data Source Types and Attributes


  • CSV
    [DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\\data.csv", "data#csv", DataAccessMethod.Sequential), DeploymentItem("data.csv"), TestMethod]
  • Excel
    DataSource("System.Data.Odbc", "Dsn=ExcelFiles;Driver={Microsoft Excel Driver (*.xls)};dbq=|DataDirectory|\\Data.xls;defaultdir=.;driverid=790;maxbuffersize=2048;pagetimeout=5;readonly=true", "Sheet1$", DataAccessMethod.Sequential), DeploymentItem("Sheet1.xls"), TestMethod]
  • Test case in Team Foundation Server
    [DataSource("Microsoft.VisualStudio.TestTools.DataSource.TestCase", "http://vlm13261329:8080/tfs/DefaultCollection;Agile", "30", DataAccessMethod.Sequential), TestMethod]
  • XML
    [DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML", "|DataDirectory|\\data.xml", "Iterations", DataAccessMethod.Sequential), DeploymentItem("data.xml"), TestMethod]
  • SQL Express
    [DataSource("System.Data.SqlClient", "Data Source=.\\sqlexpress;Initial Catalog=tempdb;Integrated Security=True", "Data", DataAccessMethod.Sequential), TestMethod]

Thursday, 1 December 2016

How to Click or find control by scrolling page in CodedUI


How to click on control if it is visible on page and we need to scroll the page to click on it.

In CodedUI we have UITestingUtilities dll that helps us a lot in finding control or verifying control existance by providing many extended methods.

In below code sample, we have one button control on page. To click on this control manually, we need to scroll the page and then we can click on control. This can be handled through code by using EnsureClickable() method. 
Here we are first making sure that the control exists by using TryFind() method and then trying to click control.

While loop added to check if more page scroll action required. Once the control is clicked the "isClickable" variable set to true, so that to break the While() loop. The exception  is thrown if the control is still hidden on blocked by some other control , To handle this condition we have to catch the exception and instead of throwing it we are scrolling the page down.


Code below

            BrowserWindow bw = new BrowserWindow();
            HtmlButton but = new HtmlButton(bw);
            //define properities for the button here

            bool isClickable = false;
            if(but.TryFind())
            {
                while (!isClickable)
                {
                    try
                    {
                        // It ensures control is visible and clickable
                        but.EnsureClickable();
                        Mouse.Click(but);
                        isClickable = true;
                    }
                    catch(FailedToPerformActionOnHiddenControlException)
                    {
                        //We dont through an exception instead we scroll the page down and try again
                        Mouse.MoveScrollWheel(-1);
                    }
                    catch (FailedToPerformActionOnBlockedControlException)
                    {
                        {
                            //We dont through an exception instead we scroll the page down and try again
                            Mouse.MoveScrollWheel(-1);
                        }
                    }
                }
            }

***Here we can add while loop break logic to avoid the situation like - the method will be continuously searching for control and scrolling page down. To do this we can count the Page scroll action and if it is more than certain count then we can break while loop and throw exception (like Control not found)

Thursday, 4 August 2016

TryFind vs WaitForControl(Ready/Exist)


TryFind() changed the test execution. The reason is that TryFind() would return true/false immediately when pages are still loading and its returned value would heavily depend on the responsiveness of the web server, so some tests would be fixed by simply replacing it with WaitForControlExist() which would block the current thread until timeout specified by default PlaybackSettings.WaitForReadyTimeout.

However prefer specifying timeout setting explicitly by calling WaitForControlReady(int millisecondsTimeout) or WaitForControlExist(int millisecondsTimeout). Somebody might accustomed with Playback.Wait(int thinkTimeMilliseconds) or Thread. Sleep(int millisecondsTimeout), but they might wait unnecessarily long. 

In addition, if combined with Assertion as be;pw:
Assert.IsTrue(someElement.WaitForControlReady(60*1000)); //Wait for 1 min
Unexpected delay could be highlighted immediately.
There are multiple WaitForControl() functions defined with UITestControl, some of them could be very helpful but are usually neglected, for example:
  • WaitForControlCondition(Predicate<UITestControl> conditionEvaluator, int millisecondsTimeout), combined with LINQ, provides a very powerful means to evaluate any status of the target control.
  • WaitForControlPropertyEqual(string propertyName, object propertyValue, int millisecondsTimeout) enables tester to monitor changes of any attribute of the control effectively.
  • bool WaitForControlNotExist(int millisecondsTimeout), combined with Assert.IsTrue(), could be used to evaluate operations have successfully caused the page changing to another state.
  • bool WaitForControlExist(int millisecondsTimeout) and bool WaitForControlReady(int millisecondsTimeout) should be used from time to time before performing solid operations like clicking, selecting or typing. Usually, the former is good enough especially when such operations would be carried out only when the browser/control is ready. But they might return different values for a specific control: usually WaitForControlExist() would return true when the target control is displayed, but in some of my projects, WaitForControlReady() would return true several minutes after WaitForControlExist() returning true.

Sunday, 10 April 2016

Database Testing with CodedUI


Lets discuss about the Database Testing with CodedUI (C#) with some sample code
Connection String plays a key role in connecting to the database
Which has a different format for different Databases like Oracle,SQL etc
//Below code will login and open the DB connection.
string connetionString = “Data Source=DBSeverName;Initial Catalog=DBName;User ID=UserName;Password=DBPassword”;
SqlConnection connection = new SqlConnection(connetionString);
connection.Open();


Once the DB connection is setup, we need to define a sql Command for executing and Sql Datareader for reading the results of the command
Once the results are read by the data reader, it is loaded into a DataTable

//Below code will help to execute the Select query.
String Selectquery = “Select FirstName from Emp where EmpID in (01)”;
SqlCommand command = new SqlCommand(Selectquery, connection);
SqlDataReader reader = command.ExecuteReader();
DataTable dataTable = new DataTable();
dataTable.Load(reader);
Once the data is loaded into the datatable, all we need to do is verify with the expected output

//Below code will help to verify the data which above code fetch from the particular table.
String rowText;
rowText = DB.dataTable.Rows[0][DB.dataTable.Columns[0]].ToString();
if (rowText.Contains(“Mayank”))
{
      Console.WriteLine(“FirstName is macthing with expected result”);
}
else
{
      Console.WriteLine(“Verification is not passed”);
}

After the verification, Close the connection
//It will close the connection.
connection.Close();

Thursday, 7 April 2016

Using a App.config file to have different Sections in CodedUI project

To make coded UI tests to work in different environments, or to have different configuration values for different test methods to override the source of data file, a config file can be setup rather than a data source. 

Things to be done to achieve this
  1. You’ll need to add a reference to the System.Configuration assembly for the solution
  2. Then add the custom elements to app.config file (which is added to test project) TestSiteConfigurationData section name in the app.config file
  3. Create configuration data class for a custom section in App.Config TestSiteConfigurationData.cs
  4. Create the Helper class file for reading the data from configuration data class TestSiteConfigurationHelper.cs
  5. Call the helper class in the Codedui Project and read the values from config file under your custom section

You might face an issue with some wrong value entered for the type of section in the app.config file

 <configSections>
    <section name="TestSiteConfigurationData"
             type="Configuring_Sections.TestSiteConfigurationData,Configuring Sections"/>
  </configSections>
   
Configuring_Sections.TestSiteConfigurationData - <ProjectNamespace>.<ConfigurationDataClassName>

Configuring Sections - the solution dll name i.e your CodedUI project name

Find the sample project implementing the above attached


Happy coding :)


Monday, 10 August 2015

Limit TestMethod Timeout in CodedUI


Sometimes when we have Test Methods which run for long time, we tend to see the below kind of exceptions and TestMethod execution stops.
"Test 'TestMethod_Name' exceeded execution timeout period." 
By default Execution time for a test method is 60mins.
This test execution timeout can be changed as per our requirements.
It can be either changed in the Settings file or else

First way is to Set a limit time for execution which is as shown below
[TestMethod]
[Timeout(6000)]
public void TestMethodName()
{
}

Second is to set infinite time limit when we dont know how much time the execution is going to happen or if we are expecting the execution to run completely irrespective of the time

[TestMethod]
[Timeout(TestTimeout.Infinite)]
public void TestMethodName()
{
}

Wednesday, 29 July 2015

Execute CodedUI TestMethod() through command prompt



Input the path of the dll in the Developer Command Prompt for VS2012/13..
cd C:\Users\...\Documents\Visual Studio 2012\Projects\CodedUITestProject\CodedUITestProject\bin\Debug
Using VSTest.Console.exe like this:
VSTest.Console.exe CodedUITestProject.dll /Tests:TestMethod1,testMethod2 /UseVsixExtensions:true  /Logger:trx
Note There is no /resultsfile option in VSTest.Console.exe command line. You need to use /Logger.trx if you want to generate a trx file.

Note The /Tests command line option cannot be used with the /TestCaseFilter command line option.

Usage  of /TestCaseFilter
Examples of /TestCaseFilter usage with filter as Priority
/TestCaseFilter:"Priority=1"

Examples of /TestCaseFilter usage with filter as Test Category
/TestCaseFilter:"TestCategory=Nightly

Examples of /TestCaseFilter usage with multiple filters using "|"
/TestCaseFilter:"TestCategory=Nightly|FullyQualifiedName=Namespace.ClassName.MethodName"

Monday, 20 July 2015

Schedule Coded UI Test to Execute At a Specific Time

The best way I have found to accomplish this is to create a .bat file which executes the test using the mstest command line tool, and setting this .bat to execute at a specific time using task scheduler. I currently do this daily on a project I am working on.
Here are the steps oulined to execute a .bat driven Coded UI test at a specified time.

Step1:
Create a .bat similar to the following:
set mstestPath="C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE"
 %mstestpath%\mstest /testcontainer:AutomatedUITest.dll  /resultsfile:TestOutput.trx
Test your script by double-clicking the .bat and assure that the test is properly executing.

Step2:
Assuming you name this .bat “TestRunner.bat”, you would then open Task Scheduler (pre-installed on Windows, type “Task” into the search bar to locate). You will see Task Scheduler (local) in the upper left of the window. Right-click, then select create Task. Give the task a name and choose appropriate security settings. Click the Triggers tab, and assign when you wish the test to auto-execute. In this screen you can set the appropriate time to run. Now click the Actions tab, click new and assign your script “TestRunner.bat” to execute and any parameters you may wish to feed to your script. Now choose settings and allow the test to run on demand. Ensure your test is executing properly by clicking the Task Scheduler Library underneath Task Scheduler (local), locate your task, right-click and choose run. If everything executes as expected, you can rest assured that your scheduled task will properly execute at the time(s) you have designated.

Monday, 15 June 2015

Invoking a TestMethod from TestCleanUp in CodedUI


While running a Test method, suppose the application went down suddenly or a time out issue came up because of which ContolNotFound exception occurred and got existed from the test method.
In this scenario in order to invoke the test method from the TestCleanup again this is how we do

[TestCleanup]
 public override void MyTestCleanup()
 {
      // Here i am writing for an generic flow checking my test failed.
      // you can check if any time out window availability or application down messages in browser
      if (TestContext.CurrentTestOutcome == UnitTestOutcome.Failed)
      {      
            var type = Type.GetType(TestContext.FullyQualifiedTestClassName);      
            if (type != null)
           {
                var instance = Activator.CreateInstance(type);
                var method = type.GetMethod(TestContext.TestName);
                try
               {
                    method.Invoke(instance, null);
               }
               catch
              {
            
              }
         }
     }
 }

Wednesday, 6 May 2015

unexpected popups handling in CodedUI

A lot of times, while running a UI test, our test runs into an unexpected page\state, say an unexpected error dialog, or an pop-up window, which would make our test fail and if that happens, rather than having the test rerun from the start, all we want is for it to resume when the page is loaded.
I am taking the example of a winforms application with an alert window. The steps would be no different if you were trying the same on any other supported technology.
Suppose let me say upon clicking a button there was an unexpected pop-up appearing. This pop-up blocks my TestMethod and makes it fail as it will not be able to perform any action as per the TestMethod. In this case these are the following steps which are to be followed
  1. Set a retry count- Playback.PlaybackSettings.MaximumRetryCount, i.e. you can specifiy the number of times you want a failed action to be retried. This is not a mandatory argument, if no value is set, the default value will be 1.
  2. Add a retry handler for the failed step. This is nothing but the handler function which will get called in case of a failure. You can add\remove this handler for any step in the coded UI test method, or even in test\class initialize as a generic handler for all failures.
  3.                         Playback.PlaybackError += Playback_PlaybackError;
  4. The handler method signature is as shown below
      1. private void Playback_PlaybackError(object sender, PlaybackErrorEventArgs e)
                {
                    Console.WriteLine("Retrying .... ");
                      // By default, the exception will be thrown. Over here we are switching to retry mode.
                      e.Result = PlaybackErrorOptions.Retry;
                        // Just a simple enter to dismiss the Alert. If you are sure of any specific properties for
                        // a popup dialog or any other specific action you need to do, this is the place to 
                        // implement them.
                        Keyboard.SendKeys("{Enter}");
                    }
        1. Now simply setting the PlaybackErrorOptions to Retry will retry your failed step over and over until either the step passes or the MaximumRetryCount is hit. If you want to do any special handling, like say dismissing an alert, you can add the code for the same within the handler.
        2. TestMethod code looks like below
            TestMethod()
                    {
                        using (ApplicationUnderTest aut = ApplicationUnderTest.Launch("UnexpectedPopupAut.exe"))
                        {
                            #region Variable Declarations
                            #endregion
            // Important to set the MaximumRetryCount count for the retry handler to be invoked.
                            Playback.PlaybackSettings.MaximumRetryCount = 3;
                            // Add the error handler.
                            Playback.PlaybackError += Playback_PlaybackError;
            //Code of your TestMethod
                            Playback.PlaybackError -= Playback_PlaybackError;
          This is supported only for the following exceptions:-
          1. PlaybackFailureException
          2. UITestControlNotFoundException
          3. UITestControlNotAvailableException
          4. TechnologyNotSupportedException
          5. InvalidUITestExtensionPackageException
          6. DecodingFailedException
          7. FailedToPerformActionsOnBlockedControlException
          8. FailedToPerformActionsOnHiddenControlException
          9. UITestControlNotVisibleException
          10. ValidationFailedException
          11. FailedToLaunchApplicationException
          12. ActionNotSupportedOnDisabledControlExcept

        Thursday, 12 February 2015

        Installation and Configuration of Test Controller and Test Agent without TFS


        Prerequisities

        Test controllers and Test agents have the following software requirement:
        Operating System
        To install a test controller or a test agent, the computer must run one of the following operating systems:
        Controller:
        • Windows 8, Windows 8.1
        • Windows 7 Service Pack 1
        • Windows Server 2012, Windows Server 2012 R2
        • Windows Server 2008 Release 2, Service Pack 1
        Agent:
        1. Windows 8, Windows 8.1
        2. Windows 7 Service Pack 1
        3. Windows XP Service Pack 3
        4. Windows Server 2012, Windows Server 2012 R2
        5. Windows Server 2008 Release 2, Service Pack 1
        6. Windows Server 2003 Service Pack 1
        .NET Framework
              To install a test controller or test agent, the computer must run the .NET Framework 4.5.

        UAC

              Change the UAC settings in both the systems to "Never Notify"

        New Local User as Administrator
              On each computer where you will install a test controller or a test agent, create a local user account that is a member of the Administrators group. Login with the local user and use the same account and password on each machine.
        1. Note:- If you are not Creating the Local User and using the same default administrator you might face issue while configuring
        2. Use this user account for your test controllers when you install and configure them.
           Team is the Local user which has been added into the machines where Test Controller and Test Agent are installed. On filling the above details by clicking on "Apply Settings" you see a pop up with validations happening. There will be an Configuration warning as we are not using the lab manager. It can be ignored
        3. Right click on the computer and Select Manage. In the Computer Management window, navigate to System Tools -> Local Users and Groups -> Groups. Add this account(i.e. Team) to the TeamTestAgentService group on the test controller machine.
        4. Install and configure your test agents using this same account(i.e Here Team).


          Configure the Test Agent with the following details. To register the Test Controller with this Test Agent give the IP Address and Click Apply Settings.
        5. Once the Setting are applied you can see a "Test Agent Status" Window appearing as below

          If the Test Agent Status is "Online" Then you are ready with the Set up for remote executions

        Monday, 9 February 2015

        Record one application only in CodedUI Test


        Generally, we test a single application using Coded UI Test. By default, Coded UI Test though will record actions on all applications.  Thus we may get unwanted actions on other application in our recording.

        We can prevent this by adding the following configuration in CodedUITestBuilder.exe.config file
        <add key="IncludeProcess" value="%SystemRoot%\system32\calc.exe"/>

        Replace calc.exe with the full path to your application. With this configuration only actions on calc.exe (or the application that you added) will be recorded.

        When using IncludeProcess, actions on the Windows desktop are not recorded. If you want to include actions on the Windows desktop, add the following configuration.
            <add key="RecordOnDesktopProcess" value="true"/>


        Alternately, we can also selectively exclude applications from recording using the following configuration.
        <add key="ExcludeProcess" value="%SystemRoot%\system32\calc.exe"/>
        Replace calc.exe with the full path to the application you want to exclude from recording.

        NOTE: These settings are applicable for Recording only. We can still drag the cross hair onto any application, get its properties and add assertions on them.

        If you see that no actions are being recorded on a particular application, first check this config file to ensure that the application has been added in the ExcludeProcess section. Also verify the IncludeProcess  configuration. If a particular process has been added in IncludeProcess, then actions on your applications will not be recorded.

        It is possible (though not recommended) to add process ids to IncludeProcess & ExcludeProcess configurations.

        Usage of Cordinate based actions in CodedUI


        When you record actions & generate code in Coded UI Test, you get actions like
        Mouse.Click(uISearchButton, new Point(18, 15));

        Many confuse by the Point argument we pass to Mouse.Click and believe that we are doing a coordinate based action. The Point argument here is relative to the button itself. So test will not fail if the button moves around in the page.

        More importantly, you can completely remove the Point argument. The code could be written as
        Mouse.Click(uISearchButton);

        This will still work. If no Point argument is specified, Visual Studio UI Test Framework determines a clickable point and performs the click on that point.

        So why do we use coordinates?

        There are specific scenarios where these coordinates really come in handy.

        Consider a DropDownButton, which drops down when you click on the expander arrow. If you click on the button’s normal area, it is invoked. If you click on the expander, it shows the additional buttons and you can click on one of them. Since we record relative coordinates for the click action, we can playback the actions on the expander also. If we had not recorded coordinates and clicked on the first available clickable point in the button, this scenario would have failed.
        e.g:- Look at the screenshot below.





        Here I am clicking on the expander in Picture Button to bring up additional options. This scenario will only work if we record relative coordinates on the click action.

        Tuesday, 20 January 2015

        Why does application close after each test in Coded UI Test


        In Coded UI, a flag CloseOnPlaybackCleanup is added to ApplicationUnderTest class. 
        For cases where an application is launched during test run, this flag helps determine whether to close the application under test after test is over.  Default value for the flag was set to true (closes the application) as it is not advisable to re-use resources from other test cases. 
        This works fine for Visual Studio 2012 and later versions. Users will see  BrowserWindow / ApplicationUnderTest is getting closed after each test case if they don't have CloseOnPlaybackCleanup flag set to false. 
         If you want to reuse any application instance launched in another test case, you have to assign CloseOnPlaybackCleanup flag to false for ApplicationUnderTest / BrowserWindow object.
        Please refer to sample code as below. If you run all these three tests together, BrowserWindow will be launched only once, remaining other tests will use existing browser instance from the previous test. If you run each test individually, then each test case will close the browser at the end of the run.

        public class CodedUITest1
            {
                public CodedUITest1()
                {
                }

                [TestMethod]
                public void CodedUITestMethod1()
                {
                   LoadLocalHost();
                }

                [TestMethod]
                public void CodedUITestMethod2()
                {
                    LoadLocalHost();
                }

                [TestMethod]
                public void CodedUITestMethod3()
                {
                    LoadLocalHost();
                }


                static BrowserWindow browserWindowInstance = null;

                public void LoadLocalHost()
                {
                    if (browserWindowInstance == null)
                    {
                        browserWindowInstance = BrowserWindow.Launch(new System.Uri("http://google.com/"));
                        browserWindowInstance.CloseOnPlaybackCleanup = false;
                        browserWindowInstance.Maximized = !browserWindowInstance.Maximized;
                    }
                    else
                    {
                        browserWindowInstance.Maximized = !browserWindowInstance.Maximized;
                    }
                }
        }     

        The same principle is applied with running tests using Command Line. If you are running tests altogether, the Application Under test will remain open in between tests in case CloseOnPlaybackCleanup is set to false. Once the run is over, all application instances which were launched during the run are closed.

        Searching a UI Test Control with an invalid property


        What if we give an invalid property as the Search/Filter property

        For Web technology,
        • If an invalid SearchProperty is used to Find a UITestControl, it will throw UITestControlNotFoundException. 
        e.g:- If you searched for the search edit box in google.com using a InvalidSearchProperty,
        this.mUISearchEdit.SearchProperties["InvalidSearchProperty"] = "foo-bar";
        you would get the UITestControlNotFoundException

        • If an invalid FilterProperty is used to Find a UITestControl, it will be ignored.
        e.g:- If you searched for the search edit box in google.com using a InvalidFilterProperty,
        this.mUISearchEdit.FilterProperties["InvalidFilterProperty"] = "foo-bar";
        you would succeed in locating the edit box and performing operations performed on it.

        For MSAA & UIA technologies,
        • If an invalid SearchProperty is used to Find a UITestControl, it will throw an ArgumentException
        e.g:- If you searched for the button ‘6’ in the calculator using a InvalidSearchProperty
        this.mUIItem6Button.SearchProperties["InvalidSearchProperty"] = "foo-bar";
        you would get the following exception.
        System.ArgumentException: The property InvalidSearchProperty is not a valid search property.
        • FilterProperties are not supported. If you specify FilterProperties for a WinForms or WPF control,  you will get the following message.
        System.ArgumentException: Filter properties are not supported by the following technology: MSAA. To search for a control, you must remove the filter properties.
        NOTE also for all technologies,
        • If an invalid Property is used in GetProperty/SetProperty, it will throw a NotSupportedException.

        Monday, 19 January 2015

        How to add all controls on a page to the UIMap


        This blog says how to add all controls on a page to the UI Map. This can be done with the following code.
        Here I am adding all controls on the bing start page to the specified ui test file.

        First create a UITest object from a file(i.e. empty UITest file).
        You can add an empty UI Test file to your Test Project by right clicking on the Test Project and choosing Add –> New Item –> Coded UI Test Map.
        UITest uiTest = UITest.Create(uiTestFileName);

        The below 3 lines create a new UIMap object and adds it to UITest object
        Microsoft.VisualStudio.TestTools.UITest.Common.UIMap.UIMap newMap = new Microsoft.VisualStudio.TestTools.UITest.Common.UIMap.UIMap();
        newMap.Id = "UIMap";
        uiTest.Maps.Add(newMap);

        Now launch the browser, navigates to google.com and passes a reference to the browser & the UIMap object to GetAllChildren method. 
        GetAllChildren(BrowserWindow.Launch(new Uri("http://bing.com")), uiTest.Maps[0];);
        GetAllChildren is a method which recursively gets the children of the browser object and adds them to the UIMap.

        The whole code

        public void AddControlsToUIMap()
                {
        string uiTestFileName = @"<LOCATION>\TestProject\UIMap.uitest";
        UITest uiTest = UITest.Create(uiTestFileName);
        Microsoft.VisualStudio.TestTools.UITest.Common.UIMap.UIMap newMap = new Microsoft.VisualStudio.TestTools.UITest.Common.UIMap.UIMap();
        newMap.Id = "UIMap";
        uiTest.Maps.Add(newMap);

        GetAllChildren(BrowserWindow.Launch(new Uri("http://google.com/")), uiTest.Maps[0];);
                     uiTest.Save(uiTestFileName);
                }

        private void GetAllChildren(UITestControl uiTestControl, Microsoft.VisualStudio.TestTools.UITest.Common.UIMap.UIMap map)
                {
        foreach (UITestControl child in uiTestControl.GetChildren())
                    {
                        map.AddUIObject((IUITechnologyElement)child.GetProperty(UITestControl.PropertyNames.UITechnologyElement));
                        GetAllChildren(child, map);
                    }
                }

        You can now customize the code based on your need. 

        If you wanted to add the Childrens of specific type, instead of GetChildren, you can use FindMatchingControls