Skip to content
Permalink
Browse files

Weather example junit + updated docs (#374)

  • Loading branch information...
MykolaGolubyev committed Jul 4, 2019
1 parent 5d3487c commit ed1b0e3cf383ac578572a15aa43c938294aa02de
Showing with 424 additions and 114 deletions.
  1. +1 −0 pom.xml
  2. +1 −1 webtau-docs/pre-filter/{installation.md → installation-groovy-runner.md}
  3. +2 −2 webtau-docs/webtau/REST/documentation.md
  4. +20 −3 webtau-docs/webtau/REST/getting-started.md
  5. +1 −1 webtau-docs/webtau/UI/getting-started.md
  6. +13 −0 webtau-feature-testing/pom.xml
  7. +2 −31 ...eature-testing/src/main/groovy/com/twosigma/webtau/featuretesting/WebTauEndToEndTestRunner.groovy
  8. +67 −0 ...ure-testing/src/main/groovy/com/twosigma/webtau/featuretesting/WebTauEndToEndTestValidator.groovy
  9. +1 −1 ...-testing/src/test/groovy/com/twosigma/webtau/featuretesting/WebTauFeaturesManualTestServer.groovy
  10. +2 −18 ...-feature-testing/src/test/groovy/com/twosigma/webtau/featuretesting/WebTauRestFeaturesTest.groovy
  11. +40 −0 ...ture-testing/src/test/groovy/com/twosigma/webtau/featuretesting/WebTauRestFeaturesTestData.groovy
  12. +1 −1 webtau-http-groovy/src/test/groovy/com/twosigma/webtau/http/HttpGroovyTest.groovy
  13. +1 −1 webtau-http/src/test/java/com/twosigma/webtau/http/HttpTestDataServer.java
  14. +44 −0 webtau-junit-like-examples-common/pom.xml
  15. +17 −3 ...like-examples-common/src/main/java/com/example/tests/junitlike}/cfg/DynamicPortBaseUrlConfig.java
  16. +1 −1 ...es-common/src/main}/resources/META-INF/services/com.twosigma.webtau.http.config.HttpConfiguration
  17. +30 −1 webtau-junit4-examples/pom.xml
  18. +75 −0 webtau-junit4-examples/src/test/groovy/com/example/tests/featuretest/JUnitFeatureTestRunner.groovy
  19. +17 −0 webtau-junit4-examples/src/test/groovy/com/example/tests/junit4/WeatherGroovyIT.groovy
  20. +54 −0 webtau-junit4-examples/src/test/groovy/com/example/tests/junit4/WebTauFeaturesJUnitTest.groovy
  21. +17 −0 webtau-junit4-examples/src/test/java/com/example/tests/junit4/WeatherJavaIT.java
  22. +0 −17 ...4-examples/src/test/resources/META-INF/services/com.twosigma.webtau.http.config.HttpConfiguration
  23. +5 −0 webtau-junit4-examples/test-expectations/WeatherGroovyIT/run-details.json
  24. +5 −0 webtau-junit4-examples/test-expectations/WeatherJavaIT/run-details.json
  25. +7 −0 webtau-junit5-examples/pom.xml
  26. +0 −33 webtau-junit5-examples/src/test/java/com/example/tests/junit5/cfg/DynamicPortBaseUrlConfig.java
@@ -118,6 +118,7 @@
<module>webtau-junit5-examples</module>
<module>webtau-junit4</module>
<module>webtau-junit4-examples</module>
<module>webtau-junit-like-examples-common</module>
<module>webtau-testapp</module>
<module>webtau-config</module>
<module>webtau-feature-testing</module>
@@ -1,4 +1,4 @@
# Installation
# Installation Of Groovy Runner

