Skip to content
Snippets Groups Projects
Commit 08ba07ef authored by alexander06's avatar alexander06 Committed by fu1106jv
Browse files

Resolve "Fix Pipeline"

**What did I do?**

* change `.gitlab-ci.yml` to basically reproduce docker compose up and npm run jest
  1. Go into server and run `npm install`
  1. Go into client and run `npm install`
  1. Go into server and run `npm run build`
  1. Go into server, start the server and run all tests in `server/tests`
  1. Go into server, start the server, go into client, start the client and run all tests in `client/tests`
* Create Testing documentation under `doc/testing.md`
* install `jest` and `ts-jest` and all their dependencies as dev-dependencies
* Create config files for jest under `client/jest.config.js` and `server/jest.config.js`
* Create basic tests that also serve as examples under `server/tests/connection.test.ts` and `client/tests/connection.test.ts`
  * The server tests basically try some GET requests to some API Endpoints defined in `server/src/routes.ts` and expect 404 errors
  * The client just polls the index.html file of the frontend
* change the `tsconfig.json` files to lint(?) the test directories
parent e9dcd6bc
No related branches found
No related tags found
No related merge requests found
# This file is a template, and might need editing before it works on your project.
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml
# Official framework image. Look for the different tagged releases at:
# https://hub.docker.com/r/library/node/tags/
image: node:16.2.0
# Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
image: node:lts-alpine
services:
- postgres:latest
......@@ -25,34 +14,52 @@ variables:
POSTGRES_USER: $POSTGRES_USER
POSTGRES_PASSWORD: $POSTGRES_PASSWORD
POSTGRES_HOST_AUTH_METHOD: trust
SKIP_PREFLIGHT_CHECK: "true"
# This folder is cached between builds
# https://docs.gitlab.com/ee/ci/yaml/index.html#cache
# These folders and files are cached between builds
cache:
paths:
- node_modules/
- dist/server.js
before_script:
- npm install
- nohup npm run watch:server &
- client/node_modules/
- server/node_modules/
- server/.env
- server/dist/
# Stages for better overview
stages:
- prepare
- build
- launch
- test
check_build:
mirror_dockerfile_server:
stage: prepare
script:
- cd server && npm install
mirror_dockerfile_client:
stage: prepare
script:
- cd client && npm install
build_server:
stage: build
script:
- npm run build
- cd server && npm run build
#launch_build:
# stage: launch
# script:
# - nohup npm run watch:server &
test_server:
stage: test
# I only run the server, since server tests are (almost) always against the API
before_script:
- cd server && npm run start &
script:
- cd server && npm run test
test_run:
test_client:
stage: test
# If specific content needs to be tested, both the server and client need to be up and running
before_script:
- cd client && npm start &
- cd server && npm start &
script:
- npm test
\ No newline at end of file
- cd client && npm run test
\ No newline at end of file
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
\ No newline at end of file
This diff is collapsed.
......@@ -9,7 +9,6 @@
"@testing-library/jest-dom": "^5.15.0",
"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^12.8.3",
"@types/jest": "^26.0.24",
"@types/node": "^12.20.36",
"@types/react": "^17.0.34",
"@types/react-dom": "^17.0.11",
......@@ -28,7 +27,7 @@
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"test": "jest",
"eject": "react-scripts eject"
},
"eslintConfig": {
......@@ -49,5 +48,11 @@
"last 1 safari version"
]
},
"proxy": "http://server:4000"
"proxy": "http://server:4000",
"devDependencies": {
"@types/supertest": "^2.0.11",
"jest": "^27.3.1",
"supertest": "^6.1.6",
"ts-jest": "^27.0.7"
}
}
require('dotenv').config();
const request = require('supertest');
import request from 'supertest';
describe('GET /', () => {
it('responds with successful (2XX) request and html file', (done) => {
describe('Serving Pages', () => {
/*
* NOTICE:
* Those are structural test examples.
* I've made it, that they all expect 404 errors,
* since the database models have changes while the API hasn't
*/
it('should serve index page', (done) => {
request("http://localhost:3000")
.get('/')
.set('Accept', 'text/html')
.expect('Content-Type', /html/)
.expect(200, done);
});
}, 60000);
});
\ No newline at end of file
......@@ -21,6 +21,7 @@
"jsx": "react-jsx"
},
"include": [
"src"
"src",
"tests"
]
}
# Testing
## Running Tests
Running tests is as simple as going either into the `client` or `server` directory and running `npm test`. Jest will then automatically take all the `*.test.ts` files and run them
> Tip: Before running any test against the client or server, make sure you have the server and/or client running
It's very important to note that the Pipeline on Gitlab will execute all the tests, so expect failed pipelines if you push broken code.
## Writing tests
To create your own tests, just create a new file in the `test` directory of the part you want to test. You could also change an existing file or even create a subdirectory with files. It's important to note that any and all tests files should end with `.test.ts` otherwise Jest will not run them.
### Structuring tests
Since testing is done with [jest](https://www.npmjs.com/package/jest) we can follow a specific structure like this:
```javascript
describe('Test', () => {
it('should do something', (done) => {
// Do something
});
it('should do something else', (done) => {
// Do something else
});
});
```
The `describe` function can be used to group specific tests into one Test Suite, so that you can have similar tests be run together. In this example the Suite would be calles "Test". `it` is used to define a single test. The first argument is simply the test name, the second parameter will be the actual test thats run. Whatever you decide to define here, will be executed. The `done` parameter is optional and can be used if you expect callback.
> Tip: make sure to create tests that maybe only test a single function or a small piece of code and be sure to use descriptive test names, since tests can already serve as documentation.
## API Testing
Using [supertest](https://www.npmjs.com/package/supertest) and the structure above, we can easily create API tests. We only have to modify our structure a little bit.
```javascript
import request from 'supertest';
describe('Test', () => {
it('should do something', (done) => {
//The URL should be always this with our project settings
request("http://localhost:4000")
.get('/api/v1/test')
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200, done)
});
});
```
This example sends a GET request to the `/api/v1/test` endpoint and expects to receive a 200 status code and a JSON response.
### GET Requests
GET Requests are already demonstrated in the example above.
>Tip: if you need to send a GET request with authentication, you can use the `.auth(username, password)` function to do so.
### POST Requests
As you can guess the requests are the same as GET requests, but with the exception of the `.post()` method.
```javascript
import request from 'supertest';
describe('Test', () => {
it('should do something', (done) => {
//The URL should be always this with our project settings
request("http://localhost:4000")
.post('/api/v1/users')
.send({name:'john'})
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200, done)
});
});
```
### Expectations
If you expect your request to yield a response with specific content, you can use the `.expect()` function. For example if you post a Username and expect to get a fixed ID, you can do this:
```javascript
describe('POST /user', () => {
it('user.name should be an case-insensitive match for "john"', (done) => {
request(app)
.post('/user')
.send('name=john') // x-www-form-urlencoded upload
.set('Accept', 'application/json')
.expect(function(res) {
res.body.id = 'some fixed id';
res.body.name = res.body.name.toLowerCase();
})
.expect(200, {
id: 'some fixed id',
name: 'john'
}, done);
});
});
```
You can do a lot more with supertest, basically everything you can to with superagent, so refer to the [supertest documentation](https://www.npmjs.com/package/supertest) and the [superagent documentation](https://www.npmjs.com/package/superagent)for more information.
## React Testing
Testing React/the Frontend works similar as API testing.
Refer to the official [Jest Testing Documentation](https://jestjs.io/docs/tutorial-react) to find out how to do it
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
\ No newline at end of file
This diff is collapsed.
......@@ -7,7 +7,7 @@
"dev": "nodemon",
"build": "tsc",
"start": "node ./dist/server.js",
"test": "echo \"Error: no test specified\" && exit 1"
"test": "jest"
},
"author": "",
"license": "ISC",
......@@ -19,9 +19,14 @@
},
"devDependencies": {
"@types/express": "^4.17.13",
"@types/jest": "^27.0.3",
"@types/node": "^16.11.6",
"@types/supertest": "^2.0.11",
"@types/validator": "^13.6.6",
"jest": "^27.3.1",
"nodemon": "^2.0.14",
"supertest": "^6.1.6",
"ts-jest": "^27.0.7",
"ts-node": "^10.4.0",
"typescript": "^4.4.4"
}
......
require('dotenv').config();
import request from 'supertest';
describe('GET Endpoints', () => {
/*
* NOTICE:
* Those are structural test examples.
* I've made it, that they all expect 404 errors,
* since the database models have changes while the API hasn't
*/
it('if response is 404, server is alive (since GET / isn\'t defined)', (done) => {
request("http://localhost:4000")
.get('/')
.set('Accept', 'text/html')
.expect('Content-Type', /html/)
.expect(404, done);
});
it('Get Vehicle Type with ID (returns 404 since no data)', (done) => {
request("http://localhost:4000")
.get('/vehicleType/1')
.set('Accept', 'text/html')
.expect('Content-Type', /html/)
.expect(404, done);
});
it('Get all Vehicle Types', (done) => {
request("http://localhost:4000")
.get('/vehicleType')
.set('Accept', 'text/html')
.expect('Content-Type', /html/)
.expect(404, done);
});
});
\ No newline at end of file
......@@ -15,6 +15,7 @@
}
},
"include": [
"src/**/*"
"src/**/*",
"tests/*"
]
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment