Accessing parent test case parameter via code

Class library usage, coding and language questions.
kmck
Certified Professional
Certified Professional
Posts: 83
Joined: Fri Jul 12, 2013 2:41 pm

Accessing parent test case parameter via code

Post by kmck » Fri Jan 24, 2014 8:13 pm

How would I programmatically access the value of a parameter declared in a parent (or ancestor) test case from a nested test case?

I change the value of that parameter within the test cases and I want to access the original initialized value after each run of its child (or descendant) test cases rather than pass the changed value from one test case to the next.

krstcs
Ranorex Guru
Posts: 2683
Joined: Tue Feb 07, 2012 4:14 pm
Location: Austin, Texas, USA

Re: Accessing parent test case parameter via code

Post by krstcs » Fri Jan 24, 2014 9:27 pm

You probably should not be changing the actual test data during the run. While there are a (very) few valid reasons for this, most of the time, they don't really apply, we are just trying to make things too complicated.


It might be easier to add another Global Parameter that is the "Working" parameter. Then you just use it for the interim, temporary changes that happen during your run.

So, if your initial parameter is TEST_VAL_1, your working parameter could be TEST_VAL_1_WORK. You would set your TEST_VAL_1 at the start of the test, and then use TEST_VAL_1_WORK during the actual runs to store and manipulate.
Shortcuts usually aren't...

krstcs
Ranorex Guru
Posts: 2683
Joined: Tue Feb 07, 2012 4:14 pm
Location: Austin, Texas, USA

Re: Accessing parent test case parameter via code

Post by krstcs » Fri Jan 24, 2014 9:35 pm

As an example, in your module you could have something like:

1. Mouse..Click..MyTextBox
2. KeySequence..$TEST_VAL_1..MyTextBox
3. GetValue..Value..$TEST_VAL_1_WORKING..MyTextBox

Or as seen in one of my tests:
Attachments
Example.png
Example.png (5.63 KiB) Viewed 4605 times
Shortcuts usually aren't...

kmck
Certified Professional
Certified Professional
Posts: 83
Joined: Fri Jul 12, 2013 2:41 pm

Re: Accessing parent test case parameter via code

Post by kmck » Fri Jan 24, 2014 9:54 pm

Thank you krstcs! I think adding a global variable as well as a local variable to the specific test case would probably work best. In my scenario, I am altering the value to run a sql query whose value I can only obtain at runtime.

For instance, as my parameter value I have:

Code: Select all

SELECT ticket FROM tickets WHERE ticketid = varValue;
And prior to running that I'll have a code module that grabs the value at runtime, and applies it to the screen replacing varValue with the actual value.

The tricky part is I have a fairly complicated query to run and applied it to all nested test cases (all of which will use that complicated query to validate data, but whose varValue will be different). But being at the parent level, instead of getting

Code: Select all

SELECT ticket FROM tickets WHERE ticketid = varValue;
varValue will instead be replaced with the previous test case's inputted value. I was hoping there was something I could do in teardown to reset the parameter's value, but it looks like I'll either have to use your method or apply that complicated query as a parameter value for each of those individual test cases, which would likely make future maintenance on that query a pain.

krstcs
Ranorex Guru
Posts: 2683
Joined: Tue Feb 07, 2012 4:14 pm
Location: Austin, Texas, USA

Re: Accessing parent test case parameter via code

Post by krstcs » Fri Jan 24, 2014 10:42 pm

AHHH!! I feel your pain!

I too need to dynamically query SQL at runtime.

What I did is I created stored procedures that return the structure I need, but they always default to returning 0 (zero) rows. Then I have custom code modules for each SQL data connector that I call right before I use that connector. In that "manipulator" module I set the SQL query to the value I want.

So, let's say I have a customerID in my parent test case and he has X-number of orderIDs, I need to run test cases for each order (and each sub-order group, and each item in each group, and each quantity change and... yeah, you get the point...).

I will have a "CustomerOrderInfoSQL" SQL data connector that has "exec GetCustomerOrderInfo @CustomerID=0" as the default query, which will return 0 rows, since there are no customers in the DB with an id of 0. My "manipulator" module would be called "Set_CustomerOrderInfoSQL_for_CustomerID" (my naming conventions prefer long human-readable strings... :D) will look like this:

