Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to test requests and websockets? [depends on Dream client] #83

Open
tcoopman opened this issue Jun 30, 2021 · 5 comments
Open

How to test requests and websockets? [depends on Dream client] #83

tcoopman opened this issue Jun 30, 2021 · 5 comments

Comments

@tcoopman
Copy link
Contributor

tcoopman commented Jun 30, 2021

Is there any recommended way or documentation on how to tests controllers and websockets?

I could use external tools, for example connect to the server with javascript and initiate websockets there, but it would be nice if we could do this from ocaml directly and use dune to run the tests

@aantron
Copy link
Owner

aantron commented Jun 30, 2021

There is some (not much) support for in-process no-network testing, see section Testing. In particular, Dream.request can be used to artificially create a request, and then Dream.test runs it through a web app. Dream's own unit test suite (highly incomplete; I've been relying on the examples so far) uses this. For example, see this helper used to define most of the router tests:

let show ?(prefix = "/") ?(method_ = `GET) target router =
try
Dream.request ~method_ ~target ""
|> Dream.test ~prefix
(router @@ fun _ -> Dream.respond ~status:`Not_Found "")
|> fun response ->
let status = Dream.status response
and body = Lwt_main.run (Dream.body response)
in
Printf.printf "Response: %i %s\n"
(Dream.status_to_int status) (Dream.status_to_string status);
if body <> "" then
Printf.printf "%s\n" body
else
()
with Failure message ->
print_endline message

These are expect tests, so they just print to STDOUT/STDERR, and ppx_expect compares them with correct output.

There is nothing else besides that, but I do have a notes item to look into this. I'd appreciate it very much if you would let me know what type of testing you'd like to do, and/or provide me with a link to some implementation of it (in JS or elsewhere). I'd then see how it should be supported in Dream or at least in OCaml.

There is nothing for testing WebSockets conveniently at the moment, a definite gap. To test them immediately, you'd need to do end-to-end tests with an external tool.

@tcoopman
Copy link
Contributor Author

tcoopman commented Jun 30, 2021

There is nothing for testing WebSockets conveniently at the moment, a definite gap. To test them immediately, you'd need to do end-to-end tests with an external tool.

That's what I was thinking about and what I was afraid of... Basically what I would want is to be able to start a Dream.websocket in a test and be able to connect clients to it.

I know how to do it with external tools, but it's a bit of overhead and not as fun as being able to do directly.

For other tests, I like the phoenix tests (https://hexdocs.pm/phoenix/testing_controllers.html)
For example:

describe "index" do
  test "lists all posts", %{conn: conn} do
    conn = get(conn, Routes.post_path(conn, :index))
    assert html_response(conn, 200) =~ "Listing Posts"
  end
end

(I don't think =~ is something ppx_expect can do)

They also have nice tests for websockets:

setup do
  {:ok, _, socket} =
    UserSocket
    |> socket("user_id", %{some: :assign})
    |> subscribe_and_join(RoomChannel, "room:lobby")

  %{socket: socket}
end

test "ping replies with status ok", %{socket: socket} do
  ref = push(socket, "ping", %{"hello" => "there"})
  assert_reply ref, :ok, %{"hello" => "there"}
end

Of course this is not for a general websocket connection, but you get the point.

@tcoopman
Copy link
Contributor Author

tcoopman commented Jul 2, 2021

Another example:

If I want to write a unit test around something that manages the current clients connected to websockets (Dream.websocket), I see no way of creating these Dream.websockets in a test contest.

@aantron aantron changed the title How to test requests and websockets? How to test requests and websockets? [depends on Dream client] Jul 3, 2021
@aantron
Copy link
Owner

aantron commented Apr 27, 2023

I started creating Hyper last year, the client counterpart to Dream. It likely can address parts of this issue.

@aantron
Copy link
Owner

aantron commented Apr 27, 2023

In particular, the client's requesting functions are request -> response promise functions, and a Dream Web app has the same type signature (before it is passed to Dream.run/Dream.serve). One of Hyper's test suites, nohttp, implements the server by directly calling the server function. Of course, there are tests with actual HTTP transports as well.

I expect this would eventually be useful for the users' Dream (and Hyper) testing.

tchibanda24 pushed a commit to tchibanda24/dream that referenced this issue Feb 5, 2025
Upgrade to the upcoming (0.10.0 ?) h2 API
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants