Skip to content

Commit 3de55c6

Browse files
committed
[Testing][JShellAPI] write documentation about testing approach
1 parent cccd5f1 commit 3de55c6

File tree

1 file changed

+94
-1
lines changed

1 file changed

+94
-1
lines changed

Diff for: JShellAPI/README.MD

+94-1
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,97 @@ The maximum ram allocated per container, in megabytes.
101101
### jshellapi.dockerCPUsUsage
102102
The cpu configuration of each container, see [--cpus option of docker](https://docs.docker.com/config/containers/resource_constraints/#cpu).
103103
### jshellapi.schedulerSessionKillScanRate
104-
The rate at which the session killer will check and delete session, in seconds, see [Session timeout](#Session-timeout).
104+
The rate at which the session killer will check and delete session, in seconds, see [Session timeout](#Session-timeout).
105+
106+
## Testing
107+
108+
> The work on testing was made in collaboration with [Alathreon](https://github.com/Alathreon) and [Wazei](https://github.com/tj-wazei). I'd like thank both of them for their trust. - FirasRG
109+
110+
This section outlines the work done to set up the first integration test that evaluates Java code by running it in a [Docker](https://www.docker.com/get-started/) container. The test ensures that the [Eval endpoint](#eval) can execute code within the containerized environment of [**JShellWrapper**](../JShellWrapper).
111+
112+
### Usage
113+
114+
```java
115+
@ContextConfiguration(classes = Main.class)
116+
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
117+
public class JShellApiTests {
118+
119+
@Autowired
120+
private WebTestClient webTestClient;
121+
122+
@Test
123+
@DisplayName("When posting code snippet, evaluate it then returns successfully result")
124+
public void evaluateCodeSnippetTest() {
125+
126+
final String testEvalId = "test";
127+
128+
final String firstCodeExpression = "int a = 2+2;";
129+
130+
final JShellSnippetResult firstCodeSnippet = new JShellSnippetResult(SnippetStatus.VALID, SnippetType.ADDITION, 1, firstCodeExpression, "4");
131+
132+
final JShellResult firstCodeExpectedResult = getJShellResultDefaultInstance(firstCodeSnippet);
133+
134+
assertThat(testEval(testEvalId, firstCodeExpression)).isEqualTo(firstCodeExpectedResult);
135+
136+
// performing a second code execution test ...
137+
}
138+
// some methods ...
139+
}
140+
```
141+
142+
### 1. Java Test Setup
143+
144+
The [@SpringBootTest](https://docs.spring.io/spring-boot/api/java/org/springframework/boot/test/context/SpringBootTest.html) and [@ContextConfiguration](https://docs.spring.io/spring-framework/reference/testing/annotations/integration-spring/annotation-contextconfiguration.html) annotations are needed to prepare the app to tests, like in a real scenario.
145+
146+
NOTE: _Test classes must be located under `/src/test/java/{org.togetherjava.jshellapi}`._
147+
148+
- The test uses [WebTestClient](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/test/web/reactive/server/WebTestClient.html) to make HTTP calls to the target endpoint.
149+
- Multiple API calls are made within the test method, so a utility instance method was created for reuse.
150+
- The test ensures that code is correctly evaluated inside the **JShellWrapper** container.
151+
152+
### 2. Gradle Configuration for Tests
153+
154+
The `build.gradle` of this project has been updated to handle **JShellWrapper** Docker image lifecycle during tests.
155+
156+
- **JShellWrapper Image Name**: the image name is injected from the root [build.gradle](../build.gradle) file, to this project's [build.gradle](build.gradle) file and also to [application.yaml](src/main/resources/application.yaml)!
157+
- **JShellWrapper Docker Image**: The image is built before the tests run.
158+
- **Container & Cleanup**: After the tests finish, the container and image are removed to ensure a clean environment.
159+
160+
```groovy
161+
def jshellWrapperImageName = rootProject.ext.jShellWrapperImageName;
162+
163+
processResources {
164+
filesMatching('application.yaml') {
165+
expand(jShellWrapperImageName: jshellWrapperImageName)
166+
}
167+
}
168+
169+
def taskBuildDockerImage = tasks.register('buildDockerImage') {
170+
group = 'docker'
171+
description = 'builds jshellwrapper as docker image'
172+
dependsOn project(':JShellWrapper').tasks.named('jibDockerBuild')
173+
}
174+
175+
def taskRemoveDockerImage = tasks.register('removeDockerImage', Exec) {
176+
group = 'docker'
177+
description = 'removes jshellwrapper image'
178+
commandLine 'docker', 'rmi', '-f', jshellWrapperImageName
179+
}
180+
181+
test {
182+
dependsOn taskBuildDockerImage
183+
finalizedBy taskRemoveDockerImage
184+
}
185+
```
186+
187+
Below are the key dependencies that were added or modified in the `build.gradle` file of this project :
188+
189+
```groovy
190+
testImplementation('org.springframework.boot:spring-boot-starter-test') {
191+
exclude group: 'ch.qos.logback', module: 'logback-classic'
192+
}
193+
testImplementation 'org.springframework.boot:spring-boot-starter-webflux'
194+
```
195+
196+
- The `logback-classic` has been excluded because of an issue encountered when running tests. The issue is typically about a conflict between some dependencies (This solution has been brought based on [a _good_ answer on Stackoverflow](https://stackoverflow.com/a/42641450/10000150))
197+
- The `spring-boot-starter-webflux` was needed in order to be able to use **WebTestClient**.

0 commit comments

Comments
 (0)