Java & Cypress 101

Softray Solutions
6 min readJan 10, 2022

Written by Milan Žuža, Software Developer and Team Lead at Softray Solutions

Systems with large scale of users demand high availability, no downtimes (if possible) and no functional issues (since that is the main reason why anyone would use the system). Those systems usually have a bunch of functionalities, which evolve during the time, and that means implementing new stuff would likely impact current functionalities. Testing those functionalities may or may not include (risky?) testing old ones, and with the system becoming more and more complex, testing appears as one painful experience (since more and more things needs to be tested to ensure nothing is broken). Having automation set in place means writing those tests once and run it each time before release is made. Spending more time on automating those tasks pays off after few releases and it’s ensuring that system will behave the same as it behaved previously. Those tests are ideated the way that they can be run independently of any other tests, self-contained and ready to replace manual QAs.

During this blog, there will be explained how to prepare sample system (in this case API), deploy it somewhere in cloud and test it using Cypress framework.

So let’s start with Java…

There is a fiction project that will be focused on capturing specific places and giving the users possibility to manipulate with them, like them etc.

There is API documentation that gives overview of the app: https://places-spot-api-dev.herokuapp.com/api/v1/swagger-ui.html

As shown above, there are a few separate functionalities, so let’s start from registration. User enters username, password & email in order to register (POST /external/users).

After that, user is saved in the system and can login using POST /external/token endpoint. In order to get the token, user will need to send username & password used from registration.

After user gets token, places & likes, functionality can be accessed. User can get places, create new ones, get specific places, and delete his/her places. Same logic applies for likes.

Regarding project structure, this is the way how it is built:

Base package has the following packages:

• Config (security classes, auth filters and global exception handler)

• Connector (feign client to another API and its models)

• Controller (entry point to system, where endpoints are placed)

• Exception (exceptions which are part of the inner system)

• Mapper (mapping DTOs to entities and vice-versa)

• Model (DTOs)

• Repository (entities and repositories- JPA)

• Service (components which contain business logic)

• Utils (common functions)

PlacesspotApplication is the main class and entry point for application to start. Package db.migration is used to create DB tables, indexes etc. during startup. Application.properties is used for storing environment variables, like DB credentials, API URLs, JWT secret etc.

In this blog, there will be no deeper discussion regarding the service and its implementation. If you want to check it yourself, you can check the source code.

Source code can be found here: https://github.com/etfgunner/Places-Api (private repo, contact mzuza@softraysolution.com for access).

Cypress

Cypress is an open-source test framework used for writing end-to-end tests, integration, and unit tests.
Both frontend applications and backend applications can be tested using cypress.

Cypress is built using next libraries and frameworks:

• Mocha (for structuring test)

• Chai (writing assertions)

• Chai-Jquery

• Sinon.js (stub and spy methods)

• Sinon-Chai (writing assertions for stubs and spies)

In order to setup cypress, you can follow instructions: https://docs.cypress.io/guides/getting-started/installing-cypress#Installing

After you setup cypress, you will be able to use Test Runner and run your tests (when initially created, demo tests will be added to your Runner).

Once you are completed, you will have structure like this:

Package.json is used to store all dependencies, e.g. Cypress.

“cypress:open”: “cypress open” is added to be able to run cypress tests by:

npm run cypress:open

This project will be testing java code described before, in order not to repeat API base URL each time, cypress.json is used.

Setting base URL is easy:

“baseURL”: “https://places-spot-api-dev.herokuapp.com/api/v1"

This way, whenever request is made, this URL will be used as default.

When writing tests for specific functionality, simply create new js file and put tests there, like auth_tests.js:

Object initialUser is created for tests in a way that each time new user data is present, using Cypress random function.

Registration test is quite simple, calling cy.request with method POST, on path /external/users and providing body created above, after which assertions are made, where response status code is checked, username and password provided in request and that ID is returned (which is used later for identifying user).

What if negative scenario should be tested? Let’s say somebody tries to register twice with the same registration data.

In that case, cy.request should be changed a bit. Cypress is assuming that response status code will be 200 by default, so in order to test those scenarios, some flag is needed to say cypress not to fail just because non 200 is returned. That is done by sending failOnStatusCode: false.
Afterwards, assertions can be made like for any positive scenario. In this case, status code is expected to be 400, which indicates that data is not valid. In this case user already exists, so the system will not accept it.

After the registration is completed, user should be able to login:

Sending same username and password from registration should result in getting token, like asserted above.

For Places tests, initializing data can be done this way:

Login data is used to get token and then run tests, place data is used to create new place and headers for authenticating user.

It is important to note that getting token should not be done each test is run, since it takes time, and there is no benefit of using it.

Login method can be created and called by before method in Cypress. That method is run before all tests once, and in this scenario, it is used to fill Authorization header.

After that, tests can be run:

Create place endpoint requires authorization to be sent, in this case Authorization header with Bearer token. The rest of test is the same as for other functionalities.

After running npm run cypress:open, cypress test runner should be up:

Here you can run tests you want, e.g. auth_tests. After clicking on them, and selecting browser, new window will be open and tests will run.

On the left you can check tests status and execution time, on the right there is UI presentation (in this case none, since only API is called).

If you want to check rest of the source code, which is not covered by this blog, you can find it here: https://github.com/etfgunner/CypressDemo (private repo, contact mzuza@softraysolution.com for access).

Main purpose of this blog is to have the basic understanding of how the development and testing process in done. Knowing how other roles work when building the system might help in understanding your role as well, as well as developing yourself in a way that tracing and finding issues are much easier to predict before enormous damage is made.

If you enjoyed reading this, click on the clap button so others can find this post.

--

--