Copy a Test

Here we will show you how to copy and paste a test. Before that, it should be noted that this is often not the right thing to do. Take a step back and ask yourself if this is actually the perfect solution. Often users get into habits of doing things the way they were used to, but there are many things we have specifically built to improve work efficiency. Some questions to ask yourself:

  • Are you looking to do negative testing? You can potentially do that in the same test using data sets and the IF component + status codes.
  • Are you looking to run from different environments? No problem with Presets.
  • Do you want to run most, but not all, test in a specific project? Execute tests using tags. (example, using a unique webhook and the tag of ‘live.’)

First, enter the project and test. Then click over to the Published version of the test, then the Copy to Clipboard option becomes available.

copy 1

Click Copy to Clipboard and then browse to the Tests view of the same, or another project. There Paste from Clipboard becomes available.

copy 2

So here is that entire adventure in video form.

Writing Tests in Code

API Fortress has three unique advantages in the market – magic, the visual composer, and the built in assertions/operations. With that said, you are not bound to them exclusively. If you are more comfortable using code, that option is available as well.

Code View

First, the whole test can be seen and edited “naked,” without our glamorous UI. Behind the curtains, the test is described using the XML markup language.

To use it, you simply need to look at the top right of the composer. The default is VISUAL COMPOSER, but right next to it is CODE VIEW. Click that.

code view - 1

Now you will see the markup language that is the basis of API Fortress.

code view - 2More experienced tests may find this to be the most efficient manner to use the platform.
Tip: The best way to learn the markup? Build your tests using the visual composer/magic, then switch to code view and have a look!

A Groovier Approach

Whether you are using the code view, or the visual composer, one important aspect to note is that all “evaluated” fields are actually able to execute a subset of Groovy commands.

For example, let’s take this assertion that verifies whether the “items” element is an array.
assert-is
Or in code view:
<assert-is expression="payload.whatever.items" type="array"/>

Now let’s say you know something more about this array, such as it should always contain more than 3 elements:

assert_greater

Or in code view
<assert-greater expression="payload.whatever.items.size()"  value="3" type="integer"/>

Notice how in the expression field we deliberately used the size() command to retrieve the size of the object at its left.

Even More Serious Grooviness

Moreover, Groovy can be put within SET components.

The first scenario is when you want to set a variable that is not a String. The best way to do it is using the Variable Mode “Object.” The value, in this case, will be evaluated as Groovy code.

set_obj
<set var="number" object="otherNumber+50"/>

Here we are assuming that otherObject is a predefined numeric variable. When the SET is executed, the number variable will be an integer.

The second scenario is when you want to write extensive logic.

Choose the SET component, then choose the item “Language” in the type drop-down (when using Visual Composer), or enter lang=”java” when writing it in Code View.

setOr in code view:

<set var="myVar" lang="java">
<![CDATA[
def item = payload.whatever.items.find { it -> it.id==11 }
return item.amount
]]>
</set>

Templating

What about all the fields that are not explicitly evaluated? Like URL, value, or POST Body? Or the content of a comment? It is often extremely useful to evaluate content on those as well. This is possible using the template syntax.
eq

<assert-equals expression="payload.id" value="${req_id}"/>

This assertion, for example, is evaluating the req_id variable right within the value.

A Little Bit of Everything

Let’s join everything we’ve learned into one snippet:

<set var="data" lang="java">
<![CDATA[
  def items = payoad.whatever.items.find{ it-> it.id>100}
  return items.collect{ it -> it.providerId}
]]>
</set>
<each expression="data">
  <post url="http://www.example.com/${counter+1}" params="[:]" var="payload2" mode="json">
   <postBody contentType="application/json">
     <![CDATA[{"providerId":${_1}}]]>
   </postBody>
  </post>
  <set var="counter" object="counter+1"/>
</each>

Want to learn more about Groovy?

Follow this link to the official documentation:
http://groovy-lang.org/documentation.html

Important Note
For security concerns, the cloud version of API Fortress is sandboxed. Meaning many programming language features are disabled. On-premises eliminates that restraint. While on cloud, if you think a specific feature should be safe to be enabled but is disabled, please contact us and we’ll do our best to help you!

Backing up your data (on-premises only)

When running an on-premises installation, you will certainly want to run periodic backups of all your data.

In this article, we will provide you the scripts to perform a data dump of API Fortress. You will then need to wire them up in your scheduled operations system, such as cron.

We will assume you have a running API Fortress installation, ability to sudo to root privileges and a general idea of how Docker works.

Backup

1. In the host server, create a directory that will host your backup. In this example, it’s /var/local/backups but it can be anything. Make sure the directory has read/write permissions docker can use,

2. Run (change the directory according to your needs):

sudo docker run --rm --net apifortress --link core_apifortress-mongo_1:mongo.apifortress -v /var/local/backups:/backup mongo:3.0.14 bash -c 'mongodump --out /backup --host mongo.apifortress'
3. Run (change the directory according to your needs):
sudo docker run --rm --net apifortress --link core_apifortress-postgres_1:postgres.apifortress -v /var/local/backups:/backup postgres:9.5.5 bash -c 'pg_dump --dbname postgresql://apipulse:jk5112@postgres.apifortress:5432/apipulse > /backup/postgres.sql'
4. Access the /var/local/backups directory. You will find both an “apipulse” directory and a “postgres.sql” file. This is all your backup. You can now zip it and copy it wherever your backup procedures require. At this point we suggest you to clear the directory used for backup to have it empty for the next backup iteration.

Backup restore

1. in the core/ directory, stop all services by issuing:

sudo docker-compose stop

2. Remove all data files from your persistent volume on the host machine. EXTREME CAUTION: this will erase all your current data. Make sure that the backup you are going to restore is available. If unsure, just MOVE the current data to another location,

3. Activate MongoDB and PostgreSQL by issuing:

sudo docker-compose up -d apifortress-postgres
sudo docker-compose up -d apifortress-mongo

4. We will assume your backup is located in /var/local/backups. Run the following commands:

sudo docker run --rm --net apifortress --link core_apifortress-mongo_1:mongo.apifortress -v /var/local/backups:/backup mongo:3.0.14 bash -c 'mongorestore /backup --host mongo.apifortress'
sudo docker run --rm --net apifortress --link core_apifortress-postgres_1:postgres.apifortress -v /var/local/backups:/backup postgres:9.5.5 bash -c 'psql -h postgres.apifortress --dbname postgresql://apipulse:jk5112@postgres.apifortress:5432/apipulse  < /backup/postgres.sql'

5. Verify that files are now present in the persistent volume location of your host machine,

6. You can now start the platform by running the ./start_all.sh script.

Flexible variables for flexible environments

In API Fortress, almost any string can be hardcoded or referenced as a variable. Hardcoding is fine as long as you’re building simple tests, however, when:

  • The number of tests is increasing
  • The complexity of tests is increasing
  • The number of tested environments is increasing

it is advisable to parametrize some items.

Most of the parametrization you will likely be doing relates to the HTTP request itself.

Using the Vault

For example, while this is perfectly legit:

harcodedIt may become extremely painful to update tens if not hundreds of tests if the domain changes.

Using the vault to store domain names is a good way to solve this problem by simply adding a “domain” variable in your vault as in:

domainAnd editing the GET like this:

parametrizedIn this way, editing the vault variable will instantly affect all tests.

Using the environments

Once the domain is parametrized, no one stops you from overriding the variable, if needed.

By activating a preset in the environments section as in:

env2You will be able to hit a different domain in the current session, without actually changing the test.

The same selection can be performed while creating a schedule, to create specific runs hitting specific environments.

In request bodies

Variables are not only bound to URLs. Request bodies can also be handled like “templates” when needed, incorporating variables as in:

bodyAnd basically anywhere

Variables can be referenced basically anywhere, let’s take this assertion in consideration:

expYes, we’re using variables as expected values.

However…

The platform not only provides you the flexibility but also the freedom to basically combine everything as you want.
With that said, we would also provide you some hints on how to get the best from your experience.

  1. Fill the vault with data that is actually project-wise. Domains, protocols, API keys. They are all fine. We discourage you to introduce test specific variables in here because it would produce an overhead of information that will be unused most of the time,
  2. Fill the globals/input set with test specific variables. Such as paths, Ids, dates, serial numbers,
  3. Make sure that vault + globals/input set make up a complete variable scope for the test. In other words, the test should be able to run without further information,
  4. Use the environments to change the values of the variable scope generated by the vault+global/input sets,
  5. Don’t overdo. Parametrize stuff that can actually change and leave everything else as static strings. Variables are… well, variable, so an excessive and unnecessary use of variables leads to uncertainty and hard to track behaviors.

Environments, vault and overrides combinations

Overview

With the introduction of the “Environments” features, your ability to mix and match your tests settings increases drastically.

Let’s review what our variable containers are, moving from the lowest priority up.

Vault: each project has a vault where variables and snippets are contained. Each vault is global to the project and its variables are injected during test execution.

Globals / Input set: they belong to each test and contain the variables that are needed by the test to perform its duties. Since these variables can be overridden to hit different environments, we generally suggest considering these variables as containers of the default scenario. If the variable has been previously declared in the vault, globals/input sets will win over the Vault.

Overrides: when an overridden variable is declared (using the API, the Scheduler or the Jenkins plugin) its value will be injected in the test when it’s executed. If the variable has already been declared in the vault or the globals/input set, it will be rewritten with the new value.

Environments and presents: they are collections of overrides. You can save an environment with a name and reuse it when running a test.

SET commands: the last item of the chain, the SET commands within a test will introduce a runtime variable. If a variable with that name has already been declared, it will be overwritten.

Suggested Usage

Tests should be as self-contained as possible and should host as much information as possible to perform its operations, with the help of the Vault. In other words, Vault + Globals / Input set should always generate a complete variable scope. Therefore, running a test without any environment selection should at least lead to no syntax or runtime errors.

Environments and overrides should be used to change some of the values, or introduce contextual values, for:

  • hitting a staging server instead of the production one
  • run the test against a special product ID

Double evaluation

All variable containers have a “double evaluation” capability. Meaning that a variable declaration can actually reference another variable.
By doing so you can decide to concentrate the actual data in the variable container that best suits your approach, and then reference it.

In the following example, we are storing the actual domains in the Vault, deciding a default in the Globals, and overriding in the environment:

VAULT:
production_domain: example.com
staging_domain: staging_example.com

GLOBALS:
domain: ${production_domain}

ENVIRONMENTS Name: staging
domain: ${staging_domain}

If run without environment selection or overrides, the test will hit the production domain. If run with the staging environment, the test will hit the staging domain.
The Environments will not know the actual domain, therefore the actual data management will happen within the Vault.

Known Issue: the double evaluation will not work on query params. Workaround: in the test, before performing the call, introduce a SET component to resolve the variable, as in <set var=”apikey” value=”${apikey}”/>

Environments loading

If you’re using environments heavily, you will soon realize that the integration using the APIF API (and any CI/CD plugin) may become unfriendly, as lots of data will need to be copied around.

For this reason, we introduced a special override variable that will allow you to ask API Fortress to load a specific environment when invoking a test using the API.

the apif_env variable, passed as an override, will cause the system to load a specific environment.

Example:

apif_env: staging

Will load the “staging” environment and all its override variables.

Notes

As you get acquinted to the platform, you may be tempted to use all these features at once. While this makes us proud, we want to warn you from the overall complexity you may achieve, expecially when you’re double-referencing variables.
An extensive use of all these techniques altogether may increase the difficulty to debug a problem, when it arises, so use them with caution!

Environments and Presets

One of the key aspects of creating meaningful tests is being able to run them against different environments, to make sure that the upcoming release will pass the tests designed for the production release.

To do so, API Fortress introduced the “Environments” feature.

An “environment” is a collection of override variables. An override variable is a variable that will replace the value of a variable that has been hardcoded within the Vault or the test itself, during a predefined session.

You can access the feature in the “tests list” by clicking the “hamburger menu” icon:

hamOr in the composer, clicking on “environments”:

ham2

Simply overriding variables

In the override panel, you can type in which variables you want to override and activate the preset:

overBy doing so, you will be overriding the variables for the current session, as long as the preset is activated. This override will be performed to your session only.

