Des nouvelles sur les QF modules print(…) et println(…)

If you are working with QF-Test scripting nodes, no matter whether you prefer Jython, Groovy or JavaScript, you will come across the QF module sooner or later. This module, accessible in all script nodes and script terminals via the variable qf, holds a bunch of helper methods designed to make the life of a script programmer easier.

From time to time the module will be enhanced by new methods – in QF-Test 4.6.0 by the methods  print and println. A good opportunity to have a look at the module and its new methods.

qf.print(ln)

The method qf.print(…) prints a string (resp. the string value of an object) to the QF-Test terminal (and with SUT scripts also to the client terminal). qf.println(…) adds a line break to the output to ensure the next output will be printed to a new line. But why not just use a simple  print (without qf. in front)?

Theoretically yes, but… The classic print writes a string to the so-called Standard Output of the program. QF-Test intercepts the string and redirects it to the terminal. Usually, this works all right, however, especially with SUT scripts, you might run into the problem that the client application itself redirects the Standard Output thus preventing QF-Test ever to ‘see’ the output. This can become really annoying when you need to resort to the classic ‘print debugging’ when writing resolvers.

qf.print(…) skirts the problem, not transmitting the string via the normal output channels, but sending it ‘directly’ via the internal RMI interface (i.e. via the same ‘line’ QF-Test uses to control the SUT and to send values for checks and events). Now, client specific adaptions will not matter anymore and on top it is slightly more efficient.

The small print

I would like to go into detail with some side effects:

1. qf.print(…) does not only take one parameter but as many as you like and joins them by space characters. This little JavaScript program:

const x = 1  
const y = 1  
const z = x + y  
qf.println(x,y,z)

will produce the terminal output ‘1 1 2'.

2. qf.print(…)calls the Java string method toString() to generate the output. So, if you have been trying in vain to check whether the Jython array module really produces a Java array:

import array  
from java.lang import String  
   
print array.array(String,("a","b","c")) # array(java.lang.String, [u'a', u'b', u'c'])

qf.println(…) will now be a solution:

import array  
from java.lang import String  
   
qf.println(array.array(String,("a","b","c"))) # [Ljava.lang.String;@353191ee]

The first script will print a Jython string representation of the array (« When an array object is printed or converted to a string, it is represented as array(typecode, initializer). « ), however not representing the view of Java on the object. The second script will print the output of toString() for Java arrays, i.e. the type information and its hash code (just for once this output will prove helpful in order to check it is a real Java array. In the Java world you would rather prefer Arrays.deepToString(a) to see the content). If you want to print the Jython string representation just add  str(…): qf.println(str(array.array(String,("a","b","c")))).

3. Like the other ‘standard’ variables (rc, out, resolvers, notifications, …) with Groovy scripts qf principally only works on top level:

class InnerClass {  
    def printSomething() {  
        println("Something")  
    }  
       
    def printSomethingElse() {  
        qf.println("SomethingElse")  
    }  
}  
   
def c = new InnerClass()  
   
c.printSomething() // => Does not reach the terminal in a Server-Script nicht im Termial an, because "println" directly uses the standard output.  
c.printSomethingElse() // => "No such property: qf for class: InnerClass"

To get around this, you can transfer the bindings via the contructor to the inner class:

class InnerClass {  
      
    def out,qf  
       
    def printSomething() {  
        out.println("Something")  
    }  
       
    def printSomethingElse() {  
        qf.println("SomethingElse")  
    }  
}  
   
def c = new InnerClass(out:out,qf:qf)  
   
c.printSomething()  
c.printSomethingElse()

Simple and effective, especially when writing your own checker or when updating older resolvers.

Nous utilisons des cookies "Matomo" pour l'évaluation anonyme de votre visite à note page web. Pour cela nous avons besoin de votre consentement qui est valable pour douze mois.

Configuration de cookies

Cookies fonctionnels

Nous utilisons des cookies fonctionnels pour garantir la fonctionnalité de base du site web.

Cookies de performance et de statistique

Nous utilisons Matomo pour analyser et améliorer notre site web. Des cookies permettent une collection anonyme des informations qui nous aident à vous offrir un visite clair et facile à utiliser de nos pages web.

Détails des cookies
Description Fournisseur Durée de vie Type But
_pk_id Matomo 13 Mois HTTP Contient un identifiant de visiteur unique et pseudonymisé interne à Matomo pour reconnaître les visiteurs qui reviennent.
_pk_ref Matomo 6 Mois HTTP Utilisé pour suivre à partir de quel site Web l'utilisateur anonymisé est arrivé sur notre site Web.
_pk_ses Matomo 1 Jour HTTP Le cookie de session Matomo est utilisé pour suivre les demandes de page du visiteur pendant la session.
_pk_testcookie Matomo Session HTTP Utilisé pour vérifier si le navigateur du visiteur prend en charge les cookies.
_pk_cvar Matomo 30 Minutes HTTP Stocker temporairement les données relatives à la visite.
_pk_hsr Matomo 30 Minutes HTTP Stocker temporairement les données relatives à la visite.