Server Sent Events — Development & Test Automation
This post is a next part of the my earlier post SSE basics.
In this post, I will get into SSE code and how we can automate it’s testing.
Please refer to my github account at BeTheCodeWithYou and clone the repository Spring-Boot-SSE to directly run the application.
please give repo a star if it did help you ✌️
The need of creating this repository was apparent due to SSE Test challenges and I couldn’t find anything fitted together!!
So, think about if you have a client connected to server over SSE but how do you make sure that your client or clients are getting events which are generated on the server and essentially how do you automate this test?? 😨
Important point to understand is that, here we are testing our server side components to make sure that it is able to send events to all the connected clients and able to release sse emitter objects when clients have initiated connection close. We have simulated the client ( UI ) with java library so that we can automate this approach. 👊
In your application code, you will have client code which will make use of browser supported EventSource object to establish SSE connection with server.
To test it, you will normally open browser, making a connection to SSE channel and then wait for the push notification to receive on the browser when an event is triggered on the server.
To test with multiple clients, you might open multiple browsers and do the same tests.
Challenges with this manual tests of SSE are:-
- can you automate this test behaviour?
- can you assert that message received by the client is correct?
- can you run this test steps with any build tools? 🏃
- could be more ….
To solve this challenge, I thought that it would be nice I find a java equivalent of EventSource object, so that I can write a client ( java based and not the browser ) that establish SSE connection. But then the next issue was, how do I assert because without which test is not complete!!
So, I found an open source library which support java equivalent of EventSource Object.
For Test automation and Assertions, I used ZeroCode TDD framework, which allows easiest way of calling a REST end point and importantly directly calling a java method and asserting what you expected.
Let’s see in SSE in Action ☀️ running the tests
I approached this by creating gradle multi module project with Spring Boot.
Project code consists of below framework and libraries,
gradle
Spring Boot
Sprint REST API
In the multi module gradle project, I have got 3 projects
see-client
sse-server
see-test-automation
Project structure setup
Sse-client
Project setup
Establish a SSE connection to REST endpoint exposed by sse-server project. This is achieved with EventSource
java object .
This project has ClientEventHandler
which overrides a onMessage
method. When server push an event, onMessage method gets invoked and you can retrieve message here.
For simplicity, I have just added sse-client project code into sse-test-automation project, but you can always define dependencies of sse-client into sse-test-automation project as well.
sse-server — in action
click to open on gif, it doesn’t run
This project exposes two rest end points.
/subscribe
for allowing client to establish SSE connection.
@GetMapping("/subscribe")
public SseEmitter subscribeForEvents() {
...
}
/events
for triggering events on the server, which in turn publish events to subscribed clients.
@PostMapping("/events")
public void pushNewEventsToClients(@RequestBody String eventData) throws IOException {
...
}
sse-test-automation
project Setup
This module automates three activities together
a) client subscription for SSE connection,
b) triggering message on the server, and
c) asserting if the client has received the published events.
sse-test-automation project is the key of part of this repository, because that’s the whole purpose of creating this repository to talk about SSE automation testing.
Assertions
As soon as client receives a message, in ClientEventHandler class, onMessage method gets called and there I am adding the message data received in the HashMap.
and then i have written a public method which returns size of the map.
See this code of file event_publish.json, how assertions is achieved.
Creating multiple Clients for SEE connection
This is achieve with the help of ZeroCode framework, which allows to create parallel threads. Refer to file parallel_load.properties
number.of.threads=3 ( to launch 2 clients and 1 server thread )
ramp.up.period.in.seconds=5 ( launch these 3 thread in gap of 5 seconds )
loop.count=1 ( do it once, so you will have total 3 threads )
How to RUN
I have created a TestSuite class, which does everything for us!!
It reads the paralle_load.properties and then create client 1 which connects to the server over SSE.
It then creates another client, client 2 which connects to server over SSE.
It then push message on the server side by calling REST end point.
Refer code here for TestSuite.java