Saving the environment

overOnce your preset is ready and you are willing to save it for later use, you can click on the “save” button and give it a name. The Preset will be associated with the current project and will be available to you and the other users.

Activating a saved environment

Once your environment is saved, you can activate it by choosing it from the “environments” dropdown that will show up by clicking on the arrow-down, to the right of the environments icon.

selIn this example, we named the environment “staging”.

To disable the environment and go back to defaults, just select “None”.

Using a saved environment via API

When using the API by invoking a test execution, you can have API Fortress load an environment based on its name.

To do so, just provide the special variable “apif_env” in the params section, and provide the name of the environment you want to load, as in:

{
  "Content-Type":"application/json",
  "payload":"{}",
  "params":{"apif_env":"staging"}
}

Using the API (For Continuous Deployment & More)

Here is a guide showing you various ways to call the API. This is particularly useful for those that want to use the platform to run tests during continuous deployments, and who are not using our Jenkins plugin.

First, you need to create the API Hook by going to the Company Settings page and clicking API Hooks section. To do this you need to be a Manager of the Company.

companySetting

Here, click +API Hook you will be prompted to choose a project. Once done, you will have the Hook URL that will give you the ability to query resources from that project. An example is
https://mastiff.apifortress.com/app/api/rest/v3/34d8mm70-c03e-267a-9fa1-90b9flsbcea2607
Note: That unique project hook is 34d8mm70-c03e-267a-9fa1-90b9flsbcea2607. This is useful for later.

A Quick Table of Contents:

Unauthenticated Endpoints

Test Run

Invoking the execution of a test via the API is a key feature of API Fortress. It allows you to trigger one, or multiple, tests to run. It can also receive input variables to override those in the tests themselves. Finally, you can also send a payload to the platform to be tested against.

Optionally, for all the endpoints you can add the following query parameters:

  • sync (boolean): the test will run synchronously and return the result as the response payload.
  • dryrun (boolean): the test will run but no events or metrics will be stored.
  • silent (boolean): no alerts will be triggered by the execution of the test.

Basic: Run a Test By Test ID

How to find a test ID.

GET https://mastiff.apifortress.com/app/api/rest/v3/project_hook/tests/test_id/run

Mock Example:

curl -v https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/34d8mm70-c03e-267a-9fa1-90b9flsbcea2607/tests/129d32j9dksdoo23e393/run

Advanced: Run a Test With Additional Information (Variable Override)

If you want to override variables, or include a payload, you have to use:

POST https://mastiff.apifortress.com/app/api/rest/v3/project_hook/tests/test_id/run

The request body will contain the variable you want to override.

Example body

{
  "payload": "{\"id\":\"123\"}",
  "Content-Type": "application/json",
  "params": {
    "server": "staging"
  }
}
  • Params will be accessible as variables inside the test.
  • Payload will be parsed based on the “Content-Type” field and will be accessible via the “payload” variable.

payload AND params are not required at the same time.

Mock Example:

curl -X POST \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/tests/35082607e4b0mm613lm82e8f/run \
-H 'content-type: application/json' \
-d '{
"payload": "{\"id\":\"123\"}",
"Content-Type": "application/json",
"params": {"server":"staging"}
}'

Automatch: Run Multiple Tests Based On a URL Pattern

Automatch is a way to simultaneously launch tests inside a project. The tests to run are selected by comparing the URL provided in the payload to the “automatch” configuration pattern in the tests. Just like the advanced run endpoint, you can override both variables and the payload:

POST https://mastiff.apifortress.com/app/api/rest/v3/project_hook/tests/automatch

Example body

{
  "payload": "{\"id\":\"123\"}",
  "Content-Type": "application/json",
  "params": {
    "server": "staging"
  },
  "url": "http://www.testme.com"
}

Mock Example:

curl -X POST \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/tests/automatch \
 -H 'content-type: application/json' \
 -d '{
 "payload": "{\"id\":\"123\"}",
 "Content-Type": "application/json",
 "params": {"server":"staging"}
}'

Basic Tags: Run Tests With Certain Tags