Download and unzip [webtau](https://repo.maven.apache.org/maven2/com/twosigma/webtau/webtau-dist/${project.version}/webtau-dist-${project.version}-webtau.zip).
Add it to your `PATH`.
@@ -56,9 +56,9 @@ The actual request URL is captured in two forms into two different files:
* `request.fullurl.txt` - contains the full URL
* `request.url.txt` - contains only the part specified in the http call in the scenario

:include-file: doc-artifacts/url-capture/request.url.path.txt {title: "request.url.txt"}
:include-file: doc-artifacts/url-capture/request.url.txt {title: "request.url.txt"}

:include-file: doc-artifacts/url-capture/request.url.full.txt {title: "request.fullurl.txt"}
:include-file: doc-artifacts/url-capture/request.fullurl.txt {title: "request.fullurl.txt"}

# Document REST calls

@@ -1,6 +1,6 @@
:include-markdown: installation.md
:include-markdown: installation-groovy-runner.md

# Bare Minimum
# Minimal Groovy Setup

:include-file: examples/scenarios/rest/simpleGet.groovy {title: "examples/scenarios/rest/simpleGet.groovy"}

@@ -10,10 +10,27 @@ To run test, navigate to `examples` dir and

:include-markdown: common/note-package-import.md

# Config File
## Config File

Url parameter can be moved to a `webtau.cfg` file.

:include-file: examples/scenarios/rest/urlOnly.cfg {title: "examples/scenarios/rest/webtau.cfg"}

[Specify multiple environments](configuration/environments) to streamline test execution.

# Minimal JUnit Setup

```tabs
Groovy: :include-file: maven/groovy-dep.xml {title: "Maven Dependency"}
Java: :include-file: maven/java-dep.xml {title: "Maven Dependency"}
```

```tabs
Groovy:
:include-file: com/example/tests/junit4/WeatherGroovyIT.groovy {title: "JUnit 4 example"}
Java:
:include-file: com/example/tests/junit4/WeatherJavaIT.java {title: "JUnit 4 example"}
```

@@ -1,4 +1,4 @@
:include-markdown: installation.md
:include-markdown: installation-groovy-runner.md

# Bare Minimum

@@ -159,6 +159,19 @@
</systemPropertyVariables>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>jar</goal>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -39,9 +39,6 @@ import java.nio.file.Paths
import static com.twosigma.webtau.cfg.WebTauConfig.getCfg

class WebTauEndToEndTestRunner implements StepReporter, StandaloneTestListener {
private static final String RUN_DETAILS_FILE_NAME = 'run-details'
private static final String EXPECTATIONS_DIR_NAME = 'test-expectations'

private Map capturedStepsSummary
private final List scenariosDetails = []

@@ -99,34 +96,8 @@ class WebTauEndToEndTestRunner implements StepReporter, StandaloneTestListener {
}

private static void validateAndSaveTestDetails(String testFileName, Map testDetails) {
def fileNameWithoutExt = removeExtension(testFileName)
def expectedPath = Paths.get(EXPECTATIONS_DIR_NAME)
.resolve(fileNameWithoutExt).resolve(RUN_DETAILS_FILE_NAME + '.json')
def actualPath = Paths.get(EXPECTATIONS_DIR_NAME)
.resolve(fileNameWithoutExt).resolve(RUN_DETAILS_FILE_NAME + '.actual.json')

def serializedTestDetails = JsonUtils.serializePrettyPrint(sortTestDetailsByContainerId(testDetails))

if (! Files.exists(expectedPath)) {
FileUtils.writeTextContent(expectedPath, serializedTestDetails)

throw new AssertionError('make sure ' + expectedPath + ' is correct. and commit it as a baseline. ' +
'test will not fail next time unless output of the test is changed')
}

def expectedDetails = sortTestDetailsByContainerId(JsonUtils.deserializeAsMap(FileUtils.fileTextContent(expectedPath)))

CompareToComparator comparator = CompareToComparator.comparator()
def isEqual = comparator.compareIsEqual(new ActualPath('testDetails'), testDetails, expectedDetails)

if (! isEqual) {
ConsoleOutputs.out('reports are different, you can use IDE to compare files: ', Color.PURPLE, actualPath,
Color.BLUE, ' and ', Color.PURPLE, expectedPath)
FileUtils.writeTextContent(actualPath, serializedTestDetails)
throw new AssertionError(comparator.generateEqualMismatchReport())
} else {
Files.deleteIfExists(actualPath)
}
WebTauEndToEndTestValidator.validateAndSaveTestDetails(removeExtension(testFileName), testDetails,
this.&sortTestDetailsByContainerId)
}

private static Map sortTestDetailsByContainerId(Map testDetails) {
@@ -0,0 +1,67 @@
/*
* Copyright 2019 TWO SIGMA OPEN SOURCE, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.twosigma.webtau.featuretesting

import com.twosigma.webtau.console.ConsoleOutputs
import com.twosigma.webtau.console.ansi.Color
import com.twosigma.webtau.expectation.ActualPath
import com.twosigma.webtau.expectation.equality.CompareToComparator
import com.twosigma.webtau.utils.FileUtils
import com.twosigma.webtau.utils.JsonUtils

import java.nio.file.Files
import java.nio.file.Paths
import java.util.function.Function

class WebTauEndToEndTestValidator {
private static final String RUN_DETAILS_FILE_NAME = 'run-details'
private static final String EXPECTATIONS_DIR_NAME = 'test-expectations'

private WebTauEndToEndTestValidator() {
}

static void validateAndSaveTestDetails(String testName, Map testDetails, Function resultConverter = { v -> v }) {
def expectedPath = Paths.get(EXPECTATIONS_DIR_NAME)
.resolve(testName).resolve(RUN_DETAILS_FILE_NAME + '.json')
def actualPath = Paths.get(EXPECTATIONS_DIR_NAME)
.resolve(testName).resolve(RUN_DETAILS_FILE_NAME + '.actual.json')

def serializedTestDetails = JsonUtils.serializePrettyPrint(resultConverter.apply(testDetails))

if (! Files.exists(expectedPath)) {
FileUtils.writeTextContent(expectedPath, serializedTestDetails)

throw new AssertionError('make sure ' + expectedPath + ' is correct. and commit it as a baseline. ' +
'test will not fail next time unless output of the test is changed')
}

def expectedDetails = resultConverter.apply(JsonUtils.deserializeAsMap(
FileUtils.fileTextContent(expectedPath)))

CompareToComparator comparator = CompareToComparator.comparator()
def isEqual = comparator.compareIsEqual(new ActualPath('testDetails'), testDetails, expectedDetails)

if (! isEqual) {
ConsoleOutputs.out('reports are different, you can use IDE to compare files: ', Color.PURPLE, actualPath,
Color.BLUE, ' and ', Color.PURPLE, expectedPath)
FileUtils.writeTextContent(actualPath, serializedTestDetails)
throw new AssertionError(comparator.generateEqualMismatchReport())
} else {
Files.deleteIfExists(actualPath)
}
}
}
@@ -26,7 +26,7 @@ class WebTauFeaturesManualTestServer {

WebTauFeaturesManualTestServer() {
testServer = new TestServer()
WebTauRestFeaturesTest.registerEndPoints(testServer)
WebTauRestFeaturesTest.WebTauRestFeaturesTestData.registerEndPoints(testServer)
WebTauUiFeaturesTest.registerEndPoints(testServer)
}

@@ -16,11 +16,7 @@

package com.twosigma.webtau.featuretesting

import com.twosigma.webtau.http.testserver.TestServer
import com.twosigma.webtau.http.testserver.TestServerJsonResponse
import com.twosigma.webtau.http.testserver.TestServerRedirectResponse
import com.twosigma.webtau.http.testserver.TestServerResponse
import com.twosigma.webtau.utils.JsonUtils

import org.junit.AfterClass
import org.junit.BeforeClass
import org.junit.Test
@@ -31,21 +27,13 @@ import static com.twosigma.webtau.featuretesting.FeaturesDocArtifactsExtractor.e
class WebTauRestFeaturesTest {
private static WebTauEndToEndTestRunner testRunner

static void registerEndPoints(TestServer testServer) {
def temperature = [temperature: 88]
testServer.registerGet("/weather", json(temperature))
testServer.registerGet("/redirect", new TestServerRedirectResponse(HttpURLConnection.HTTP_MOVED_TEMP, testServer, "/weather"))
testServer.registerGet("/city/London", json([time: "2018-11-27 13:05:00", weather: temperature]))
testServer.registerPost("/employee", json([id: 'id-generated-2'], 201))
testServer.registerGet("/employee/id-generated-2", json([firstName: 'FN', lastName: 'LN']))
}

@BeforeClass
static void init() {
testRunner = new WebTauEndToEndTestRunner()

def testServer = testRunner.testServer
registerEndPoints(testServer)
WebTauRestFeaturesTestData.registerEndPoints(testServer)

testRunner.startTestServer()
}
@@ -152,10 +140,6 @@ class WebTauRestFeaturesTest {
"scenarios/rest/$configFileName", additionalArgs)
}

private static TestServerResponse json(Map response, statusCode = 200) {
return new TestServerJsonResponse(JsonUtils.serialize(response), statusCode)
}

private void deleteCustomers() {
def ids = http.get(customersUrl()) {
return _embedded.customers.id
@@ -0,0 +1,40 @@
/*
* Copyright 2019 TWO SIGMA OPEN SOURCE, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.twosigma.webtau.featuretesting

import com.twosigma.webtau.http.testserver.TestServer
import com.twosigma.webtau.http.testserver.TestServerJsonResponse
import com.twosigma.webtau.http.testserver.TestServerRedirectResponse
import com.twosigma.webtau.http.testserver.TestServerResponse
import com.twosigma.webtau.utils.JsonUtils

class WebTauRestFeaturesTestData {
static void registerEndPoints(TestServer testServer) {
def temperature = [temperature: 88]
testServer.registerGet("/weather", json(temperature))
testServer.registerGet("/redirect", new TestServerRedirectResponse(HttpURLConnection.HTTP_MOVED_TEMP,
testServer, "/weather"))
testServer.registerGet("/city/London", json([time: "2018-11-27 13:05:00", weather: temperature]))
testServer.registerPost("/employee", json([id: 'id-generated-2'], 201))
testServer.registerGet("/employee/id-generated-2", json([firstName: 'FN', lastName: 'LN']))

}

private static TestServerResponse json(Map response, statusCode = 200) {
return new TestServerJsonResponse(JsonUtils.serialize(response), statusCode)
}
}
@@ -549,7 +549,7 @@ class HttpGroovyTest implements HttpConfiguration {
void "url doc capture includes query params specified as HttpQueryParams"() {
http.get('/params', http.query([a: 1, b: 'text'])) {}

String artifactName = 'url-capture2'
String artifactName = 'url-capture-with-query-params'
http.doc.capture(artifactName)

readAndAssertCapturedFileTextContents(artifactName, 'request.url.txt', '/params?a=1&b=text')
@@ -28,7 +28,7 @@
public class HttpTestDataServer {
private final TestServer testServer;

HttpTestDataServer() {
public HttpTestDataServer() {
testServer = new TestServer();

TestServerJsonResponse objectTestResponse = jsonResponse("objectTestResponse.json");
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2019 TWO SIGMA OPEN SOURCE, LLC
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.twosigma.webtau</groupId>
<artifactId>webtau-parent</artifactId>
<version>1.11-SNAPSHOT</version>
</parent>

<artifactId>webtau-junit-like-examples-common</artifactId>

<dependencies>
<dependency>
<groupId>com.twosigma.webtau</groupId>
<artifactId>webtau-http</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
@@ -14,16 +14,30 @@
* limitations under the License.
*/

package com.example.tests.junit4.cfg;
package com.example.tests.junitlike.cfg;

import com.twosigma.webtau.cfg.WebTauConfig;
import com.twosigma.webtau.http.HttpHeader;
import com.twosigma.webtau.http.config.HttpConfiguration;
import com.twosigma.webtau.utils.UrlUtils;

public class DynamicPortBaseUrlConfig implements HttpConfiguration {

public static final String SPRING_BOOT_EXAMPLE_URL_PREFIX = "/customers";

@Override
public String fullUrl(String url) {
String port = System.getProperty("springboot.http.port", "8080");
return "http://localhost:" + port + url;
if (url.contains("/customers")) {
String port = System.getProperty("springboot.http.port", "8080");
int prefixIdx = url.indexOf(SPRING_BOOT_EXAMPLE_URL_PREFIX);
return "http://localhost:" + port + url.substring(prefixIdx);
}

if (UrlUtils.isFull(url)) {
return url;
}

return UrlUtils.concat(WebTauConfig.getCfg().getBaseUrl(), url);
}

@Override

0 comments on commit ed1b0e3

Please sign in to comment.
You can’t perform that action at this time.