Ranorex Studio and Visual Studio are working together very well.

  1. The Ranorex Studio Project and Solution format is that of Visual Studio. You might want to open a Ranorex Project in VS to commit it to Team Foundation Server (TFS) of which VS is a natural client. You can also use MSBuild to build the Ranorex Project.
  2. The EXE or DLL that Ranorex produces is a .NET Assembly, which can be used in VS.
  3. An EXE or DLL that Visual Studio produces can be referenced in Ranorex Studio.

In this blog I want to take advantage of the second point in this list. I show work flows to do unit testing in Visual Studio by referencing .NET Assemblies produced with Ranorex Studio.

Ranorex_in_vs_with_comments

Sample Project

For the purpose of this blog I use the VIPTestSuite Sample that comes with Ranorex 3.0.

VIPTestSuiteSample

This Ranorex sample project’s assembly is used in this Visual Studio 2010 project: VIP_VS_Test

To run the project you need Visual Studio 2010 and Ranorex 3.0.

  • Open Ranorex 3.0
  • In the start page choose the sample as shown in the above screenshot
  • Build the Ranorex VIPTestSuite Sample (Menu: Build/Build Solution)
  • Open the downloaded and unzipped Visual Studio 2010 project
  • Build the Visual Studio Test Project (Menu: Build/Build Solution)
  • Run a test from within Visual Studio 2010
  • Or run a test with MSTest :
    mstest /testcontainer:VIP_VS_Test.dll /test:Test_AddAndDeleteSingleVIP

The Ranorex Studio Project

Let’s look at a Ranorex Studio Project. It contains:

  • XML files
    • Repositories (rxrep files)
    • Recordings (rxrec files)
      Recording files have a reference to a repository file.
    • Reports
  • .NET source code files (cs or vb files), generated code and user code
  • .NET assemblies as output files

What in such a project is usable from outside Ranorex Studio?

  • XML files: no.
    The XML format is only of importance within Ranorex Studio, for the Recorder, the Spy and the Editors.Note: With Ranorex Studio 3.0 the test suite file (.rxtst) was added. This is special in the sense that no .NET code is generated for it. It stays a XML file. Its purpose is Test Case Management and t is thus an alternative to NUnit’s and Visual Studio’s Test Case Management. It is very good to organize data driven test cases.
  • .NET source code: yes, but …
    The .NET Source Code files can be used in Visual Studio. Actually some people do program in VS using the Ranorex API. But by doing so one looses the advantages of the integrated test development that Ranorex Studio provides, the automatic synchronization between the XML files (repository or recording) and the code, the test suite, …
  • .NET assemblies: yes
    The .NET assemblies produced by Ranorex Studio are well confined entities in a standardized format, that can be referenced by other .NET projects, be it from Ranorex Studio or Visual Studio. The assembly contains all the classes for the recordings and the repository and can be used from C# or Visual Basic or any other .NET language.

Visual Studio and NUnit Attribute-based Test Assemblies

Given the new Test Management in Ranorex Studio, what could induce a tester to use Ranorex Assemblies in Visual Studio or NUnit?

In VS 2008 there is unit test support and this got some more attention in VS 2010. VS 2010 Ultimate provides full coverage of life cycle management and testing tools. The NUnit Test Framework also uses .NET and has wide acceptance. What they don’t provide is a support for all the technologies that Ranorex provides. In NUnit and Visual Studio test assemblies tests are methods with attributes that mark them as test methods. Visual Studio test assemblies use these attributes

  • [TestClass()] for the containing class
  • [TestMethod()] for the test method
  • [TestInitialize()] for a method that does initializations
  • [TestCleanup()] for a method that restores the previous state

Tests from such assemblies can then be started with MSTest.exe. To start tests using the NUnit framework (via console or GUI) the following attributes must be used:

  • [TestFixture()]
  • [Test]
  • [SetUp()]
  • [TearDown()]

The test drivers (MsTest.exe or nunit-console.exe) execute the tests and make a report file. That is a .trx file for MsTest.exe and a NUnit XML file for NUnit. Both of these formats, but more so the latter, can be recognized by popular Continuous Integration Frameworks, like CruiseControl and Hudson.

Ranorex Tests in Visual Studio Projects

When working with both, Ranorex Studio and Visual Studio, I would recommend the following workflow:

  1. Create a test solution with Ranorex Studio.
  2. Edit and extend tests in Ranorex Studio.
  3. Compile
  4. Create a Test Project in Visual Studio
    • Add the ranorex assembly as reference (exe or dll)
    • Add Ranorex.Core.dll as reference
    • For test suite projects: make a text resource referencing your Ranorex Studio’s rxtst file
  5. Edit and extend tests in Ranorex Studio.
  6. Compile
  7. Adapt Visual Studio projects to the changes in Ranorex Studio
  8. Repeat the last three steps

Note: When you run a test from within Visual Studio the file handle is not released. In order to compile again you need to restart Visual Studio.

In order to have an abort key, you need to set it in the constructor of the test class. This requires a reference to the System.Windows.Forms assembly.

public VIPUnitTest()
{
    Ranorex.Keyboard.AbortKey = System.Windows.Forms.Keys.Pause;
}

Recordings or User Code Modules

The generated class for a recording implements the ITestModule interface:

public interface ITestModule
{
    void Run();
}

Per default the Run() method is private, therefore for a recording the following public function is generated:

public static void Start()
{
    TestModuleRunner.Run(Instance);
}

To play a recording from Visual Studio do something like this.