GET https://mastiff.apifortress.com/app/api/rest/v3/project_hook/tests/tag/tag/run

Mock Example:

curl -X GET \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/tests/tag/staging/run \
 -d '{
 "payload": "{\"id\":\"123\"}",
 "Content-Type": "application/json",
 "params": {"server":"staging"}
}'

Advanced Tags: Run Tests Tagged With a Certain Word

POST https://mastiff.apifortress.comapp/api/rest/v3/project_hook/tests/tag/tag/run

Example body

{
  "payload": "{\"id\":\"123\"}",
  "Content-Type": "application/json",
  "params": {
    "server": "staging"
  }
}

Mock Example:

curl -X POST \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/tests/tag/staging/run \
 -H 'content-type: application/json' \
 -d '{
 "payload": "{\"id\":\"123\"}",
 "Content-Type": "application/json",
 "params": {"server":"staging"}
}'

Basic By Project: Run all Published Tests of a Specific Project

GET https://mastiff.apifortress.com/app/api/rest/v3/project_hook/tests/run-all

Mock Example:

curl -X GET \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/tests/run-all \
 -d '{
 "payload": "{\"id\":\"123\"}",
 "Content-Type": "application/json",
 "params": {"server":"staging"}
}'

Advanced By Project: Run All Published Tests of a Project With Additional Information

POST https://mastiff.apifortress.com/app/api/rest/v3/project_hook/tests/run-all

Example body

{
  "payload": "{\"id\":\"123\"}",
  "Content-Type": "application/json",
  "params": {
    "server": "staging"
  }
}

Mock Example:

curl -X POST \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/tests/run-all \
 -H 'content-type: application/json' \
 -d '{
 "payload": "{\"id\":\"123\"}",
 "Content-Type": "application/json",
 "params": {"server":"staging"}
}'

Insights (Data & Information)

The API Fortress API also allows you to retrieve metrics and data of your tests.

Events: Shows Information About Test Failures and Successes

GET https://mastiff.apifortress.com/app/api/rest/v3/project_hook/insights/events

Mock Example:

curl -X GET \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/insights/events

Events Stream: Show Test Success and Failure Information As An Event Stream

GET https://mastiff.apifortress.com/app/api/rest/v3/project_hook/insights/events/stream

Mock Example:

curl -X GET \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/insights/events/stream

Metrics: Provide Details on Performance

GET https://mastiff.apifortress.com/app/api/rest/v3/project_hook/insights/metrics

Mock Example:

curl -X GET \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/insights/metrics

Metrics Stream: Provide Details on Performance in an Event Stream

GET https://mastiff.apifortress.com/app/api/rest/v3/project_hook/insights/metrics/stream

Mock Example:

curl -X GET \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/insights/metrics/stream

List of Tests in a Project

GET https://mastiff.apifortress.com/app/api/rest/v3/project_hook/tests

Mock Example:

curl -X GET \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/tests

Details of a Project

GET https://mastiff.apifortress.com/app/api/rest/v3/project_hook/

Mock Example:

curl -X GET \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/

Authenticated endpoints

The following endpoints might contain sensitive information, therefore authentication is required.

Authentication

GET https://mastiff.apifortress.com/app/api/rest/v3/project_hook/login

The user credentials, provided by basic HTTP authentication, need to match the user profile selected during the project hook creation. This endpoint will generate a JWT token which is valid only for the provided project hook. The token is necessary for all the endpoints containing potentially sensitive information, and updating data. The authentication is achieved by sending a valid access token in the request header, in the form Authorization: Bearer access_token

Mock Example:

curl -X GET \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/login \
 -H 'authorization: Basic ABCD' \
 -H 'content-type: application/json'

Insights (Data & Information)

Provide Details About a Specific Event

GET https://mastiff.apifortress.com/app/api/rest/v3/project_hook/insights/events/event_id
The event_id can be retrieved by performing the events endpoint first.

Mock Example:

curl -X GET \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/insights/events/5963451d12b87d3379d2f1co \
 -H 'autho: Bearer ABCD' \
 -H 'content-type: application/json'

Tests

Provide the Details About a Specific Test

GET https://mastiff.apifortress.com/api/rest/v3/project_hook/tests/test_id

