Add GitLab CI/CD tutorial.
BIN
docs/assets/img/github-action-dark.avif
Normal file
BIN
docs/assets/img/github-action-dark.webp
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
docs/assets/img/github-action-light.avif
Normal file
BIN
docs/assets/img/github-action-light.webp
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
docs/assets/img/github-new-repository-dark.avif
Normal file
BIN
docs/assets/img/github-new-repository-dark.webp
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
docs/assets/img/github-new-repository-light.avif
Normal file
BIN
docs/assets/img/github-new-repository-light.webp
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
docs/assets/img/gitlab-new-repository-dark.avif
Normal file
BIN
docs/assets/img/gitlab-new-repository-dark.png
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
docs/assets/img/gitlab-new-repository-dark.webp
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
docs/assets/img/gitlab-new-repository-light.avif
Normal file
BIN
docs/assets/img/gitlab-new-repository-light.png
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
docs/assets/img/gitlab-new-repository-light.webp
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
docs/assets/img/gitlab-pipeline-dark.avif
Normal file
BIN
docs/assets/img/gitlab-pipeline-dark.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
docs/assets/img/gitlab-pipeline-dark.webp
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
docs/assets/img/gitlab-pipeline-light.avif
Normal file
BIN
docs/assets/img/gitlab-pipeline-light.png
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
docs/assets/img/gitlab-pipeline-light.webp
Normal file
After Width: | Height: | Size: 36 KiB |
@ -1,9 +1,8 @@
|
|||||||
# CI/CD Integration
|
# CI/CD Integration
|
||||||
|
|
||||||
Up until now, we have run our test files locally. Now, we want to integrate
|
Up until now, we have run our test files locally. Now, we want to integrate them in a CI/CD pipeline
|
||||||
them in a CI/CD pipeline (like [GitHub Actions] or [GitLab CI/CD pipelines]). As
|
(like [GitHub Actions] or [GitLab CI/CD pipelines]). As Hurl is very fast, we're going to run our tests on each commit
|
||||||
Hurl is very fast, we're going to run our tests on each commit of our project,
|
of our project, drastically improving the project quality.
|
||||||
drastically improving the project quality.
|
|
||||||
|
|
||||||
A typical web project pipeline is:
|
A typical web project pipeline is:
|
||||||
|
|
||||||
@ -11,23 +10,74 @@ A typical web project pipeline is:
|
|||||||
- publish the application image to a Docker registry,
|
- publish the application image to a Docker registry,
|
||||||
- pull the application image and run integration tests.
|
- pull the application image and run integration tests.
|
||||||
|
|
||||||
In this workflow, we're testing the same image that will be used and deployed in
|
In this workflow, we're testing the same image that will be used and deployed in production.
|
||||||
production.
|
|
||||||
|
|
||||||
> For the tutorial, we are skipping build and publication phases and
|
> For the tutorial, we are skipping build and publication phases and
|
||||||
> only run integration tests on a prebuilt Docker image. To check a complete
|
> only run integration tests on a prebuilt Docker image. To check a complete
|
||||||
> project with build, Docker upload/publish and integration tests, go to <https://github.com/jcamiel/hurl-express-tutorial>
|
> project with build, Docker upload/publish and integration tests, go to <https://github.com/jcamiel/hurl-express-tutorial>
|
||||||
|
|
||||||
In a first step, we're going to write a bash script that will pull our Docker
|
In a first step, we're going to write a shell script that will pull our Docker image, launch it and run Hurl tests
|
||||||
image, launch it and run Hurl tests against it. Once we have checked that this
|
against it. Once we have checked that this script runs locally, we'll see how to run it automatically in a CI/CD
|
||||||
script runs locally, we'll see how to run it automatically in a CI/CD pipeline.
|
pipeline.
|
||||||
|
|
||||||
|
|
||||||
|
## Templating Tests
|
||||||
|
|
||||||
|
Before writing our test script, we're going to template our Hurl files so we can run them more easily in various
|
||||||
|
configuration. One way to do this is to use [variables]. We've already seen variables when [chaining requests],
|
||||||
|
we're going to see how we can use them to inject data.
|
||||||
|
|
||||||
|
In the file `basic.hurl`, we first test the home page:
|
||||||
|
|
||||||
|
```hurl
|
||||||
|
# Checking our home page:
|
||||||
|
GET http://localhost:3000
|
||||||
|
|
||||||
|
# ...
|
||||||
|
```
|
||||||
|
|
||||||
|
We've hardcoded our server's URL but what if we need to run the same test on another URL (against production
|
||||||
|
URL with HTTPS for example)? We can use a variable like this:
|
||||||
|
|
||||||
|
```hurl
|
||||||
|
# Checking our home page:
|
||||||
|
GET {{host}}
|
||||||
|
|
||||||
|
# ...
|
||||||
|
```
|
||||||
|
|
||||||
|
And run our file with [`--variable`] option:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ hurl --variable host=http://localhost:3000 --test basic.hurl
|
||||||
|
```
|
||||||
|
|
||||||
|
This way, our host is not hardcoded any more and we can run our tests in various configurations.
|
||||||
|
|
||||||
|
1. Replace `http://localhost:3000` by `{{host}}` in `basic.hurl`, `login.hurl` and `signup.hurl` and test that everything is ok
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ hurl --variable host=http://localhost:3000 --test *.hurl
|
||||||
|
Running Hurl tests
|
||||||
|
[1mintegration/basic.hurl[0m: [1;36mRunning[0m [1/2]
|
||||||
|
[1mintegration/basic.hurl[0m: [1;32mSuccess[0m (4 request(s) in 18 ms)
|
||||||
|
[1mintegration/login.hurl[0m: [1;36mRunning[0m [2/2]
|
||||||
|
[1mintegration/login.hurl[0m: [1;32mSuccess[0m (6 request(s) in 18 ms)
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
Executed files: 2
|
||||||
|
Succeeded files: 2 (100.0%)
|
||||||
|
Failed files: 0 (0.0%)
|
||||||
|
Duration: 48 ms
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, we're ready to write our integration script.
|
||||||
|
|
||||||
## Integration Script
|
## Integration Script
|
||||||
|
|
||||||
1. First, create a directory name `movies-project`, add [`integration/basic.hurl`]
|
1. First, create a directory name `movies-project`, add [`integration/basic.hurl`]
|
||||||
and [`integration/create-quiz.hurl`] from the previous tutorial to the directory.
|
and [`integration/create-quiz.hurl`] from the previous tutorial to the directory.
|
||||||
|
|
||||||
<pre><code class="language-shell">$ mkdir movies-project
|
<pre><code class="language-shell"><!-- no-escape -->$ mkdir movies-project
|
||||||
$ cd movies-project
|
$ cd movies-project
|
||||||
$ mkdir integration
|
$ mkdir integration
|
||||||
$ vi integration/basic.hurl
|
$ vi integration/basic.hurl
|
||||||
@ -36,15 +86,19 @@ $ vi integration/basic.hurl
|
|||||||
|
|
||||||
$ vi integration/login.hurl
|
$ vi integration/login.hurl
|
||||||
|
|
||||||
# Import <a href="https://github.com/jcamiel/hurl-express-tutorial/raw/main/integration/login.hurl">login.hurl</a> here!</code></pre>
|
# Import <a href="https://github.com/jcamiel/hurl-express-tutorial/raw/main/integration/login.hurl">login.hurl</a> here!
|
||||||
|
|
||||||
|
$ vi integration/signup.hurl
|
||||||
|
|
||||||
|
# Import <a href="https://github.com/jcamiel/hurl-express-tutorial/raw/main/integration/signup.hurl">signup.hurl</a> here!</code></pre>
|
||||||
|
|
||||||
Next, we are going to write the first version of our integration script that will
|
Next, we are going to write the first version of our integration script that will
|
||||||
just pull the Quiz image and run it:
|
just pull the Quiz image and run it. This script will our server URl as argument
|
||||||
|
|
||||||
2. Create a script named `bin/integration.sh` with the following content:
|
2. Create a script named `bin/integration.sh` with the following content:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
echo "Starting container"
|
echo "Starting container"
|
||||||
@ -55,7 +109,7 @@ docker run --name movies --rm --detach --publish 3000:3000 ghcr.io/jcamiel/hurl-
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ chmod u+x bin/integration.sh
|
$ chmod u+x bin/integration.sh
|
||||||
$ bin/integration.sh
|
$ bin/integration.sh http://localhost:3000
|
||||||
Starting container
|
Starting container
|
||||||
5d311561828d6078e84eb4b8b87dfd5d67bde6d9614ad83860b60cf310438d2a
|
5d311561828d6078e84eb4b8b87dfd5d67bde6d9614ad83860b60cf310438d2a
|
||||||
```
|
```
|
||||||
@ -70,9 +124,8 @@ $ docker stop movies
|
|||||||
movies
|
movies
|
||||||
```
|
```
|
||||||
|
|
||||||
Now, we have a basic script that starts our container. Before adding our
|
Now, we have a basic script that starts our container. Before adding our integration tests, we need to ensure that our
|
||||||
integration tests, we need to ensure that our application server is ready: the
|
application server is ready: the container has started, but the application server can take a few seconds to be
|
||||||
container has started, but the application server can take a few seconds to be
|
|
||||||
really ready to accept incoming HTTP requests.
|
really ready to accept incoming HTTP requests.
|
||||||
|
|
||||||
To do so, we can test our health API. With a function `wait_for_url`,
|
To do so, we can test our health API. With a function `wait_for_url`,
|
||||||
@ -82,12 +135,12 @@ until the check succeeds with [`--retry`] Hurl option. Once the test has succeed
|
|||||||
5. Modify `bin/integration.sh` to wait for the application to be ready:
|
5. Modify `bin/integration.sh` to wait for the application to be ready:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
wait_for_url () {
|
wait_for_url () {
|
||||||
echo "Testing $1..."
|
echo "Testing $1..."
|
||||||
echo -e "GET $1\nHTTP 200" | hurl --retry "$2" > /dev/null;
|
printf 'GET %s\nHTTP 200' "$1" | hurl --retry "$2" > /dev/null;
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,21 +148,20 @@ echo "Starting container"
|
|||||||
docker run --name movies --rm --detach --publish 3000:3000 ghcr.io/jcamiel/hurl-express-tutorial:latest
|
docker run --name movies --rm --detach --publish 3000:3000 ghcr.io/jcamiel/hurl-express-tutorial:latest
|
||||||
|
|
||||||
echo "Waiting server to be ready"
|
echo "Waiting server to be ready"
|
||||||
wait_for_url 'http://localhost:3000' 60
|
wait_for_url "$1" 60
|
||||||
|
|
||||||
echo "Stopping container"
|
echo "Stopping container"
|
||||||
docker stop movies
|
docker stop movies
|
||||||
```
|
```
|
||||||
|
|
||||||
We have now the simplest integration test script: it pulls our Docker image, then starts
|
We have now the simplest integration test script: it pulls our Docker image, then starts the container and waits for a `200 OK` response.
|
||||||
the container and waits for a `200 OK` response.
|
|
||||||
|
|
||||||
Next, we're going to add our Hurl tests to the script.
|
Next, we're going to add our Hurl tests to the script.
|
||||||
|
|
||||||
6. Modify `bin/integration.sh` to add integration tests:
|
6. Modify `bin/integration.sh` to add integration tests:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
# ...
|
# ...
|
||||||
@ -121,7 +173,7 @@ echo "Waiting server to be ready"
|
|||||||
# ...
|
# ...
|
||||||
|
|
||||||
echo "Running Hurl tests"
|
echo "Running Hurl tests"
|
||||||
hurl --test integration/*.hurl
|
hurl --variable host="$1" --test integration/*.hurl
|
||||||
|
|
||||||
echo "Stopping container"
|
echo "Stopping container"
|
||||||
# ...
|
# ...
|
||||||
@ -130,7 +182,7 @@ echo "Stopping container"
|
|||||||
7. Run [`bin/integration.sh`] to check that our application passes all tests:
|
7. Run [`bin/integration.sh`] to check that our application passes all tests:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ bin/integration.sh
|
$ bin/integration.sh http://localhost:3000
|
||||||
Starting container
|
Starting container
|
||||||
48cf21d193a01651fc42b80648abdb51dc626f31c3f9c8917aea899c68eb4a12
|
48cf21d193a01651fc42b80648abdb51dc626f31c3f9c8917aea899c68eb4a12
|
||||||
Waiting server to be ready
|
Waiting server to be ready
|
||||||
@ -160,8 +212,18 @@ to create a [GitHub Action]. You can also see how to integrate your tests in [Gi
|
|||||||
1. Create a new empty repository in GitHub, named `movies-project`:
|
1. Create a new empty repository in GitHub, named `movies-project`:
|
||||||
|
|
||||||
<div class="picture">
|
<div class="picture">
|
||||||
|
<picture>
|
||||||
|
<source srcset="/docs/assets/img/github-new-repository-light.avif" type="image/avif">
|
||||||
|
<source srcset="/docs/assets/img/github-new-repository-light.webp" type="image/webp">
|
||||||
|
<source srcset="/docs/assets/img/github-new-repository-light.png" type="image/png">
|
||||||
<img class="light-img u-drop-shadow u-border u-max-width-100" src="/docs/assets/img/github-new-repository-light.png" width="680" alt="Create new GitHub repository"/>
|
<img class="light-img u-drop-shadow u-border u-max-width-100" src="/docs/assets/img/github-new-repository-light.png" width="680" alt="Create new GitHub repository"/>
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source srcset="/docs/assets/img/github-new-repository-dark.avif" type="image/avif">
|
||||||
|
<source srcset="/docs/assets/img/github-new-repository-dark.webp" type="image/webp">
|
||||||
|
<source srcset="/docs/assets/img/github-new-repository-dark.png" type="image/png">
|
||||||
<img class="dark-img u-drop-shadow u-border u-max-width-100" src="/docs/assets/img/github-new-repository-dark.png" width="680" alt="Create new GitHub repository"/>
|
<img class="dark-img u-drop-shadow u-border u-max-width-100" src="/docs/assets/img/github-new-repository-dark.png" width="680" alt="Create new GitHub repository"/>
|
||||||
|
</picture>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@ -178,7 +240,7 @@ $ git commit -m "Add integration tests."
|
|||||||
create mode 100755 bin/integration.sh
|
create mode 100755 bin/integration.sh
|
||||||
...
|
...
|
||||||
$ git remote add origin https://github.com/jcamiel/movies-project.git
|
$ git remote add origin https://github.com/jcamiel/movies-project.git
|
||||||
$ git push -u origin main
|
$ git push --set-upstream origin main
|
||||||
Enumerating objects: 7, done.
|
Enumerating objects: 7, done.
|
||||||
Counting objects: 100% (7/7), done.
|
Counting objects: 100% (7/7), done.
|
||||||
...
|
...
|
||||||
@ -211,7 +273,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
curl --location --remote-name https://github.com/Orange-OpenSource/hurl/releases/download/4.0.0/hurl_4.0.0_amd64.deb
|
curl --location --remote-name https://github.com/Orange-OpenSource/hurl/releases/download/4.0.0/hurl_4.0.0_amd64.deb
|
||||||
sudo dpkg -i hurl_4.0.0_amd64.deb
|
sudo dpkg -i hurl_4.0.0_amd64.deb
|
||||||
bin/integration.sh
|
bin/integration.sh http://localhost:3000
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Commit and push the new action:
|
4. Commit and push the new action:
|
||||||
@ -231,13 +293,113 @@ Counting objects: 100% (6/6), done.
|
|||||||
Finally, you can check on GitHub that our action is running:
|
Finally, you can check on GitHub that our action is running:
|
||||||
|
|
||||||
<div class="picture">
|
<div class="picture">
|
||||||
<img class="light-img u-drop-shadow u-border u-max-width-100" src="/docs/assets/img/github-action-light.png" width="752" alt="GitHub Action"/>
|
<picture>
|
||||||
<img class="dark-img u-drop-shadow u-border u-max-width-100" src="/docs/assets/img/github-action-dark.png" width="752" alt="GitHub Action"/>
|
<source srcset="/docs/assets/img/github-action-light.avif" type="image/avif">
|
||||||
|
<source srcset="/docs/assets/img/github-action-light.webp" type="image/webp">
|
||||||
|
<source srcset="/docs/assets/img/github-action-light.png" type="image/png">
|
||||||
|
<img class="light-img u-drop-shadow u-border u-max-width-100" src="/docs/assets/img/github-action-light.png" width="680" alt="GitHub Action"/>
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source srcset="/docs/assets/img/github-action-dark.avif" type="image/avif">
|
||||||
|
<source srcset="/docs/assets/img/github-action-dark.webp" type="image/webp">
|
||||||
|
<source srcset="/docs/assets/img/github-action-dark.png" type="image/png">
|
||||||
|
<img class="dark-img u-drop-shadow u-border u-max-width-100" src="/docs/assets/img/github-action-dark.png" width="680" alt="GitHub Action"/>
|
||||||
|
</picture>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Running Tests with GitLab CI/CD
|
## Running Tests with GitLab CI/CD
|
||||||
|
|
||||||
If you use [GitLab CI/CD], you can check [this detailed tutorial] on how to continuously run your Hurl test suite.
|
1. Create a new empty repository in GitLab, named `movies-project`:
|
||||||
|
|
||||||
|
<div class="picture">
|
||||||
|
<picture>
|
||||||
|
<source srcset="/docs/assets/img/gitlab-new-repository-light.avif" type="image/avif">
|
||||||
|
<source srcset="/docs/assets/img/gitlab-new-repository-light.webp" type="image/webp">
|
||||||
|
<source srcset="/docs/assets/img/gitlab-new-repository-light.png" type="image/png">
|
||||||
|
<img class="light-img u-drop-shadow u-border u-max-width-100" src="/docs/assets/img/gitlab-new-repository-light.png" width="680" alt="Create new GitLab repository"/>
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source srcset="/docs/assets/img/gitlab-new-repository-dark.avif" type="image/avif">
|
||||||
|
<source srcset="/docs/assets/img/gitlab-new-repository-dark.webp" type="image/webp">
|
||||||
|
<source srcset="/docs/assets/img/gitlab-new-repository-dark.png" type="image/png">
|
||||||
|
<img class="dark-img u-drop-shadow u-border u-max-width-100" src="/docs/assets/img/gitlab-new-repository-dark.png" width="680" alt="Create new GitLab repository"/>
|
||||||
|
</picture>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
2. On your computer, create a git repo in `movies-project` directory and
|
||||||
|
commit the projects files:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ git init
|
||||||
|
Initialized empty Git repository in /Users/jc/Documents/Dev/movies-project/.git/
|
||||||
|
$ git add .
|
||||||
|
$ git commit -m "Add integration tests."
|
||||||
|
[master (root-commit) ea3e5cd] Add integration tests.
|
||||||
|
3 files changed, 146 insertions(+)
|
||||||
|
create mode 100755 bin/integration.sh
|
||||||
|
...
|
||||||
|
$ git remote add origin git@gitlab.com:jcamiel/movies-project.git
|
||||||
|
$ git push --set-upstream origin main
|
||||||
|
Enumerating objects: 7, done.
|
||||||
|
Counting objects: 100% (7/7), done.
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
Next, we are going to add a GitLab CI/CD pipeline. The purpose of this pipeline will be to launch our integration
|
||||||
|
script on each commit. We'll base our image on a Docker based image, with a [Docker-In-Docker service].
|
||||||
|
|
||||||
|
3. Create a file `.gitlab-ci.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
image: docker:24
|
||||||
|
|
||||||
|
build:
|
||||||
|
stage: build
|
||||||
|
services:
|
||||||
|
- docker:24-dind
|
||||||
|
before_script:
|
||||||
|
# Add Hurl on Alpine (testing channel)
|
||||||
|
- apk add --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/testing hurl
|
||||||
|
script:
|
||||||
|
- bin/integration.sh http://docker:3000
|
||||||
|
```
|
||||||
|
|
||||||
|
> Because of Docker-In-Docker, our server is accessible with the `docker` hostname (and not `localhost`). As we have
|
||||||
|
> made our script configurable, we can just pass the hostname and don't modify our integration script
|
||||||
|
|
||||||
|
|
||||||
|
4. Commit and push the new action:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ git add .gitlab-ci.yml
|
||||||
|
$ git commit -m "Add GitLab CI/CD pipeline."
|
||||||
|
[main 11c4e7e] Add GitLab CI/CD pipeline.
|
||||||
|
1 file changed, 13 insertions(+)
|
||||||
|
create mode 100644 .gitlab-ci.yml
|
||||||
|
$ git push
|
||||||
|
Enumerating objects: 6, done.
|
||||||
|
Counting objects: 100% (6/6), done.
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, you can check on GitLab that our pipeline is running:
|
||||||
|
|
||||||
|
<div class="picture">
|
||||||
|
<picture>
|
||||||
|
<source srcset="/docs/assets/img/gitlab-pipeline-light.avif" type="image/avif">
|
||||||
|
<source srcset="/docs/assets/img/gitlab-pipeline-light.webp" type="image/webp">
|
||||||
|
<source srcset="/docs/assets/img/gitlab-pipeline-light.png" type="image/png">
|
||||||
|
<img class="light-img u-drop-shadow u-border u-max-width-100" src="/docs/assets/img/gitlab-pipeline-light.png" width="680" alt="GitHub Action"/>
|
||||||
|
</picture>
|
||||||
|
<picture>
|
||||||
|
<source srcset="/docs/assets/img/gitlab-pipeline-dark.avif" type="image/avif">
|
||||||
|
<source srcset="/docs/assets/img/gitlab-pipeline-dark.webp" type="image/webp">
|
||||||
|
<source srcset="/docs/assets/img/gitlab-pipeline-dark.png" type="image/png">
|
||||||
|
<img class="dark-img u-drop-shadow u-border u-max-width-100" src="/docs/assets/img/gitlab-pipeline-dark.png" width="680" alt="GitHub Action"/>
|
||||||
|
</picture>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
For a more complete [GitLab CI/CD] example, you can check [this detailed tutorial] on how to continuously run your Hurl test suite.
|
||||||
|
|
||||||
|
|
||||||
## Tests Report
|
## Tests Report
|
||||||
@ -259,3 +421,7 @@ Now, we can add more Hurl tests and start developing new features with confidenc
|
|||||||
[GitLab CI/CD]: https://about.gitlab.com/why-gitlab/
|
[GitLab CI/CD]: https://about.gitlab.com/why-gitlab/
|
||||||
[this detailed tutorial]: https://about.gitlab.com/blog/2022/12/14/how-to-continously-test-web-apps-apis-with-hurl-and-gitlab-ci-cd/
|
[this detailed tutorial]: https://about.gitlab.com/blog/2022/12/14/how-to-continously-test-web-apps-apis-with-hurl-and-gitlab-ci-cd/
|
||||||
[`--retry`]: /docs/manual.md#retry
|
[`--retry`]: /docs/manual.md#retry
|
||||||
|
[variables]: /docs/templates.md#variables
|
||||||
|
[chaining requests]: /docs/tutorial/chaining-requests.md
|
||||||
|
[Docker-In-Docker service]: https://docs.gitlab.com/ee/ci/docker/
|
||||||
|
[`--variable`]: /docs/manual.md#variable
|
||||||
|