TQL - Step by step
It doesn't take long for users new to Tricentis Tosca to come across TQL, or Tosca Query Language. This article contains a detailed description of how TQL can be used with virtual folders and in Reporting, in addition to the common search function.
A quick introduction
The TQL search is context-dependent. This means that the starting point has an effect on the search to be carried out. A search, which is performed on the basis of a project root element, produces different results from one based on the topmost Module folder.
TQL is deeply rooted in Tosca. Even the normal, Simple Search dialog is based on it.
To understand what this means, we'll conduct two searches for the term Insurant under the Simple Search tab in the search dialog: one from the project root element and one from the topmost Module folder.
TQL Search Dialog
The simple search based on the project root element returns approximately 80 hits (depending on how many times the ExecutionLists were previously started). The search based on the Module folder returns 4 entries (2 modules and 2 image files).
In the search settings, you can further limit your search to TestSteps by selecting TestSteps as the Objecttype. In the search dialog you can also switch from Simple Search to TQL Search. The search then looks as follows:
=>SUBPARTS:TestStep[(Name=?"Insurant")]
Each query starts with the arrowOperator=> or ->. The double arrow =>indicates that the operation is carried out recursively, while the single arrow -> indicates that a simple operation is performed. The expression ->SUBPARTS returns the subelements as results, whereas =>SUBPARTS returns the subelements of the subelements as well as the hierarchies beneath.
Structure of a TQL search
In our sample query, we have used SUBPARTSto search for all child elements. If we had used SUPERPARTS, we would have searched for parent elements instead. By adding :TestStep we restrict our search. A logical expression in square brackets adds a further restriction. In this example, we search for TestSteps whose names contain the value Insurant.
Both restrictions are optional. We could also search all TestSteps (by omitting the name restriction), search for elements with the value Insurant, or omit all restrictions and simply search all child elements.
Examples with explanation
Below we will provide you with some examples which can be useful on a daily basis. These examples build upon a basic knowledge of Tosca.
TestCases that are not assigned to any ExecutionLists
There are moments during every project when we would like to know if all created TestCases have been assigned to ExecutionLists.The following query answers this question:
=>SUBPARTS:TestCase[COUNT("ExecutionEntries")==0]
To analyze the query, we are searching through all subordinate subelements of the type TestCase. Furthermore, we only want to find elements that are not assigned to an ExecutionList, i.e elements which do not have any ExecutionEntries. This leads to the conditioned expression [COUNT("ExecutionEntries")==0].
In other circumstances, for instance in Requirements Management, it might also be of interest to find all TestCases that are assigned exactly once or more than once.
From one element to the next
All TestCase links that are not assigned to a TestCase could be of interest to Requirements Management. This example shows how to jump from one element to the next:
=>SUBPARTS:Requirement->TestCaseLink[COUNT("TestedBy")==0]
First, all Requirements are scanned and all corresponding TestCaseLinks are identified. Then these are filtered out by checking for the ones that still lack a TestedBy. With the command ->SUBPARTS:Requirement->TestCaseLink we can search for the TestCaseLinks that belong to the Requirements.
Auto completion can serve as a practical help with the data entry.
Linking several queries
Usually, one single condition is not sufficient for a more precise search. If you would like to perform more complex search queries you will come up against the limits of simple TQL very quickly, particularly in the use of elements. For this reason, TQL additionally supports the following set operations: UNION, COMPLEMENTand INTERSECTION.
Functions for set operations
From time to time, working with set operations requires the use of an absolute point of reference. The function PROJECT can be used for this purpose. PROJECT provides the project root element independent of the starting point.
The following expression returns a list of all Modules used in ExecutionLists.
![]() |
->PROJECT=>SUBPARTS:ExecutionList->SUBPARTS:ExecutionEntry->TestCase->SUBPARTS:TestStep->Module |
The search begins in the ExecutionLists, and continues with ExecutionEntries, TestCases and TestSteps.
But what you probably most want to know is which Modules are no longer of any use and can be marked for deletion. But this also means that you need all Modules not appearing in the last query, the complementary set.
->COMPLEMENT(->PROJECT=>SUBPARTS:Module,->PROJECT=>SUBPARTS:ExecutionList->SUBPARTS:ExecutionEntry->TestCase->SUBPARTS:TestStep->Module)
Another example is the search for orphaned TestCases, that is, TestCases that are not assigned to any Requirement.
->COMPLEMENT(->PROJECT=>SUBPARTS:TestCase,->PROJECT->AllOwnedSubItems:TCFolder[PossibleContent =? "Requirement"]=>SUBPARTS:Requirement->TestCaseLink->TestedBy)
Breaking down the individual components presents a clearer picture of the complementary set that is described here and mapped using COMPLEMENT. The first string ->PROJECT=>SUBPARTS:TestCase describes the set of all TestCases in the project. Since the second string is longer it may be useful to divide it up into its constituent parts.
The first part of this long string uses ->PROJECT->AllOwnedSubItems:TCFolder[PossibleContent =? "Requirement"] to search all folders that are both Requirement folders and beneath the project root. The next part =>SUBPARTS:Requirement->TestCaseLink->TestedBy first captures all subelements that are a Requirement. After this, the TestCaseLink objects are captured and all assigned TestCases are captured using TestedBy.
The complementary set of TestCases, which are linked to a Requirement by a TestedBy, to all TestCases equals the set of all orphaned TestCases.
TQL in virtual folders and reports
The power of TQL is used for various different functions within Tricentis Tosca. TQL queries can for instance be saved to virtual folders. A virtual folder is then created at the desired location in the project tree. The TQL query can be entered under Queryin the Properties tab.
Saving a TQL query to a virtual folder
The results of this search are displayed as the content of the virtual folder.
Virtual folder - view
There are several advantages to this. Not only is the display of frequently used queries clearly laid out, these queries can also, for example, be output as reports. The objects that are shown can be directly edited in the virtual folder. However, the virtual folder itself only displays one view of the objects. When a virtual folder is created, please keep in mind that the query is performed based on the position of the virtual folder.
To output a virtual folder as a report, a report must be created by selecting the option Create Report from virtual folder from the context menu of the virtual folder.
The report is created in the folder Reporting under GeneratedReports.
A report created from a virtual folder
TQL Checklist
![]() |
Did I choose the correct starting point? |
![]() |
Have I used the arrow operators correctly? Am I searching within the correct levels? |
![]() |
If you get stuck: in 90% of cases there is more than one way to solve the problem. For example, take more than just the SUBPARTS into consideration; try the SUPERPARTS as well. |
Need a hand with
![]() |
Tosca uses special characters for certain functions. Special characters, which are used as values, require a backslash as an escape character (e.g. [Name == "1\\2"] if the name is 1\2). |
Related topics in the Web Help:
Short, everyday examples (consider this as an inspiration)
as well as sections in the following chapters: Virtual folders, Test data management, or Reporting.
![]() |
Do you have any practical examples you would like to share with us? Or would you like to report change requests or make suggestions for improvement? Please do not hesitate to use the feedback option to enter into contact with us. |