Bala
Bala

Reputation: 1203

Share Application under test object between multiple coded ui tests

I would like to start the application under test in a single test and use the opened application in the other tests. This is because starting the application takes quite sometime and it might be expensive if I repeat it for each test. I would like to have a single object of by AUT in the object map that is initialized along with the the UI map object.

This method fails because the object is not being passed between different tests even if it is static. Is there any solution to this issue?

UIMap

public partial class UIMap
{
    public ApplicationUnderTest _aut { get; set; }

    public void AUT_Open()
    {
        string AUTExecutable = ConfigurationManager.AppSettings["AUTExecutable"];
        _aut = ApplicationUnderTest.Launch(AUTExecutable );
    }
    ...
 }

Test

private static UIMap map;

[TestMethod]
public void Test01()
{
    ...
    this.UIMap.RecognitionDesigner_Open();
}

[TestMethod]
public void Test02()
{
    //Do something on the UIMap that tries to use the same member variable- _aut 
    //in the UIMap
}

Upvotes: 0

Views: 1532

Answers (3)

Ladislav
Ladislav

Reputation: 329

I had the same problem, i.e. the AUT object initialized in first test method was NULL in second method. I tried a lot of things but only one helped me: I had to make AUT property of the class static!

Here is my very simple code which uses calculator application.

using System;
using Microsoft.VisualStudio.TestTools.UITesting;
using Microsoft.VisualStudio.TestTools.UITesting.WpfControls;
using Microsoft.VisualStudio.TestTools.UITesting.WinControls;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UITest.Extension;
using Keyboard = Microsoft.VisualStudio.TestTools.UITesting.Keyboard;

namespace CUIT
{
    [CodedUITest]
    public class UITestDemo
    {
        private readonly string path = @"C:\Windows\SysWOW64\calc.exe";
        static ApplicationUnderTest app = null;

        [TestMethod]
        public void Start()
        {
            app = ApplicationUnderTest.Launch(path);
            Playback.Wait(1000);
            app.CloseOnPlaybackCleanup = false;
            app.SearchProperties[ApplicationUnderTest.PropertyNames.Name] = "Calculator";
            app.SearchProperties[ApplicationUnderTest.PropertyNames.ClassName] = "CalcFrame";
        }

        [TestMethod]
        public void TestButtonOne()
        {
            Assert.IsNotNull(app, "Should not be NULL!");
            app.SetFocus();
            WinButton btn1 = new WinButton(app);
            btn1.SearchProperties[WinButton.PropertyNames.Name] = "1";
            Mouse.Click(btn1);
            Mouse.Click(btn1);
            Mouse.Click(btn1);
            Playback.Wait(3000);
        }
    }
}

Upvotes: 0

Bala
Bala

Reputation: 1203

I was able to solve this issue by using _aut.CloseOnPlaybackCleanup = false;. Apparently, the reference to the UIMap object seems to get lost at the end of each test method.

public partial class UIMap
{
    public ApplicationUnderTest _aut { get; set; }

    public void AUT_Open()
    {
         string AUTExecutable = ConfigurationManager.AppSettings["AUTExecutable"];
         _aut = ApplicationUnderTest.Launch(AUTExecutable );
         _aut.CloseOnPlaybackCleanup = false;
    }
    ...
}

Upvotes: 1

nikita
nikita

Reputation: 2817

Tests run independent from each other and UIMap is recreated on each test. I suggest to use ClassInitialize attribute, since method marked with this attribute executes only once and before all tests in class. You will be absolutely sure that your process will be launched because now you are depended on the order of execution of tests, which is not good.

private static TestContext contextSave;

[ClassInitialize]
public static void DoOneTime(TestContext context)
{
    string AUTExecutable = ConfigurationManager.AppSettings["AUTExecutable"];
    _aut = ApplicationUnderTest.Launch(AUTExecutable );
    context.Properties.Add("AUT", _aut);
    contextSave = context;
}

[TestMethod]
public void Test01()
{
   //...
   DoSthmWithAUT(context.Properties["AUT"]);
}

[TestMethod]
public void Test02()
{
    DoOtherWithAUT(context.Properties["AUT"]);
}
[ClassCleanup]
public static void Cleanup()
{
     contextSave = null;
}

Notice, that in general you won't be able to tell that Test01 run before and only before Test02. If you really want order - then use Ordered Tests.

Upvotes: 0

Related Questions