Code: Select all

        /// <summary>
        /// Constructs a new instance.
        /// </summary>
        public Set_CustomerOrderInfoSQL_for_CustomerID()
        {
            // Do not delete - a parameterless constructor is required!
        }

        string _CustomerID = "";
        [TestVariable("E30C24EB-F235-4568-B4B1-61E7337136F0")]
        public string CustomerID
        {
        	get { return _CustomerID; }
        	set { _CustomerID = value; }
        }
        
        /// <summary>
        /// Performs the playback of actions in this module.
        /// </summary>
        /// <remarks>You should not call this method directly, instead pass the module
        /// instance to the <see cref="TestModuleRunner.Run(ITestModule)"/> method
        /// that will in turn invoke this method.</remarks>
        void ITestModule.Run()
        {
            Mouse.DefaultMoveTime = 300;
            Keyboard.DefaultKeyPressTime = 100;
            Delay.SpeedFactor = 1.0;
            
            TCS_LIB.Data.SetupSqlDataConnector("CustomerOrderInfoSQL", string.Format("exec GetCustomerOrderInfo @CustomerID={0}", CustomerID));
        }
The last line is key. It calls a library module that does all the connector work, basically, for the "named" connector, change the SQL query to the product of the string.Format() method. The library method looks like:

Code: Select all

        public static void SetupSqlDataConnector(string dataCacheName, string queryString) {
            ((SqlDataConnector)DataSources.Get(dataCacheName).Connector).Query = queryString;
        }
I pass in the CustomerID as a module variable so Ranorex allows me to bind it in the test case so I can pass it in from the parent test case's data set.

I do this same thing for most of my data sets. We have a very complex data structure for customer purchases and such, and this allows me to feed it all in at run-time in a way that can also control the flow of the test based on the data. If a manipulator returns no rows, then the associated child test case will be skipped.


I believe they are working on a way to pass test parameters/variables into the SQL connectors, but I don't know for sure if/when that will happen.
Shortcuts usually aren't...

kmck
Certified Professional
Certified Professional
Posts: 83
Joined: Fri Jul 12, 2013 2:41 pm

Re: Accessing parent test case parameter via code

Post by kmck » Mon Jan 27, 2014 7:28 pm

I like your method! Thank you for sharing it, I'm going to give it a whirl and see how it works with my test cases. I suspect it will work very since your queries are a bit more complex than the queries I will have to run (I only really need to input one variable per query, rather than multiple dynamic variables. Thinking about that makes my head hurt a little :) )

I remember during one of the Ranorex workshops they mentioned a future possibility passing parameters into your SQL connector, which would definitely be very helpful. Here's hoping it's implemented sooner than later!

krstcs
Ranorex Guru
Posts: 2683
Joined: Tue Feb 07, 2012 4:14 pm
Location: Austin, Texas, USA

Re: Accessing parent test case parameter via code

Post by krstcs » Mon Jan 27, 2014 8:44 pm

I try to only have one test variable per module for these, but there are a few that need multiple inputs.

I actually really enjoy that part of it, making the test data look and behave like real world data would. But I'm probably just weird that way...

If you have any issues let me know, always fun to see different implementations and figure out new ways to approach the problems.


And I agree whole-heartedly with you on hoping they get it soon! :D
Shortcuts usually aren't...

krstcs
Ranorex Guru
Posts: 2683
Joined: Tue Feb 07, 2012 4:14 pm
Location: Austin, Texas, USA

Re: Accessing parent test case parameter via code

Post by krstcs » Mon Jan 27, 2014 9:02 pm

OK, I put together a demo project for this so that anyone else that needed it could have a template to work with.

Make sure to setup the SQL connector correctly (I didn't put one in here).

Let me know if you have any questions.


EDIT TO ADD: The ONE big problem is that you might need to have lots of the manipulator modules, one for each different combination of values with stored procedures. You will also want to use stored procedures wisely. If you want to do it all with straight SQL queries, you can, but stored procedures are usually faster and easier to maintain. Let the DB handle data manipulation since that is what they are good at.
Attachments
SQLDataConnectorDemo.zip
(12.14 KiB) Downloaded 195 times
Shortcuts usually aren't...

mojohlic
Posts: 31
Joined: Thu Oct 11, 2012 4:37 pm

Re: Accessing parent test case parameter via code

Post by mojohlic » Tue Feb 18, 2014 5:56 pm

I thought I could just make a comment because somebody is going to look for an answer to that question : Accessing parent test case parameter via code.

I do use it several times to get data in code, to pass data from and to other test cases, or to code modules etc.

So, I use this:

TestSuite.Current.GetTestCase("your parent test case name"").Parameters["Name of parameter"]

Sample:
string temp = TestSuite.Current.GetTestCase("TC_Temp").Parameters["tc_parameter"];

you can also get the data source this way:
TestSuite.Current.GetTestCase("your test case name").DataContext

Sample to know the row that you are in:
int row = TestSuite.Current.GetTestCase("TC_Temp").DataContext.CurrentRowIndex;

kmck
Certified Professional
Certified Professional
Posts: 83
Joined: Fri Jul 12, 2013 2:41 pm

Re: Accessing parent test case parameter via code

Post by kmck » Mon Apr 28, 2014 6:01 pm

Thank you very much, krstcs for posting the solution, and mojohlic for the answer to the original question! :D

JimLin
Posts: 38
Joined: Mon Jun 02, 2014 4:23 pm

Re: Accessing parent test case parameter via code

Post by JimLin » Fri Jun 13, 2014 11:55 am

Krstcs, thanks for the solution and demo.

After a day banging my head on my desk trying to get this to work, I discovered that if I had followed the instructions provided in the demo properly, I would have got it working in about 30 minutes :( .

User avatar
odklizec
Ranorex Guru
Ranorex Guru
Posts: 3922
Joined: Mon Aug 13, 2012 9:54 am
Location: Zilina, Slovakia

Re: Accessing parent test case parameter via code

Post by odklizec » Wed Jun 24, 2015 12:11 pm

Hi,

Sorry for reopening this old thread. I too want to access the parent test case from current one (via code). I'm already using the way suggested by mojohlic. But I would like to avoid accessing parent test cases by their name, because of the risk of renaming test cases. So I would rather like to find the parent test case using TestSuite.Current and then somehow access its parent TC.

I found there is a method GetParentTestCase [TestSuite.GetParentTestCase(TestSuiteEntry entry)], but I'm not quite sure what should be used as argument? And there seems to be nothing in Ranorex API about GetParentTestCase. Thanks in advance!
Pavel Kudrys
Ranorex explorer at Descartes Systems

Please add these details to your questions:
  • Ranorex Snapshot. Learn how to create one >here<
  • Ranorex xPath of problematic element(s)
  • Ranorex version
  • OS version
  • HW configuration

User avatar
odklizec
Ranorex Guru
Ranorex Guru
Posts: 3922
Joined: Mon Aug 13, 2012 9:54 am
Location: Zilina, Slovakia

Re: Accessing parent test case parameter via code

Post by odklizec » Wed Jun 24, 2015 12:37 pm

OK, I found the way around. This code access parent Test Case from the actual one...

Code: Select all

var TC = (TestCase)TestCase.Current; 
var curTC = TestSuite.Current.GetTestCase(TC.Parent.Name);

However, I'm still curious about proper use of GetParentTestCase ;)
Last edited by odklizec on Tue Jul 07, 2015 11:26 am, edited 3 times in total.
Pavel Kudrys
Ranorex explorer at Descartes Systems

Please add these details to your questions:
  • Ranorex Snapshot. Learn how to create one >here<
  • Ranorex xPath of problematic element(s)
  • Ranorex version
  • OS version
  • HW configuration

mojohlic
Posts: 31
Joined: Thu Oct 11, 2012 4:37 pm

Re: Accessing parent test case parameter via code

Post by mojohlic » Wed Jun 24, 2015 2:35 pm

Thanks odklizec for the posting. Very informative :D