# Parameters

Working with [Loadmill](https://www.loadmill.com) makes it very easy to convert recorded browser/network sessions (via HAR files) into test scenarios. But once a scenario has been created, it often needs to be **parameterized** in order to denote the dynamic parts of your API.

This is best explained by example, so let's have a look at the following test scenario:

1. User adds a blog post: `curl https://www.myblog.com/posts --data "Hello World!"`
2. User likes his own post: `curl -X PUT https://www.myblog.com/posts/123/like`

The `123` part is the identifier of the blog post created by the user - it cannot be known in advance because it is generated by the server at runtime. This is a very common use case for **parameters** and is handled by two simple steps:

1. [Extract](#parameter-extraction) the ID from the first response into a parameter, e.g. `postId`
2. Embed the parameter in the second request URL: `https://www.myblog.com/posts/${postId}/like`

You may embed parameters with the `${}` syntax in the request URL as well as the request body, request headers, [extractions](#parameter-extraction), [assertions](https://docs.loadmill.com/api-testing/test-suite-editor/parameters/assertions) and more.

Note that any parameterized expression such as `posts/${postId}` will remain as-is if no such parameter is defined or extracted before the expression is evaluated.

## Default Parameters

Another common use case for parametrization is when you want to **reuse test scenarios** on different environments or with small adjustments.

Let's extend our first example by requiring that the user provide credentials via **basic authentication**. This means our new URLs could look like this:

1. `https://testUser:testPassword@www.myblog.com/posts`
2. `https://testUser:testPassword@www.myblog.com/posts/${postId}/like`

If you would like to use different credentials for every test run, you may replace the username and password with parameters and set their values in the [Test Suite Parameters](https://docs.loadmill.com/api-testing/test-suite-editor/test-suite-parameters) tab whenever you reuse the test. So now the URLs will look like:

1. `https://${user}:${pass}@www.myblog.com/posts`
2. `https://${user}:${pass}@www.myblog.com/posts/${postId}/like`

Using parameter defaults is especially useful for automated testing and CI where you may be testing a different server every time you run a test. Please refer to the [Loadmill CLI and npm module](https://www.npmjs.com/package/loadmill#parameters) for more information about how to inject parameters dynamically in such scenarios.

## Parameter Extraction

Parameters can be defined and populated with values dynamically after each request in your test scenario.

![](https://684333474-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LHDbUNdi3wPd9vSolzU%2Fuploads%2Fgit-blob-f52c06b4432a7ad8e86e2fea890a3ad39d869023%2FScreenshot%20-%202021-10-03T143044.215.png?alt=media\&token=68ccd39b-8d89-4342-8d07-a0be29937d0d)

There are several **extraction query types** that may be used:

* **JSONPath** - used for extracting values from a JSON response. For example, the query `$.post.id` will extract the value `123` from this JSON response:

```javascript
 {
     "post": {
         "id": 123,
         "text": "Hello World!"
     }
 }
```

![](https://684333474-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LHDbUNdi3wPd9vSolzU%2Fuploads%2Fgit-blob-0cb281731e6ead3ab7fdb557fdd1c50a36ecfdd3%2FScreenshot%20-%202021-10-03T143158.042.png?alt=media\&token=2f5a17f8-a05a-4cd9-bc2c-8dacaabaea73)

* **JQuery (Cheerio)** - used for extracting values from XML/HTML responses. We use a subset of the JQuery selector syntax called [Cheerio](https://cheerio.js.org). You may add an optional (but very useful) **attribute** input to your query that selects an attribute value from the first element found by the jQuery. If you do not provide an attribute to select, the query will simply output the inner content of said element.
* **JS RegExp** - used for extracting arbitrary values from any kind of textual response via regular expressions with capture groups. For example, we can extract the `id` field from the same JSON response we've seen above using a regular expression: `.*"id":\s*([0-9]*)`.
* **Header** - used for extracting response header values via header names.
* **Assignment** - used for assigning an explicit value to a parameter or [a function](https://docs.loadmill.com/api-testing/test-suite-editor/functions) to an existing parameter. Previously defined or built-in parameters may be embedded within the string, e.g. `https://${host}/path/to/glory` or `The time is ${__now}`.
* **Clojure** - used for extracting values from Clojure (EDN content type) responses. Querying the data is done using JSONPath. For example, the query `$[":user"][":id"]` will extract the value `56` from this EDN response:

```
 {:user {:role :viewer, :name "Rivi", :teams nil, :id "56"}}
 
```

Previously defined or built-in parameters may be embedded within **any kind of extraction query**. These parameters will be evaluated right before the query itself is evaluated.

## Built-in Parameters

There are several **built-in** parameters that you can use in your test scenario. They are:

* `__status` The status code of the last HTTP response.
* `__statusText` The status text of the last HTTP response.
* `__responseTime` The total response time (in milliseconds) of the last HTTP response.
* `__testRunId` - The test run id: (Suite / Flow / Load)
* `__testStartTime` - The test run start time (UTC in milliseconds)
* `__launchedBy` - The name of the user running the test.

**Note:** some previous built-in parameters are now defined as no-argument [parameter functions](https://docs.loadmill.com/api-testing/test-suite-editor/parameters/functions) and can still be used in the same way.

## Advanced Usage

So far, we've only seen how to inject a simple parameter value into an arbitrary expression, e.g. `Hello ${name}`. However, it is also possible to inject a ***computed value*** using [Parameter Operators](#operators) or [Parameter Functions](https://docs.loadmill.com/api-testing/test-suite-editor/functions), e.g. `The total price is ${price + __mult(price,tax)}`. You may use operators or functions anywhere parameters may be used.

Computed values can be extremely useful when you need to introduce conditional behavior to your test. Say you want to skip **Purchase Request** if the preceding **Get Price Request** response returns a price above the current budget. This could be accomplished by extracting the price to a parameter and setting the **Purchase Request** skip condition to `${budget <= price}`.

![](https://684333474-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LHDbUNdi3wPd9vSolzU%2Fuploads%2Fgit-blob-63038782c643304d87a116a7f09ece5468a1ba4b%2FScreen%20Shot%202021-10-05%20at%2016.45.21.png?alt=media\&token=61c8a93f-f5ef-4181-8884-1de81343726e)

You may also use ***literal values*** within expressions, e.g. `${__if_then_else(is_good,'Success!',':_(')}` - but be aware there are some [syntactic limitations](#notes-and-limitations).

Function calls without arguments can be used with or without parentheses, e.g. `__random_uuid` can be used instead of `__random_uuid()`.

See below the full list of supported [operators](#operators) and [functions](https://docs.loadmill.com/api-testing/test-suite-editor/functions).

### Notes And Limitations

Current syntax has some limitations. Syntax errors are easy to spot in the GUI - a malformed expression will simply not be highlighted.

If an expression is invalid due to its syntax it will simply remain as-is and will not be computed nor replaced at run-time. If, however, an operator or a function receives invalid input (e.g. division by zero or any of the parameter arguments not having a value) the test will fail with an error.

Note that predefined parameter values (AKA [Parameter Defaults](#default-parameters)) are computed whenever a test configuration is validated - thus computation related errors will render the test configuration invalid.

Current syntax limitations are:

* Operators ***must*** be separated from their arguments by spaces, e.g. `${x + y}` is fine but `${x+y}` will not be computed.
* Spaces are ***not allowed*** anywhere else within an expression, e.g. both `${__add(x, y)}` and `${fullName == 'John Doe'}` will not be computed.
* **Literal values** may not contain whitespace characters, commas (`,`) or single quotes (`'`). These cannot be escaped - simply define a previous parameter with the desired value when the need arises. Note that numeric literal values need to be quoted the same as any other value, e.g. `${x > '0'}` is OK but `${x > 0}` will not be computed.
* You may chain multiple operations together, e.g. `${x * y + z}` but you may ***not*** use parentheses to set precedence, e.g. `${(x * y) + z}` will not be computed. This can usually be worked around using functions though, e.g. `${__mult(x,y) + z}`
* All operators have the ***same precedence*** - computations always conform to right-associativity, i.e. `${x * y + z - j + k}` will be computed as `x * (y + (z - (j + k)))`.
* Computations may ***not be nested***, i.e. you may not pass a computed value as an argument to function, e.g. `${__mult(x,y) + z}` is OK but neither `${__mult(x + y,z)}` nor `${__mult(__add(x,y),z)}` will be computed.
* Unary operators, e.g. `${-x}` are ***not*** supported. This can be overcome using functions such as [\_\_neg](https://docs.loadmill.com/api-testing/test-suite-editor/parameters/functions#__neg-p-1) or [\_\_not](https://docs.loadmill.com/api-testing/test-suite-editor/parameters/functions#__not-p-1).

### Operators

The currently supported operators are:

#### Textual Operators

* `=` Strict equals operator. Aliases: `==` and `===`.
* `!=` Strict not-equals operator. Alias: `!==`.

May be applied to any two parameters which have values.

#### Boolean Operators

* `|` Logical OR operator. Alias: `||`.
* `&` Logical AND operator. Alias: `&&`.

May be applied to any two parameters which have values.

#### **True Semantics**

A parameter translates to boolean `true` if and only if

* It has a value ***and***
* The value is not an empty string ***and***
* The value is not equal to `false`, `FALSE`, `FaLsE` or any other combination of upper-case and lower-case letters that forms the word `false`.

The computed value of a valid boolean operation is either exactly `true` or exactly `false`.

#### Numeric Operators

* `+` Addition operator.
* `-` Subtraction operator.
* `*` Multiplication operator.
* `/` Division operator.
* `<` Less-then operator.
* `<=` Less-then-or-equals operator.
* `>` Greater-then operator.
* `>=` Greater-then-or-equals operator.

May be applied to any two parameters which have values that translate to ***finite numbers***. Computed values are ***not*** rounded to integers.

###