The test_id can be retrieved by calling the test endpoint or, the easiest way, by copying it from the interstitial page:

testidIntersitialtestID

Mock Example:

curl -X GET \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/tests/35082607e4b0mm613lm82e8f \
 -H 'authorization: Bearer ABCD' \
 -H 'content-type: application/json'

Show the Content of the Unit for the Given Test

GET https://mastiff.apifortress.com/app/api/rest/v3/project_hook/tests/test_id/unit

Mock Example:

curl -X GET \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/tests/35082607e4b0mm613lm82e8f/unit \
 -H 'authorization: Bearer ABCD' \
 -H 'content-type: application/json'

Show the Content of the Unit for the Given Test as a Downloadable File

GET https://mastiff.apifortress.com/app/api/rest/v3/project_hook/tests/test_id/unit/file

Mock Example:

curl -X GET \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/tests/35082607e4b0mm613lm82e8f/unit/file \
 -H 'authorization: Bearer ABCD' \
 -H 'content-type: application/json'

Show the Content of the Input-Set for the Given Test

GET https://mastiff.apifortress.com/app/api/rest/v3/project_hook/tests/test_id/input

Mock Example:

curl -X GET \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/tests/35082607e4b0mm613lm82e8f/input \
 -H 'authorization: Bearer ABCD' \
 -H 'content-type: application/json'

Show the Content of the Input-Set for the Given Test as a Downloadable File

GET https://mastiff.apifortress.com/app/api/rest/v3/project_hook/tests/test_id/input/file

Mock Example:

curl -X GET \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/tests/35082607e4b0mm613lm82e8f/input/file \
 -H 'authorization: Bearer ABCD' \
 -H 'content-type: application/json'

Update Tests

Update the Unit of a Given Test

POST https://mastiff.apifortress.com/app/api/rest/v3/project_hook/tests/test_id/unit/update
The unit will be passed as body.

Example body:

{
  "text": "<unit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" name=\"main\" xsi:noNamespaceSchemaLocation=\"http://apifortress.com/app/unit.xsd\"><requirements></requirements><configs></configs><sequence name=\"main\"><assert-exists expression=\"payload\"/></sequence></unit>"
}

Mock Example:

curl -X POST \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/tests/35082607e4b0mm613lm82e8f/unit/update \
 -H 'authorization: Bearer ABCD' \
 -H 'content-type: application/json' \
 -d '{
 "text": "<unit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" name=\"main\" xsi:noNamespaceSchemaLocation=\"http://apifortress.com/app/unit.xsd\"><requirements></requirements><configs></configs><sequence name=\"main\"><assert-exists expression=\"payload\"/></sequence></unit>"
}'

Update the Unit of a Given Test by Accepting It As a Raw POST Body

POST https://mastiff.apifortress.com/app/api/rest/v3/project_hook/tests/test_id/unit/update/file
The unit will be passed as body.

Example body

<unit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="main" xsi:noNamespaceSchemaLocation="http://apifortress.com/app/unit.xsd">
    <requirements></requirements>
    <configs></configs>
    <sequence name="main">
        <get url="${protocol}${domain}${endpoint}" params="['id':id]" var="payload" mode="json"></get>
        <assert-equals expression="payload.status" value="200" comment="status is equal to 200, if not stop the test" stoponfail="true"/>
    </sequence>
</unit>

Mock Example:

curl -X POST \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/tests/35082607e4b0mm613lm82e8f/unit/update/file \
 -H 'authorization: Bearer ABCD' \
 -H 'content-type: text/xml' \
 -d '<unit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="main" xsi:noNamespaceSchemaLocation="http://apifortress.com/app/unit.xsd">
 <requirements></requirements>
 <configs></configs>
 <sequence name="main">
 <get url="${protocol}${domain}${endpoint}" params="['\''id'\'':id]" var="payload" mode="json"></get>
 <assert-equals expression="payload.status" value="200" comment="status is equal to 200, if not stop the test" stoponfail="true"/>
 </sequence>
</unit>'

Update the Input-Set of the Given Test

POST https://mastiff.apifortress.com/app/api/rest/v3/project_hook/tests/test_id/input/update
The input will be passed as body.

