GUI-based API clients such as Postman and Insomnia have risen in popularity over time. Despite this, various annual developer surveys show that a large percentage of developers, QA and automation engineers, and API testers still resort to using the command line when testing their APIs.
If you’re a developer who prefers interacting with APIs through the command line, Hurl is an excellent Postman alternative that improves the DX of working with APIs through the command line. In this article, we’ll go through an in-depth explanation of the Hurl tool, its unique benefits, and how to use it.
Hurl is a command-line tool that enables developers to run and test HTTP requests directly from their command line. Its CLI-based approach offers a lightweight alternative to GUI-based tools like Postman. Hurl supports APIs implemented using various protocols such as REST, GraphQL, and SOAP.
Under the hood, Hurl utilizes the legendary cURL CLI tool for HTTP transfers. As a result, it shares various similarities with cURL, including deriving its name from cURL and supporting cURL options.
Hurl supports a wide variety of operating systems including Windows, Linux, and MacOS. As a CLI tool, Hurl is also available for use within Continuous Integration (CI) pipelines.
Any HTTP requests you want Hurl to execute are stored in files with the .hurl
extension. Each request URL within a Hurl file is referred to as an entry. Every entry has at least the request method and the URL.
Hurl supports having multiple request entries within a single file and will execute them sequentially when the file is run. Also, Hurl supports matching multiple .hurl
files for execution using regular expressions. You’ll see the benefit of matching multiple files during the code demos later.
A basic Hurl file contains at least a single URL entry, which you want Hurl to validate against as shown in the next code block. When executed, Hurl will make a GET request to the Rick and Morty API to fetch all the characters and print them out:
GET https://rickandmortyapi.com/api
Executing the command above should result in an API response like the following:
Hurl outputs the API response by default. Considering that, you can manipulate the API response in many ways, such as redirecting it to another tool like jq to prettify the JSON result.
If you have jq
installed, executing the next command will use the shell pipe operator |
to pass the response body output from Hurl to jq
for better formatting:
hurl characters.hurl | jq
As you can see below, the data is formatted in a much more readable way than the output we saw before:
As your testing requirements increase, Hurl gives you the ability to expand your Hurl file to test multiple URLs and validate their responses, status codes, and even headers.
Unlike other API clients such as Postman, Hurl is completely open source, free to use, and community-driven. It leverages cURL to improve the experience of working with APIs from the terminal using a plain text syntax and it gives developers a lot of flexibility to tweak and customize their API requests.
Hurl offers a very lightweight, portable, and easy-to-install tool that you can use in development environments where the system or storage resources are limited such as cloud-based virtual environments or server workstations.
Testing your API through a CLI tool presents an opportunity for you to automate the steps and avoid repetitive work whenever you make changes to your API. Hurl provides support for GitHub Actions and BitBucket, enabling developers to include executing their Hurl tests in their CI/CD pipelines.
If you’re deciding whether to use a GUI-based API client like Postman or a command-line tool like Hurl, the following high-level comparison table may help aid your choice:
Hurl | Postman | |
---|---|---|
Pricing | Hurl is a free, open source software with no pricing tier to restrict certain features. | Postman is a paid software and not open source. It however has other free open source tools such as the Newman CLI, and Code Generators. |
Usage | Hurl is fully command-line based with no support for testing APIs through a web browser or desktop application. | Postman provides a web browser and desktop application client for API testing. The Newman CLI from Postman supports API testing through the command line. |
Learning curve | Hurl has a steep learning curve for non-technical users as you need to learn its concepts and syntax. | Postman is better suited for non-technical users as the GUI makes testing APIs easier. |
Complexity | Hurl is less complex to begin using as it does not have an onboarding process. | Postman is often quite complex to get up and running as it prompts you to create an account, create a workspace for the project, and also configure the CLI when used within CI/CD workflows. |
Data privacy | Hurl does not collect or store user or team information. The additional details for your API are stored within the project as environment variables in key-value pairs format. | Postman collects user data and persists your testing preferences, binary files, and environment variables outside your project |
At this point, you now know what the Hurl tool is and the benefits it offers to developers who love performing API tests through their CLI. We’ve also discussed some of the drawbacks you should be aware of before diving into Hurl, such as its learning curve — especially for beginners.
If you’re willing to put in some time and effort to get familiar with Hurl, it could be a great and powerful tool in your developer toolbox. Let’s proceed to use Hurl in a demo project.
Let’s see Hurl’s benefits in action by using it to test the public Rick and Morty API service. We’ll test the REST and GraphQL endpoints from the Rick and Morty service, alongside the frontend website elements that display all RickandMorty characters and episodes.
Hurl provides various functions for developers to perform implicit and explicit assertions on their API responses.
For APIs returning data in JSON format, the JSONPath assert allows developers to traverse through a response object and check its values. On the other hand, developers testing services returning data in XML format are to make use of the XPath assert.
Execute the following command to create a folder named RickAndMortyHurl
:
mkdir RickAndMortyHurl
You can also manually create the folder with your preferred name on your computer. The folder will store the Hurl files for testing the Rick and Morty API.
Create your first Hurl file with the name characters.hurl
within the project folder and add the content of the next code block into it to expand the first RickAndMorty example:
GET https://rickandmortyapi.com/api/character HTTP 200 [Asserts] jsonpath "$.info.count" exists jsonpath "$.info.pages" exists jsonpath "$.results" exists jsonpath "$.results" count >= 20
The code above directs Hurl to make a GET request to the /character
endpoint of the Rick and Morty API and expect only a 200 response status code. The code also contains an Asserts
block, which explicitly uses the jsonpath
assert to check if certain properties exist in the info object, as well as whether the objects in the results
array are equal to or greater than 20.
Hurl gives you the ability to customize its execution output by applying its debug options to run the command. In this scenario, you should know more about the execution rather than the API response. Hence, you can apply the verbose
and no-output
debug options to the command.
Execute the following to run the characters.hurl
file in a verbose mode without printing the JSON response from the Rick and Morty API:
hurl --verbose --test characters.hurl
As shown in the following image, Hurl outputs more details in the verbose mode about the API request being made rather than the API response body:
If any of the asserts fail, Hurl will print out the exact failing line with the received and expected values for its stack trace and pause the execution of the file.
To test, change any of the predicate values within the characters.hurl
file and run the file again.
The following image shows the Hurl stack trace when the expected count value of the objects within the results array is greater than the actual value obtained after the API request:
Similar to creating Hurl asserts using the jsonpath for JSON data, Hurl also provides you with XPath for capturing data from XML responses.
Before you begin writing the tests, open the Rick and Morty website to view its text content. You should see something like the following with some large text and a grid of random Rick and Morty characters:
Considering that we don’t have access to the codebase for the website as we’re not its developers, we can understand the HTML structure behind it by using the Web Inspector element:
As you inspect the HTML elements present on the page, you will observe that the large text is the only H1 element on the page, and the Rick and Morty character cards are within an article element.
Knowing the elements and their attributes is important when testing XML data as you will often need to filter through to these specific elements before running your assertions.
Create another hurl file named rickandmorty-website.hurl
within your Hurl project directory to store the entry for the XML data test.
Add the content of the following code block to your rickandmorty-website.hurl
file to direct Hurl to make a request to the Rick and Morty webpage and execute queries on its XML elements:
# rickandmorty-website.hurl GET https://rickandmortyapi.com HTTP 200 [Asserts] xpath "//h1" exists xpath "normalize-space(//h1)" contains "The Rick and Morty API" xpath "//section" count == 2 xpath "//article" count == 6
The asserts block in the code block above will direct Hurl to validate that the Rick and Morty website passes the following conditions:
Execute the command below to run the tests for the Rick and Morty website:
hurl rickandmorty-website.hurl --test
Once the test file runs successfully, you should see the result in your terminal:
At this point, you are now familiar with executing tests using Hurl. Let’s see how to automate the execution of the tests within a CI/CD pipeline such as GitHub Actions.
In addition to using unit and integration test suites in CI pipelines, developers often want to test their API endpoints directly using real-world values to ensure the response bodies meet the expected results. If you have this need, Hurl is the perfect choice for you!
Being a very lightweight and fast API client makes Hurl a perfect choice for CI pipelines as they have limited resources. Developers have the option to use scripts to install the Hurl binary into their CI pipelines or through community-managed actions such as install-hurl-cross-platform
and setup-hurl
.
To use GitHub Actions, you need to create your action spec in a .yml
file within a .github
root folder and add the following code to it. In a repository, GitHub Actions will use the following specification to execute a workflow run using the defined jobs whenever a pull request is opened or reopened:
.github/ci.yml name: RickAndMorty CI Run on: pull_request: types: - opened - reopened jobs: build: runs-on: ubuntu-latest permissions: contents: read steps: - name: Checkout uses: actions/checkout@v4 - name: Hurl Integration test run: | 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 hurl --test *.hurl --variable URL=https://rickandmortyapi.com
Although the workflow above is not ideal — as it’s testing against an external application and not the current changes in the pull request — it gives you an idea of how to set up your workflow.
Going through the ci.yml
file, you will observe that the build job is using cURL to download the Hurl V4 binary before installing it with root user privileges. With Hurl installed, the job further executes all the Hurl files using a wildcard *.hurl
and passes in the target URL as a variable to execute the requests against it.
Using two curly braces wrapped around a word — like {{test_var}}
— is the syntax for using variables in Hurl files.
Variables are used to store and reuse certain values or change them dynamically as you would when running tests against different application environments. They also enable you to read sensitive credentials such as API keys and tokens into your Hurl files without hardcoding them in.
To improve on the workflow file above, you will need to create a deployment preview flow into your GitHub Action and replace the Rick and Morty website URL with your deploy preview URL.
Hurl presents a feature-rich, flexible, and lightweight tool for testing your APIs straight out of your terminals, CI/CD pipelines, or environments with limited resources. With Hurl, developers who love their command line and terminals no longer have to feel left out when it comes to API testing or compelled to use GUI API clients!
In this tutorial, we explored the benefits of Hurl, evaluated it as a Postman alternative, and went through some examples to show Hurl’s features in action. If you have any further questions, feel free to comment them below.
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowEfficient initializing is crucial to smooth-running websites. One way to optimize that process is through lazy initialization in Rust 1.80.
Design React Native UIs that look great on any device by using adaptive layouts, responsive scaling, and platform-specific tools.
Angular’s two-way data binding has evolved with signals, offering improved performance, simpler syntax, and better type inference.
Fix sticky positioning issues in CSS, from missing offsets to overflow conflicts in flex, grid, and container height constraints.