For my uses it's great that it has both test suite mode and individual invocation mode. I use it to execute a test suite of HTTP requests against a service in CI.
I'm not a super big fan of the configuration language, the blocks are not intuitive and I found some lacking in the documentation assertions that are supported.
Overall the tool has been great, and has been extremely valuable.
I started using interface testing when working on POCs. I found this helps with LLM-assisted development. Tests are written to directly exercise the HTTP methods, it allows for fluidity and evolution of the implementations as the project is evolving.
I also found the separation of testing very helpful, and it further enforces the separation between interface and implementation. Before hurl, the tests I wrote would be written in the test framework of the language the service is written in. The hurl-based tests really help to enforce the "client" perspective. There is no backdoor data access or anything, just strict separation betwen interface, tests and implementation :)
jicea · 59m ago
Maintainer here, thanks for the feedbacks. 6-7 years ago, when we started working on Hurl, we started with a JSON then a YAML file format. We gradually convinced ourself to write a new file format and I completely understand that it might feel weird. We tried (maybe not succeeded!) to have something simple for the simple case...
I'm really interested by issues with the documentation: it can always be improved and any issues is welcome!
zackify · 3m ago
Oh wow! This reminds me so much of what I was trying to do almost 10 years ago but I was too much of a noob to make it make more sense haha.
Hurl is awesome. A while back I ported a small web service from Python to Rust. Having rigorous tests of the public API is amazing; a language-independent integration test! I was able to swap it out with no changes to the public API or website.
Worth mentioning that using Hurl in Rust specifically gives you a nice bonus feature: integration with cargo test tooling. Since Hurl is written in Rust, you can hook into hurl-the-library and reuse your .hurl files directly in your test suite. Demo: https://github.com/perrygeo/axum-hurl-test
1a527dd5 · 7h ago
Yeah love Hurl, we stared using it back in 2023-09.
We had a test suite using Runscope, I hated that changes weren't versioned controlled. Took a little grunt work and I converted them in Hurl (where were you AI?) and got rid of Runscope.
Now we can see who made what change when and why. It's great.
hliyan · 2h ago
I must say, the sample section[1] does an excellent job of making a case for the tool, especially to people who are inclined to make a snap judgement about the usefulness of the tool within the first 5 minutes (I'm sometimes guilty of this).
You should probably be looking at the Cargo.toml file(s) (for direct dependencies at least) instead of the lock file as the lock file will include dependencies used for dev/testing.
twodave · 1h ago
I took a lot of inspiration from this project when designing my own HTTP testing tool[0]. We needed to be able to run hundreds of tests quickly, and in parallel. If that is something you need and you like Hurl, then you might like Nap also.
Hi Hurl maintainer here, happy to answer any question and get feedbacks!
gavinray · 5h ago
So, myself and many folks I know have taken to writing tests in the form of ".http" files that can be executed by IDE extensions in VS Code/IDEA.
Those basically go in the form
POST http://localhost:8080/api/foo
Content-Type: application/json
{ "some": "body" }
And then we have a 1-to-1 mapping of "expected.json" outputs for integration tests.
We use a bespoke bash script to run these .http file with cURL, and then compare the outputs with jq, log success/failure to console, and write "actual.json"
Can I use HURL in a similar way? Essentially an IDE-runnable example HTTP request that references a JSON file as the expected output?
And then run HURL over a directory of these files?
xnorswap · 45m ago
I like this approach.
Is your expected.json the actual response body, or is it an object containing body, status, header values, and time-taken, etc?
hiddew · 7h ago
Hurl is underappreciated for writing nice and maintainable HTTP-level test suites. Thanks for the tool!
airstrike · 2h ago
Arguably off-topic but I just want to say few naming choices give me more satisfaction than Hurl
jiehong · 7h ago
Thanks a lot for maintaining it!
Where do you see hurl in the next 2 years?
jicea · 7h ago
Obviously better IDEs integration, support for gRPC, Websocket would be very cool.
A favorite of mine is to be available through official `apt`: there has been some work but it's kind of stuck. The Debian integration is the more difficult integration we have to deal. It's not Debian fault, there are a lot of documentation but we've struggled a lot and fail to understand the process.
It is targeted toward more postman crowd though. May not be as lightweight.
LadyCailin · 5h ago
It’s not nearly as lightweight, and one of the major dealbreakers for postman and equivalents (even ignoring all the drama with postman) is that you have to import and export the data in the client in order to get some text file you can just commit to repo. For my team, that’s a dealbreaker, because it means that people write entire suites of stuff, and never commit them, meaning other people end up doing the same work over and over.
argentinian · 4h ago
In Bruno you don't have to import or export to get a text file.
LadyCailin · 3h ago
Ahhh, ok. I think I’m thinking about Insomnia, which is basically (in fact?) a fork of Postman. Anyways, that fact is what made Postman a dealbreaker for me, even before the drama. Another thing I like about Rest Client is that the configuration is just a text file, so bearer token etc can be updated via script that runs in a loop.
Rest Client has a few cons though, like request chaining.
https://github.com/mistweaverco/kulala.nvim is an another restish (it can do gRPC to) plugin for neovim. It is intended to be compatible with a Jetbrains as much as possible.
(After I have seen the IntelliJ one from a colleague I was searching for one like that in neovim. That's the best one I found. It's not perfect, but it works.
Edit: The tool from OP looks very neat though. I will try it out. Might be a handy thing for a few prepared tests that I run frequently
mcescalante · 7h ago
yep, I've played with Hurl and find it nice but recently have been leaning into the .http stuff more. IntelliJ has it built in, there's the plugin you linked, and then for CLI i've used httpYac. No "vendor lock in", really easy to share with copy & paste or source control.
gotimo · 6h ago
+1 On HttpYac, it's been really nice to get started with and growing into a more powerful API testing suite over time
kalli · 5h ago
This looks interesting. Longtime user of the Vscode-restclient, but have been moving over to httpyac lately for the scripting and cli use. Will take a look to see if hurl is a good fit.
One annoying thing I've found in testing these tools is that a standard hasn't emerged for using the results of one request as input for another in the syntax of `.http` files. These three tools for instance have three different ways of doing it:
* hurl uses `[Captures]`
* Vscode-restclient does it by referencing request names in a variable declaration (like: `@token = {{loginAPI.response.body.token}}`).
* While httpyac uses `@ref` syntax.
From a quick round of testing it seems like using the syntax for one might break the other tools.
Guilty to have created yet-another-format for HTTP client! To "mitigate" this issue, you can use `hurlfmt` (distributed along `hurl`) that would allow you to export a Hurl file to JSON. You could then go from this JSON to another... It's not magic but it can help if you're going to change from Hurl to another thing.
kalli · 4h ago
No worries, it's also interesting to see different peoples approaches to the best syntax for this. Exporters/importers do make life a bit easier I suppose.
I don't know what the mechanism/incentive for getting a standard would be either. Probably most likely would be if there was one clear "winner" that everyone else felt the need mirror.
In any case, appreciate the reply and the tool. Good luck with it.
jiggawatts · 4h ago
What's really special is that Visual Studio Code and Visual Studio both have .HTTP files... which are incompatible with each other.
Snapshots diff current with previous output and I only have to accept or reject the diff. I don't have to write the expected response myself. Snapshots can also stub out parts of the response that are not determistic.
adelineJoOs · 6h ago
> Snapshots can also stub out parts of the response that are not determistic.
TIL! The way I knew to do it was to have a mock implementation that behaved like the real thing, expect for data/time/uuids/..., where there was just a placeholder.
Snapshot tests being able to "mask" those non-deterministic parts sounds cool!
adelineJoOs · 2h ago
tbh, that seems pretty close to what I would call snapshot testing already. What people usually do with it is using it for more broadly compared to API testing (for example, I currently use it to test snapshots of a TUI application I am developing) - i.e. you can use it whenever your test is of the form "I have something that I can print in some way and that should look the same until I explicitely want it to look differently in the future". There are a bit more bells and wizzles - For example, it is nice that one does not have to write the initial snapshots oneself. You write the test, execute, it creates the resulting file, then you review and commit that - handy little workflow!
WhitneyLand · 1h ago
One thing not really advertised about Claude Code is it makes all command line tools plain text/plain English.
“Get data from the last log entry in <file> and post it to <url>”
yoavm · 2h ago
The one thing I never understood about the Hurl format is why the response status code assertion happens at the request section and not under the `[Asserts]` section. I wonder what the rationale behind that is.
jorgeleo · 1h ago
So we are not doing telnet anymore?
antisceptic · 9h ago
Is that POST in the readme sending the password in the query params? Is this shorthand or literally adding them to the params?
I don't really feel the need for a curl replacement. In the past I've used httpie which is pretty slick but I end up falling back to writing tests in python using requests library.
Maybe I'm not the target audience here, but I should still say something nice I guess. It's nice that it's written in Rust, and open source tooling is in need of fresh projects ever since everyone started bunkering up against the AI monolith scraping all their work. We should celebrate this kind of project, I just wish I had a use for it.
jicea · 8h ago
The POST in the README is going to send the params in the request body "url form encoded" like a form in a web page. There are more samples on the doc site [1].
Regarding curl, Hurl is just adding some syntax to pass data from request to request and add assert to responses. For a one time send & forget request, curl is the way, but if you've a kind of workflow (like accessing an authentified resource) Hurl is worth a try. Hurl uses libcurl under the hood and you've an option `--curl` to get a list of curl commands.
> The POST in the README is going to send the params in the request body "url form encoded" like a form in a web page.
Is there a different POST request in the readme or are you saying that this example is going to send the "user" and "password" params in the request body?
That seems really surprising to me - how would you then send a POST request that includes query string parameters? The documentation on form parameters [1] suggests there's an explicit syntax for sending form-encoded request parameters
I see it more as a Postman replacement than curl. When I’m working on a set of APIs, I can quickly write a Hurl file with different combinations that I’m working on. There are usually editor integrations to run individual requests. Then I can share the same Hurl file to my team or commit it in the repo.
tra3 · 8h ago
Check out tavern if you’re in python-land. Pretty pleasant way to write declarative API tests.
lelanthran · 6h ago
For automated testing I use hurl, but my personal dev roadmap is to create another tool.
The deficiencies in huel with client state management is not easy to fix.
What I'd like is full client state control with better variable management and use.
For my last project I used Python to write the tests, which appears to work well initially. Dunno how well it will hold up for ongoing maintenance.
epalm · 4h ago
This is interesting. I’m wondering how programmable this is. Would this project (or any similar ones) be able to POST a json payload with a field set to “now()”?
If I want to open a modal & check something, could it simulate clicking on open modal button? Or is it first level for now (without any support for interactions / javascript magic)
jicea · 8h ago
Hurl works only on the HTTP layer, there is no JavaScript engine. If your modal open a form that will trigger some kind of XHR, you'll "simulate" the HTTP traquets that the form modal could have done. Hurl is not a kind of Playwright for instance.
blueflow · 3h ago
Is there any program code that is not based on plain text? Punch cards maybe? For the value of "plain text" that includes a programming language with its own syntax and grammar, like Hurl.
ninetyninenine · 1h ago
This is cool, but also genuine question why this over some scripting language that can easily do http calls as well?
I don’t think the DSL is significantly easier than a PL and it’s more limited to?
Is it because of raw speed or ease of reading the DSL?
gabesullice · 8h ago
This looks awesome. I've searched for something like this many times and made a half dozen half-hearted attempts to build it too. Great job!
lambda-science · 5h ago
Isn't that very similar to Jetbrains HTTP Client ?
genericspammer · 7h ago
Can you have different environments or profiles or whatever, with different global variables?
Can you share "fixtures" amongst tests? For example, I wouldn't want to have to copy/paste the signup and login process for each type of user across hundreds of tests.
What about test isolation? Are people using something else to "prime" the service before/after running these tests?
For my uses it's great that it has both test suite mode and individual invocation mode. I use it to execute a test suite of HTTP requests against a service in CI.
I'm not a super big fan of the configuration language, the blocks are not intuitive and I found some lacking in the documentation assertions that are supported.
Overall the tool has been great, and has been extremely valuable.
I started using interface testing when working on POCs. I found this helps with LLM-assisted development. Tests are written to directly exercise the HTTP methods, it allows for fluidity and evolution of the implementations as the project is evolving.
I also found the separation of testing very helpful, and it further enforces the separation between interface and implementation. Before hurl, the tests I wrote would be written in the test framework of the language the service is written in. The hurl-based tests really help to enforce the "client" perspective. There is no backdoor data access or anything, just strict separation betwen interface, tests and implementation :)
I'm really interested by issues with the documentation: it can always be improved and any issues is welcome!
https://github.com/zackify/legible
Worth mentioning that using Hurl in Rust specifically gives you a nice bonus feature: integration with cargo test tooling. Since Hurl is written in Rust, you can hook into hurl-the-library and reuse your .hurl files directly in your test suite. Demo: https://github.com/perrygeo/axum-hurl-test
We had a test suite using Runscope, I hated that changes weren't versioned controlled. Took a little grunt work and I converted them in Hurl (where were you AI?) and got rid of Runscope.
Now we can see who made what change when and why. It's great.
[1] https://github.com/Orange-OpenSource/hurl?tab=readme-ov-file...
https://github.com/Orange-OpenSource/hurl/blob/master/Cargo....
[0] https://naprun.dev
Those basically go in the form
And then we have a 1-to-1 mapping of "expected.json" outputs for integration tests.We use a bespoke bash script to run these .http file with cURL, and then compare the outputs with jq, log success/failure to console, and write "actual.json"
Can I use HURL in a similar way? Essentially an IDE-runnable example HTTP request that references a JSON file as the expected output?
And then run HURL over a directory of these files?
Is your expected.json the actual response body, or is it an object containing body, status, header values, and time-taken, etc?
Where do you see hurl in the next 2 years?
A favorite of mine is to be available through official `apt`: there has been some work but it's kind of stuck. The Debian integration is the more difficult integration we have to deal. It's not Debian fault, there are a lot of documentation but we've struggled a lot and fail to understand the process.
[1]: https://github.com/Orange-OpenSource/hurl/issues/366
If I find time I could throw a spec file + ci/cd workflow to get you going that way too
You make GET request to server with any of supported crawlers and obtain result in JSON
https://github.com/rumca-js/crawler-buddy/
Supports request, selenium, Httpx, curl cffi, etc
It gives you full control of constructing requests and assertions because test scenarios may include arbitrary JavaScript.
https://marketplace.visualstudio.com/items?itemName=humao.re...
Which is a banger VS Code extension for all sorts of http xyz testing.
It is targeted toward more postman crowd though. May not be as lightweight.
Rest Client has a few cons though, like request chaining.
(After I have seen the IntelliJ one from a colleague I was searching for one like that in neovim. That's the best one I found. It's not perfect, but it works.
Edit: The tool from OP looks very neat though. I will try it out. Might be a handy thing for a few prepared tests that I run frequently
One annoying thing I've found in testing these tools is that a standard hasn't emerged for using the results of one request as input for another in the syntax of `.http` files. These three tools for instance have three different ways of doing it:
* hurl uses `[Captures]`
* Vscode-restclient does it by referencing request names in a variable declaration (like: `@token = {{loginAPI.response.body.token}}`).
* While httpyac uses `@ref` syntax.
From a quick round of testing it seems like using the syntax for one might break the other tools.
[1]: https://hurl.dev/docs/capturing-response.html
[2]: https://github.com/Huachao/vscode-restclient
[3]: https://httpyac.github.io/guide/metaData.html#ref-and-forcer...
I don't know what the mechanism/incentive for getting a standard would be either. Probably most likely would be if there was one clear "winner" that everyone else felt the need mirror.
In any case, appreciate the reply and the tool. Good luck with it.
Conway's Law in action, ladies and gentlemen.
https://blog.jetbrains.com/idea/2022/12/http-client-cli-run-...
TIL! The way I knew to do it was to have a mock implementation that behaved like the real thing, expect for data/time/uuids/..., where there was just a placeholder. Snapshot tests being able to "mask" those non-deterministic parts sounds cool!
“Get data from the last log entry in <file> and post it to <url>”
I don't really feel the need for a curl replacement. In the past I've used httpie which is pretty slick but I end up falling back to writing tests in python using requests library.
Maybe I'm not the target audience here, but I should still say something nice I guess. It's nice that it's written in Rust, and open source tooling is in need of fresh projects ever since everyone started bunkering up against the AI monolith scraping all their work. We should celebrate this kind of project, I just wish I had a use for it.
Regarding curl, Hurl is just adding some syntax to pass data from request to request and add assert to responses. For a one time send & forget request, curl is the way, but if you've a kind of workflow (like accessing an authentified resource) Hurl is worth a try. Hurl uses libcurl under the hood and you've an option `--curl` to get a list of curl commands.
[1]: https://hurl.dev/docs/samples.html
Is there a different POST request in the readme or are you saying that this example is going to send the "user" and "password" params in the request body?
> POST https://example.org/login?user=toto&password=1234
That seems really surprising to me - how would you then send a POST request that includes query string parameters? The documentation on form parameters [1] suggests there's an explicit syntax for sending form-encoded request parameters
[1]: https://hurl.dev/docs/request.html#form-parameters
[1]: https://github.com/Orange-OpenSource/hurl/issues/4151
The deficiencies in huel with client state management is not easy to fix.
What I'd like is full client state control with better variable management and use.
For my last project I used Python to write the tests, which appears to work well initially. Dunno how well it will hold up for ongoing maintenance.
I don’t think the DSL is significantly easier than a PL and it’s more limited to?
Is it because of raw speed or ease of reading the DSL?
[1]: https://hurl.dev/docs/manual.html#netrc
première fois que je vois qqch de cool sortir d'orange.
What about test isolation? Are people using something else to "prime" the service before/after running these tests?