finalize test suites and improve documentation
This commit is contained in:
parent
645fde6f87
commit
0e29958bf9
33
.aliases
33
.aliases
@ -90,9 +90,38 @@ alias pg-sql-restore='gunzip --stdout | docker exec -i hsadmin-ng-postgres psql
|
|||||||
alias fp='grep -r '@Accepts' src | sed -e 's/^.*@/@/g' | sort -u | wc -l'
|
alias fp='grep -r '@Accepts' src | sed -e 's/^.*@/@/g' | sort -u | wc -l'
|
||||||
|
|
||||||
alias gw-spotless='./gradlew spotlessApply -x pitest -x test -x :processResources'
|
alias gw-spotless='./gradlew spotlessApply -x pitest -x test -x :processResources'
|
||||||
alias gw-test='. .aliases; . .tc-environment; ./gradlew test'
|
|
||||||
alias gw-check='. .aliases; . .tc-environment; gw test check -x pitest'
|
alias gw-check='. .aliases; . .tc-environment; gw test check -x pitest'
|
||||||
|
|
||||||
|
# HOWTO: run all 'normal' tests (no scenario+import-tests): `gw-test`
|
||||||
|
# You can also mention specific targets: `gw-test importOfficeData`.
|
||||||
|
# This will always use the environment from `.tc-environment`.
|
||||||
|
#
|
||||||
|
# HOWTO: re-run tests even if no changed can be detected: `gw-test --rerun`
|
||||||
|
# You can also mention specific targets: `gw-test scenarioTest --rerun`.
|
||||||
|
# This will always use the environment from `.tc-environment`.
|
||||||
|
#
|
||||||
|
# HOWTO: run all tests (unit, integration+acceptance, import and scenario): `gw-test --all`
|
||||||
|
# You can also re-run all these tests, which will take ~20min: `gw-test --all --rerun`
|
||||||
|
# This will always use the environment from `.tc-environment`.
|
||||||
|
#
|
||||||
|
function _gwTest() {
|
||||||
|
. .aliases;
|
||||||
|
. .tc-environment;
|
||||||
|
if [ "$1" == "--all" ]; then
|
||||||
|
shift # to remove the --all from $@
|
||||||
|
# delierately in separate gradlew-calls to avoid Testcontains-PostgreSQL problem spillover
|
||||||
|
./gradlew unitTest "$@" &&
|
||||||
|
./gradlew officeIntegrationTest bookingIntegrationTest hostingIntegrationTest "$@" &&
|
||||||
|
./gradlew scenarioTest "$@" &&
|
||||||
|
./gradlew importOfficeData importHostingAssets "$@";
|
||||||
|
elif [ $# -eq 0 ] || [[ $1 == -* ]]; then
|
||||||
|
./gradlew test "$@";
|
||||||
|
else
|
||||||
|
./gradlew "$@";
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
alias gw-test=_gwTest
|
||||||
|
|
||||||
alias howto=bin/howto
|
alias howto=bin/howto
|
||||||
alias cas-curl=bin/cas-curl
|
alias cas-curl=bin/cas-curl
|
||||||
|
|
||||||
@ -107,6 +136,6 @@ if [ ! -f .environment ]; then
|
|||||||
fi
|
fi
|
||||||
source .environment
|
source .environment
|
||||||
|
|
||||||
alias scenario-reports-upload='./gradlew scenarioTests convertMarkdownToHtml && ssh hsh03-hsngdev@h50.hostsharing.net "rm -f doms/hsngdev.hs-example.de/htdocs-ssl/scenarios/office/*.html" && scp build/doc/scenarios/*.html hsh03-hsngdev@h50.hostsharing.net:doms/hsngdev.hs-example.de/htdocs-ssl/scenarios/office'
|
alias scenario-reports-upload='./gradlew scenarioTest convertMarkdownToHtml && ssh hsh03-hsngdev@h50.hostsharing.net "rm -f doms/hsngdev.hs-example.de/htdocs-ssl/scenarios/office/*.html" && scp build/doc/scenarios/*.html hsh03-hsngdev@h50.hostsharing.net:doms/hsngdev.hs-example.de/htdocs-ssl/scenarios/office'
|
||||||
alias scenario-reports-open='open https://hsngdev.hs-example.de/scenarios/office'
|
alias scenario-reports-open='open https://hsngdev.hs-example.de/scenarios/office'
|
||||||
|
|
||||||
|
21
Jenkinsfile
vendored
21
Jenkinsfile
vendored
@ -35,9 +35,24 @@ pipeline {
|
|||||||
|
|
||||||
stage ('Tests') {
|
stage ('Tests') {
|
||||||
parallel {
|
parallel {
|
||||||
stage('Unit-/Integration/Acceptance-Tests') {
|
stage('Unit-Tests') {
|
||||||
steps {
|
steps {
|
||||||
sh './gradlew check --no-daemon -x pitest -x dependencyCheckAnalyze -x importOfficeData -x importHostingAssets'
|
sh './gradlew unitTest --no-daemon'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('General-Tests') {
|
||||||
|
steps {
|
||||||
|
sh './gradlew generalTest --no-daemon'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Office-Tests') {
|
||||||
|
steps {
|
||||||
|
sh './gradlew officeIntegrationTest --no-daemon'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Booking+Hosting-Tests') {
|
||||||
|
steps {
|
||||||
|
sh './gradlew bookingIntegrationTest hostingIntegrationTest --no-daemon'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('Import-Tests') {
|
stage('Import-Tests') {
|
||||||
@ -47,7 +62,7 @@ pipeline {
|
|||||||
}
|
}
|
||||||
stage ('Scenario-Tests') {
|
stage ('Scenario-Tests') {
|
||||||
steps {
|
steps {
|
||||||
sh './gradlew scenarioTests --no-daemon'
|
sh './gradlew scenarioTest --no-daemon'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
50
README.md
50
README.md
@ -51,10 +51,11 @@ Everything is tested on _Ubuntu Linux 22.04_ and _MacOS Monterey (12.4)_.
|
|||||||
To be able to build and run the Java Spring Boot application, you need the following tools:
|
To be able to build and run the Java Spring Boot application, you need the following tools:
|
||||||
|
|
||||||
- Docker 20.x (on MacOS you also need *Docker Desktop* or similar) or Podman
|
- Docker 20.x (on MacOS you also need *Docker Desktop* or similar) or Podman
|
||||||
- optionally: PostgreSQL Server 15.5-bookworm
|
- optionally: PostgreSQL Server 15.5-bookworm, if you want to use the database directly, not just via Docker
|
||||||
(see instructions below to install and run in Docker)
|
(see instructions below to install and run in Docker)
|
||||||
- The matching Java JDK at will be automatically installed by Gradle toolchain support to `~/.gradle/jdks/`.
|
- The matching Java JDK at will be automatically installed by Gradle toolchain support to `~/.gradle/jdks/`.
|
||||||
- You also might need an IDE (e.g. *IntelliJ IDEA* or *Eclipse* or *VS Code* with *[STS](https://spring.io/tools)* and a GUI Frontend for *PostgreSQL* like *Postbird*.
|
- You also might need an IDE (e.g. *IntelliJ IDEA* or *Eclipse* or *VS Code* with *[STS](https://spring.io/tools)* and a GUI Frontend for *PostgreSQL* like *Postbird*.
|
||||||
|
- Python 3 is expected in /usr/bin/python3 if you want to run the `howto` tool (see `bin/howto`)
|
||||||
|
|
||||||
If you have at least Docker and the Java JDK installed in appropriate versions and in your `PATH`, then you can start like this:
|
If you have at least Docker and the Java JDK installed in appropriate versions and in your `PATH`, then you can start like this:
|
||||||
|
|
||||||
@ -64,7 +65,12 @@ If you have at least Docker and the Java JDK installed in appropriate versions a
|
|||||||
gw # initially downloads the configured Gradle version into the project
|
gw # initially downloads the configured Gradle version into the project
|
||||||
|
|
||||||
gw test # compiles and runs unit- and integration-tests - takes >10min even on a fast machine
|
gw test # compiles and runs unit- and integration-tests - takes >10min even on a fast machine
|
||||||
gw scenarioTests # compiles and scenario-tests - takes ~1min on a decent machine
|
# `gw test` does NOT run import- and scenario-tests.
|
||||||
|
# Use `gw-test` instead to make sure .tc-environment is sourced.
|
||||||
|
gw scenarioTest # compiles and scenario-tests - takes ~1min on a decent machine
|
||||||
|
# Use `gw-test scenarioTest` instead to make sure .tc-environment is sourced.
|
||||||
|
|
||||||
|
howto test # shows more test information about how to run tests
|
||||||
|
|
||||||
# if the container has not been built yet, run this:
|
# if the container has not been built yet, run this:
|
||||||
pg-sql-run # downloads + runs PostgreSQL in a Docker container on localhost:5432
|
pg-sql-run # downloads + runs PostgreSQL in a Docker container on localhost:5432
|
||||||
@ -437,36 +443,42 @@ Some of these rules are checked with *ArchUnit* unit tests.
|
|||||||
|
|
||||||
### Run Tests from Command Line
|
### Run Tests from Command Line
|
||||||
|
|
||||||
Run all tests which have not yet been passed with the current source code:
|
Run all unit-, integration- and acceptance-tests which have not yet been passed with the current source code:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
gw test
|
gw test # uses the current environment, especially HSADMINNG_POSTGRES_JDBC_URL
|
||||||
|
```
|
||||||
|
|
||||||
|
If the referenced database is not empty, the tests might fail.
|
||||||
|
|
||||||
|
To explicitly use the Testcontainers-environment, run:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
gw-test # uses the environment from .tc-environment
|
||||||
```
|
```
|
||||||
|
|
||||||
Force running all tests:
|
Force running all tests:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
gw cleanTest test
|
gw-test --rerun
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To find more options about running tests, try `howto test`.
|
||||||
|
|
||||||
|
|
||||||
### Spotless Code Formatting
|
### Spotless Code Formatting
|
||||||
|
|
||||||
Code formatting for Java is checked via *spotless*.
|
Code formatting for Java is checked via *spotless*.
|
||||||
The formatting style can be checked with this command:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
gw spotlessCheck
|
|
||||||
```
|
|
||||||
|
|
||||||
This task is also included in `gw build` and `gw check`.
|
|
||||||
|
|
||||||
To apply formatting rules, use:
|
To apply formatting rules, use:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
gw spotlessApply
|
gw-spotless
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The gradle task spotlessCheck is also included in `gw build` and `gw check`,
|
||||||
|
thus if the formatting is not compliant to the rules, the build is going to fail.
|
||||||
|
|
||||||
|
|
||||||
### JaCoCo Test Code Coverage Check
|
### JaCoCo Test Code Coverage Check
|
||||||
|
|
||||||
This project uses the JaCoCo test code coverage report with limit checks.
|
This project uses the JaCoCo test code coverage report with limit checks.
|
||||||
@ -508,9 +520,8 @@ This task is also executed as part of `gw check`.
|
|||||||
|
|
||||||
#### Remark
|
#### Remark
|
||||||
|
|
||||||
In this project, there is little business logic in *Java* code;
|
In this project, there is a large amount of code is in *plsql*, especially for RBAC.
|
||||||
most business code is in *plsql*
|
*Java* ist mostly used for mapping and validating REST calls to database queries.
|
||||||
and *Java* ist mostly used for mapping REST calls to database queries.
|
|
||||||
This mapping ist mostly done through *Spring* annotations and other implicit code.
|
This mapping ist mostly done through *Spring* annotations and other implicit code.
|
||||||
|
|
||||||
Therefore, there are only few unit tests and thus mutation testing has limited value.
|
Therefore, there are only few unit tests and thus mutation testing has limited value.
|
||||||
@ -603,7 +614,8 @@ and would not need the `rbac.role` table anymore.
|
|||||||
We would also reduce the depth of the expensive recursive CTE-query.
|
We would also reduce the depth of the expensive recursive CTE-query.
|
||||||
|
|
||||||
This has to be explored further.
|
This has to be explored further.
|
||||||
For now, we just keep it in mind and
|
For now, we just keep it in mind and FIXME
|
||||||
|
|
||||||
|
|
||||||
### The Mapper is Error-Prone
|
### The Mapper is Error-Prone
|
||||||
|
|
||||||
@ -637,7 +649,7 @@ howto
|
|||||||
Add `--args='--spring.profiles.active=...` with the wanted profile selector:
|
Add `--args='--spring.profiles.active=...` with the wanted profile selector:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
gw bootRun --args='--spring.profiles.active=external-db,only-office,without-test-data'
|
gw bootRun --args='--spring.profiles.active=external-db,only -office,without-test-data'
|
||||||
```
|
```
|
||||||
|
|
||||||
These profiles mean:
|
These profiles mean:
|
||||||
|
35
build.gradle
35
build.gradle
@ -255,16 +255,14 @@ licenseReport {
|
|||||||
}
|
}
|
||||||
project.tasks.check.dependsOn(checkLicense)
|
project.tasks.check.dependsOn(checkLicense)
|
||||||
|
|
||||||
|
// HOWTO: run all tests except import- and scenario-tests: gw test
|
||||||
// HOWTO: run all unit tests: gw test
|
|
||||||
test {
|
test {
|
||||||
finalizedBy jacocoTestReport // generate report after tests
|
finalizedBy jacocoTestReport // generate report after tests
|
||||||
excludes = [
|
excludes = [
|
||||||
'net.hostsharing.hsadminng.**.generated.**',
|
'net.hostsharing.hsadminng.**.generated.**',
|
||||||
]
|
]
|
||||||
useJUnitPlatform {
|
useJUnitPlatform {
|
||||||
excludeTags 'importOfficeData', 'importHostingAssets', 'scenarioTest', 'generalIntegrationTest',
|
excludeTags 'importOfficeData', 'importHostingAssets', 'scenarioTest'
|
||||||
'officeIntegrationTest', 'bookingIntegrationTest', 'hostingIntegrationTest'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,6 +334,19 @@ jacocoTestCoverageVerification {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HOWTO: run all unit-tests which don't need a database: gw unitTest
|
||||||
|
tasks.register('unitTest', Test) {
|
||||||
|
useJUnitPlatform {
|
||||||
|
excludeTags 'importOfficeData', 'importHostingAssets', 'scenarioTest', 'generalIntegrationTest',
|
||||||
|
'officeIntegrationTest', 'bookingIntegrationTest', 'hostingIntegrationTest'
|
||||||
|
}
|
||||||
|
|
||||||
|
group 'verification'
|
||||||
|
description 'runs all unit-tests which do not need a database'
|
||||||
|
|
||||||
|
mustRunAfter spotlessJava
|
||||||
|
}
|
||||||
|
|
||||||
// HOWTO: run all integration tests which are not specific to a module, like base, rbac, config etc.
|
// HOWTO: run all integration tests which are not specific to a module, like base, rbac, config etc.
|
||||||
tasks.register('generalIntegrationTest', Test) {
|
tasks.register('generalIntegrationTest', Test) {
|
||||||
useJUnitPlatform {
|
useJUnitPlatform {
|
||||||
@ -384,18 +395,6 @@ tasks.register('hostingIntegrationTest', Test) {
|
|||||||
mustRunAfter spotlessJava
|
mustRunAfter spotlessJava
|
||||||
}
|
}
|
||||||
|
|
||||||
// HOWTO: run all tests except import- and scenario-tests: gw standardTest
|
|
||||||
tasks.register('standardTest', Test) {
|
|
||||||
useJUnitPlatform {
|
|
||||||
excludeTags 'importOfficeData', 'importHostingAssets', 'scenarioTest'
|
|
||||||
}
|
|
||||||
|
|
||||||
group 'verification'
|
|
||||||
description 'runs all tests except import- and scenario-tests'
|
|
||||||
|
|
||||||
mustRunAfter spotlessJava
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.register('importOfficeData', Test) {
|
tasks.register('importOfficeData', Test) {
|
||||||
useJUnitPlatform {
|
useJUnitPlatform {
|
||||||
includeTags 'importOfficeData'
|
includeTags 'importOfficeData'
|
||||||
@ -418,7 +417,7 @@ tasks.register('importHostingAssets', Test) {
|
|||||||
mustRunAfter spotlessJava
|
mustRunAfter spotlessJava
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register('scenarioTests', Test) {
|
tasks.register('scenarioTest', Test) {
|
||||||
useJUnitPlatform {
|
useJUnitPlatform {
|
||||||
includeTags 'scenarioTest'
|
includeTags 'scenarioTest'
|
||||||
}
|
}
|
||||||
@ -518,7 +517,7 @@ tasks.register('convertMarkdownToHtml') {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
convertMarkdownToHtml.dependsOn scenarioTests
|
convertMarkdownToHtml.dependsOn scenarioTest
|
||||||
|
|
||||||
// shortcut for compiling all files
|
// shortcut for compiling all files
|
||||||
tasks.register('compile') {
|
tasks.register('compile') {
|
||||||
|
@ -5,6 +5,7 @@ import net.hostsharing.hsadminng.mapper.Array;
|
|||||||
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
import net.hostsharing.hsadminng.mapper.StrictMapper;
|
||||||
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
import net.hostsharing.hsadminng.persistence.EntityManagerWrapper;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
|
import org.junit.jupiter.api.Tag;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
@ -19,6 +20,7 @@ import jakarta.servlet.http.HttpServletRequest;
|
|||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@Tag("generalIntegrationTest")
|
||||||
@DataJpaTest
|
@DataJpaTest
|
||||||
@ComponentScan(basePackageClasses = { Context.class, JpaAttempt.class, EntityManagerWrapper.class, StrictMapper.class })
|
@ComponentScan(basePackageClasses = { Context.class, JpaAttempt.class, EntityManagerWrapper.class, StrictMapper.class })
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
|
Loading…
x
Reference in New Issue
Block a user