How to pass variables between test cases in a suite (the "right" way...)

Hey all,

I would just like to share a super simple approach to passing variables between test cases in a suite, as I’ve seen many topics over the years with questions on how to do this efficiently. To be clear, there are already several approaches to this, including, but not limited to:

1.) Creating “empty” GlobalVariables in a Profile, assigning values to those variables at runtime, then consuming them as a global variable in later scripts.

  • This approach works fine, but in my opinion is non-ideal, as it contaminates the GlobalVariable namespace with a bunch (potentially 1000’s) of empty variables of global scope.

2.) Using callTestCase() with parameters.

  • This also works fine, but is cumbersome both syntactically and in terms of test case organization, “Variables” tab usage, etc. (again, in my opinion).

3.) Writing the variables to data files.

  • This can also be quite cumbersome, and of course any data will persist even after a test case/test suite ends, which has the potential to cause a lot of problems.

Instead, we can use static collections to do this.

Create a utility class which just instantiates a few different types of collections, with a static reference:


What this means is that any values put into these collections will be available for the lifetime of any Test Case and/or any Test Suite. For example, if I have two test cases, and put both into a suite, I can pass a variable generated in TC1 into the map, and retrieve that value when the suite runs TC2:





Test Suite:




To demonstrate that the lifetime of this variable map is that of the test suite (and no longer), if I then just run TC2 alone, you’ll see that the value is no longer in there:


Disclaimer: I’m aware that this is nothing groundbreaking. All it takes is understanding the nature of static references. I’m just sharing this because I’ve yet to see this solution posted anywhere. Also, I generally write scripts in such a way that there are zero external dependencies (they are “hermetically sealed”), but have some colleagues that had this requirement, so yeah…

Hopefully this is helpful :wink:


I’ve posted it but you’re right in the sense that I didn’t make a point of describing the full mechanism. I have a map GLOBALS which is populated from GlobalVariables, JSON data read from disk and a few other bits and pieces.

Yeah, it’s not very neat and could do with a cleanup :confused:

Great post though, Brandon. :clap: Bookmarked.

1 Like

Link? Thanks!

Here’s one: How to use Global Variables between test suites while executing Test Suite Collection?

Context is different but you get the gist.

Like you said, kinda hard to tell what’s happening, but I agree, it’s the same general idea. Nice.

1 Like

Yes, no, kinda…

Yours is far more robust, especially in terms of types. Mine is minimalist by comparison (belies my JS tendencies, relying on coercion etc). But that’s okay, I can call on you when I need something more-better-good :wink:

Boths solutions are great, used with the right context.
The one proposed by @Brandon_Hein may be faster since everything is stored in memory, but won’t persist across suites in a collection. With the caveat that … with large amount of data can be memory hungry
The one presented by @Russ_Thomas may be a bit slower but will work across suites and will preserve the final data set for debug if needed. And with a proper flush-to-disk routine can be memory friendly.
One may use a combination of those, using properly written hooks
Nice job, guys! Kudos!

L.E. one day i will present my POC using an sqlite db. That may solve both remaining issues. But not yet … everybody knows I am lazy …

1 Like

One too many moving parts for my tastes. :stuck_out_tongue_closed_eyes:

This is true. Good point.

In theory, sure. In my example, I’ve allowed the collections to contain Objects, so if the script-writer added many many large objects, the heap may be exceeded. But:

1.) This could be tempered by only allowing Strings in the collections (i.e. <String, String> instead of <String, Object>, etc.).
2.) Probably 99% of the time, the script-writer would only every use this for storing String vars anyway. You would need several million of these entries before having to worry about memory.

Great observations!

@Brandon_Hein, would it work if the test suite is being run in parallel (e.g. in multiple browsers)?

No, these collections are not thread safe. You could easily make them so by throwing them into a ThreadLocal though, for example:

public static ThreadLocal<Map<String, Object>> map = new ThreadLocal<Map<String, Object>>();


However, you’d have to ensure that the test cases that were sharing the collection were running on the same thread, which is not really possible to do…

1 Like

2 Test Suites running in parallel run in 2 separated OS processes (independent Java VMs). See the following post for detail:

Therefore thread-safety of collections would not matter much when you run 2 Test Suites.

Thread-safety matters only when you create threads in Test Cases yourself. I do not think there are many people who does multi-threading in Katalon Studio, but there are some posts regarding multi-threading in Test Cases.

1 Like