Example body

{
  "text": "<sets xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" name=\"main\" xsi:noNamespaceSchemaLocation=\"http://mastiff.apifortress.com/app/input.xsd\"><global><param name=\"country\">US</param></global><set name=\"search 1\"><param name=\"q\">music</param></set></sets>"
}

Mock Example:

curl -X POST \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/tests/35082607e4b0mm613lm82e8f/input/update \
 -H 'authorization: Bearer ABCD' \
 -H 'content-type: application/json' \
 -d '{
 "text": "<sets xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" name=\"main\" xsi:noNamespaceSchemaLocation=\"http://mastiff.apifortress.com/app/input.xsd\"><global><param name=\"country\">US</param></global><set name=\"search 1\"><param name=\"q\">music</param></set></sets>"
}'

Update the Input of a Given Test By Accepting It As a Raw Post Body

POST https://mastiff.apifortress.com/app/api/rest/v3/project_hook/tests/test_id/input/update/file
The input will be passed as body.

Example body

<sets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="main" xsi:noNamespaceSchemaLocation="http://mastiff.apifortress.com/app/input.xsd">
    <global>
        <param name="protocol">https://</param>
        <param name="domain">mastiff.apifortress.com</param>
        <param name="endpoint">/app/api/examples/retail/product</param>
    </global>
    <set name="ID 1">
        <param name="id">511</param>
    </set>
</sets>

Mock Example:

curl -X POST \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/6de267cd-df01-4782-8046-3seee6f4c093782/tests/35082607e4b0mm613lm82e8f/input/update/file \
 -H 'authorization: Bearer ABCD' \
 -H 'content-type: text/xml' \
 -d '<sets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="main" xsi:noNamespaceSchemaLocation="http://mastiff.apifortress.com/app/input.xsd">
 <global>
 <param name="protocol">https://</param>
 <param name="domain">mastiff.apifortress.com</param>
 <param name="endpoint">/app/api/examples/retail/product</param>
 </global>
 <set name="ID 1">
 <param name="id">511</param>
 </set>
</sets>'

Creating Tests Outside of API Fortress

Validators

When developing outside the API Fortress Composer, you will want to be sure the syntax of your units and input-sets are correct. For this work there are two different endpoints. One for the input-set, and one for the unit.

Validate the Unit

POST https://mastiff.apifortress.com/app/api/rest/v3/validators/unit
The unit will be passed as body.

Example Body

{
  "text": "<unit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" name=\"main\" xsi:noNamespaceSchemaLocation=\"http://apifortress.com/app/unit.xsd\"><requirements></requirements><configs></configs><sequence name=\"main\"><assert-exists expression=\"payload\"/></sequence></unit>"
}

Mock Example:

curl -X POST \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/validators/unit \
 -H 'content-type: application/json' \
 -d '{
 "text": "<unit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" name=\"main\" xsi:noNamespaceSchemaLocation=\"http://apifortress.com/app/unit.xsd\"><requirements></requirements><configs></configs><sequence name=\"main\"><assert-exists expression=\"payload\"/></sequence></unit>"
}'

Validate the Input-Set

POST https://mastiff.apifortress.com/app/api/rest/v3/validators/input
The input-set will be passed as body

Example Body:

{
  "text": "<sets xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" name=\"main\" xsi:noNamespaceSchemaLocation=\"http://mastiff.apifortress.com/app/input.xsd\"><global><param name=\"country\">US</param></global><set name=\"search 1\"><param name=\"q\">music</param></set></sets>"
}

Mock Example:

curl -X POST \
https://private-e9aac-apifortressv3.apiary-mock.com/app/api/rest/v3/validators/input \
 -H 'content-type: application/json' \
 -d '{
 "text": "<sets xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" name=\"main\" xsi:noNamespaceSchemaLocation=\"http://mastiff.apifortress.com/app/input.xsd\"><global><param name=\"country\">US</param></global><set name=\"search 1\"><param name=\"q\">music</param></set></sets>"
}'

 

 

Using the Jenkins Plugin

The API Fortress Jenkins Plugin allows you to run tests during automated builds. The tests that fail may, or may not, cause a build failure based on your settings.

Watch the walkthrough video.

Install the Jenkins plugin

From the Jenkins Update Center, search and install the API Fortress plugin.

jenkins1A Jenkins restart may be required. You will be prompted accordingly.

Configure a build step

Add the API Fortress build step where it best suits your needs.

jenkins2

Modes

There are 4 testing modes available. “Run single test” will run a single test, while the others will run suites of tests.

Run Single Test

You can run a single test by providing a test ID. Test IDs can be found in test interstitial pages.

See where to retrieve the test IDs later in this document.

Run Automatch

You can run our “automatch” mode by providing a URL representing a certain endpoint. You can configure automatch patterns in the “Automatch” section of each test. Read more about automatch here .

Run by Tag

Choosing “by tag” will run multiple tests marked with a certain tag. Tags can be added and edited in the test details.

Run Project

By running a full project, you will be running all tests contained in the project.

Hook URL

The hook URL is an API endpoint that references a specific project within an API Fortress environment.

See the Hook URLs section to create one.

Options

The following options can apply to any mode.

Blocking

The plugin can silently run (blocking = false), which lets the build continue with a success and inform you if the test failed using the various methods available. Or it can actively determine the build success (blocking=true), so that the build will wait for the tests result and stop the build if the tests fail.

Dry-run

If checked, no events will be stored within API Fortress. To be used in conjunction with “blocking.”

Silent

If checked, no alerts will be sent if the tests fail.

Parameters Override

You can override up to 3 parameters in the test scope. These variables will appear within the test scope just like any other variable. Useful if you are looking to override the domain of the service being tested (ie. staging vs production).

Hook URLs

Hook URLs are API endpoints representing one of your projects. These endpoints have unique paths, and do not require authentication for most non-disclosing operations.

To create a Hook URL:

  1. Access your API Fortress dashboard.
  2. Enter the company configuration screen (gear icon in the top right).
  3. Choose API Hooks on the side menu.
  4. Create a new Hook by choosing the user (necessary for advanced functions) and the project.
  5. A unique URL will be generated. That is the URL to be used in your build step configuration.

Test IDs and Project ID

To retrieve a specific test ID from the API Fortress dashboard:

  1. Access the tests list for the project you intend to use.
  2. Edit one of tests and access the interstitial page.
  3. Click on “show/hide test information.”
    jenkins4
  4. The test ID and the Project ID are shown here.

Input set and global variables

In the test creation process, the definition of global and local variables allows you to parametrize the test to allow more flexibility.

The global variables are meant to be the ones that are common for the whole test (i.e. api key, domain etc). For adding a global variable click on the +Add Global Param in the Data Set panel and fill the name and value.

variable

globalThe variable will be present in the test scope, and will be constant during the test exeuction.

The input set, instead, is a group of input variables representing a scenario (i.e product id). To add in input set, click the + button in the Input Set section and add a name for the set. Then click + Add Param and add the variable name and value.

inputSet

The unit will be executed once for each input set you have defined. At each iteration, one input set will enter the scope.

If you define a variable both in the global section and the input set, the value used in the test will be the one defined in the input set.

The variables can be defined also in the Vault (for more info see here) and in the Schedule (for more info see here).

The priority order is:

  • if the same variable is defined in the Vault and in the composer (no matter if it is a global variable or an input set), the one defined in the composer will be used.
  • if the same variable is defined in the composer both as global and input set, the value of the input set will be used
  • if the same variable is defined in the Vault (or in the composer) and in the scheduler, the variable defined in the scheduler will be used for the tests.

Proof of Concept Time – Get Excited!

Welcome to your API Fortress trial!

You should have received an email with your login credentials from the platform. If you haven’t please email API Fortress.

The links below are resources that will easily get you started with standing up your APIs. If additional resources are required please do not hesitate to reach out. Our lines of communications are always open to support you throughout this process.

Keys to a Successful Evaluation

Phase 1:

Phase 2:

Phase 3:

More Docs

Videos
More Videos

Example public APIs to play with:
Retail API
Uber API

Please let us know if there is anything else we can do to help with the evaluation process.