[TestMethod]
public void PlayRecordingModules()
{
    try
    {
        VIPTestSuite.RecorderModules.StartSystemUnderTest.Instance.SutPath
            = SutPath;
        VIPTestSuite.RecorderModules.StartSystemUnderTest.Start();
        VIPTestSuite.RecorderModules.AddVIP.Start();
        VIPTestSuite.RecorderModules.CloseApplication.Start();
    }
    catch (Ranorex.ValidationException)
    {
        Assert.Fail();
    }
}

A Ranorex User Code Module must also implement the ITestModule interface. If no Start() method is provided, the code equivalent to the one above would be:

[TestMethod]
public void PlayUserCodeModules()
{
    VIPTestSuite.RecorderModules.StartSystemUnderTest.Instance.SutPath
        = SutPath;
    Ranorex.Core.Testing.TestModuleRunner.Run(
        VIPTestSuite.RecorderModules.StartSystemUnderTest.Instance);
    Ranorex.Core.Testing.TestModuleRunner.Run(
        VIPTestSuite.RecorderModules.AddVIP.Instance);
    Ranorex.Core.Testing.TestModuleRunner.Run(
        VIPTestSuite.RecorderModules.CloseApplication.Instance);
}

If the Ranorex Test Module test fails an exception will be thrown. If you don’t catch the exception, Visual Studio or MSTest will do so for you.

Ranorex Test Suite

There is no .NET API to access the test cases of a test suite. But one can access them using the command line parameters of the produced executable assembly. Test cases of a test suite are stored in the rxtst file, which is a separate XML file that needs to be deployed with the assembly.

MSTest per default copies test assemblies, but no additional files. This article from MSDN explains how to deploy additional files with MSTest. In short: Double Click on Local.testsettings and go to deployment.
Another alternative could be to provide a full path to the rxtst file:

Ranorex.Core.Testing.TestSuiteRunner.Run(
    typeof(VIPTestSuite.VIPTestSuiteRepository),
    @"/testsuite:C:testsVipTestSuite.rxtst");

But when deploying to different machines one has to care for an absolute path that is valid on all of them.
The alternative to deploying the rxtst file separately I use here is to integrate it as text resource into the VS test assembly. This way there is no need to separately deploy the rxtst file.

  1. Right-click on the project and select properties from the context menu
  2. In the resources tab click on the blue line in the center to create a resource file
  3. From the drop-down “Add Resource” choose “Add New Text File” and give it a name like VipTestSuite
  4. Find all occurences of VipTestSuite in the project
  5. In the .resx change the file path to
    ..........RanorexRanorexStudio ProjectsSamplesVIPTestSuiteVIPTestSuite.rxtst
    Note: This is the relative path into the Ranorex solution folder. The same file is used for Ranorex and Visual Studio. Take care to use the rxtst file that fits to the referenced VIPTestSuite.exe. They are linked via GUIDs.
  6. In the solution explorer remove VipTestSuite.txt that was generated when adding the text resource

Test methods accessing the ranorex test suite file (rxtst) would look like this:

[TestMethod]
public void Test_AddAndDeleteSingleVIP()
{
    int res = Ranorex.Core.Testing.TestSuiteRunner.Run(
        typeof(VIPTestSuite.VIPTestSuiteRepository),
        "/testcase:AddAndDeleteSingleVIP  /param:"StartPath="
        +SutPath+""", Resources.VipTestSuite);
    Assert.AreEqual(res,0);//-1 is return on failure
}

Note: Resources.VipTestSuite is provided as an additional parameter

Important:
The first parameter of Ranorex.Core.Testing.TestSuiteRunner.Run is a type of the referenced Ranorex assembly (VipTestSuite.exe in our case).

This conversion can be automated with a script. I have added this as a custom build step in the sample project. Remove it if you don’t have Python installed.

import sys

def rxtst_to_cs(rxtst_file,cs_file):
    """collects all root testcases and
    creates a C# file with a partial class
    containing the corresponding test methods"""
    from xml.etree.ElementTree import ElementTree
    rxtst = ElementTree()
    rxtst.parse(rxtst_file);
    method_template = """

            [TestMethod]
            public void Test_{0}()
            {{
                int res = Ranorex.Core.Testing.TestSuiteRunner.Run(
                    typeof(VIPTestSuite.VIPTestSuiteRepository),
                    "/testcase:{0}  /param:"StartPath="
                    +SutPath+""", Resources.VipTestSuite);
                Assert.AreEqual(res,0);//-1 is return on failure
            }}
    """
    methods = ""
    tests = rxtst.findall("content/testcase")
    methods += 'n'.join(
        [method_template.format(t.get("name")) for t in tests])
    tests = rxtst.findall("content/folder/testcase")
    methods += 'n'.join(
        [method_template.format(t.get("name")) for t in tests])
    tests = rxtst.findall("content/folder/folder/testcase")
    methods += 'n'.join(
        [method_template.format(t.get("name")) for t in tests])
    code_wrapping = """

    using System;
    using System.Text;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using VIP_VS_Test.Properties;

    namespace VIP_VS_Test
    {{
        public partial class VIPUnitTest
        {{
            {0}
        }}
    }}
    """
    with open(cs_file,'w') as f:
        f.write(code_wrapping.format(methods))

if __name__ == "__main__":
    rxtst_to_cs(sys.argv[1],sys.argv[2])

If you open the Microsoft Report file (trx file) you can also see the details about test failure, because the output of the Ranorex executable is recorded by the Microsoft test driver. In addition those details are also in the Ranorex rxlog file. This file can be rendered with the Internet Explorer, if you rename the extension to xml.

You might also like these articles