From 60332bb563609667c60cb77dd333e32aadb6b45b Mon Sep 17 00:00:00 2001 From: Tian Baoqiang Date: Sun, 9 Apr 2017 03:38:20 -0500 Subject: [PATCH] BAEL-451 (#1610) * BAEL-451 rest api test with JBehave * reformat pom * exclude live test from normal mvn test --- rest-testing/pom.xml | 318 +++++++++--------- .../baeldung/rest/jbehave/AbstractStory.java | 45 +++ .../rest/jbehave/GithubUserNotFoundSteps.java | 59 ++++ .../GithubUserNotFoundStoryLiveTest.java | 18 + .../GithubUserResponseMediaTypeSteps.java | 40 +++ ...hubUserResponseMediaTypeStoryLiveTest.java | 18 + .../GithubUserResponsePayloadSteps.java | 40 +++ ...ithubUserResponsePayloadStoryLiveTest.java | 18 + .../baeldung/rest/jbehave/IncreaseSteps.java | 34 ++ .../rest/jbehave/IncreaseStoryLiveTest.java | 38 +++ .../resources/github_user_not_found.story | 19 ++ .../github_user_response_mediatype.story | 13 + .../github_user_response_payload.story | 12 + .../src/test/resources/increase.story | 15 + 14 files changed, 532 insertions(+), 155 deletions(-) create mode 100644 rest-testing/src/test/java/com/baeldung/rest/jbehave/AbstractStory.java create mode 100644 rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserNotFoundSteps.java create mode 100644 rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserNotFoundStoryLiveTest.java create mode 100644 rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponseMediaTypeSteps.java create mode 100644 rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponseMediaTypeStoryLiveTest.java create mode 100644 rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponsePayloadSteps.java create mode 100644 rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponsePayloadStoryLiveTest.java create mode 100644 rest-testing/src/test/java/com/baeldung/rest/jbehave/IncreaseSteps.java create mode 100644 rest-testing/src/test/java/com/baeldung/rest/jbehave/IncreaseStoryLiveTest.java create mode 100644 rest-testing/src/test/resources/github_user_not_found.story create mode 100644 rest-testing/src/test/resources/github_user_response_mediatype.story create mode 100644 rest-testing/src/test/resources/github_user_response_payload.story create mode 100644 rest-testing/src/test/resources/increase.story diff --git a/rest-testing/pom.xml b/rest-testing/pom.xml index f7f94a49a6..746752133c 100644 --- a/rest-testing/pom.xml +++ b/rest-testing/pom.xml @@ -1,164 +1,171 @@ - 4.0.0 - com.baeldung - rest-testing - 0.1-SNAPSHOT + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + com.baeldung + rest-testing + 0.1-SNAPSHOT - rest-testing + rest-testing - + - + - - com.google.guava - guava - ${guava.version} - + + com.google.guava + guava + ${guava.version} + - - commons-io - commons-io - ${commons-io.version} - + + commons-io + commons-io + ${commons-io.version} + - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + - + - - org.apache.httpcomponents - httpclient - ${httpclient.version} - - - org.apache.httpcomponents - httpcore - ${httpcore.version} - + + org.apache.httpcomponents + httpclient + ${httpclient.version} + + + org.apache.httpcomponents + httpcore + ${httpcore.version} + - + - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + - + - - org.slf4j - slf4j-api - ${org.slf4j.version} - - - ch.qos.logback - logback-classic - ${logback.version} - - - - org.slf4j - jcl-over-slf4j - ${org.slf4j.version} - runtime - - - org.slf4j - log4j-over-slf4j - ${org.slf4j.version} - + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + + org.slf4j + jcl-over-slf4j + ${org.slf4j.version} + runtime + + + org.slf4j + log4j-over-slf4j + ${org.slf4j.version} + - + - - junit - junit - ${junit.version} - test - + + junit + junit + ${junit.version} + test + - - org.hamcrest - hamcrest-core - ${org.hamcrest.version} - test - - - org.hamcrest - hamcrest-library - ${org.hamcrest.version} - test - + + org.hamcrest + hamcrest-core + ${org.hamcrest.version} + test + + + org.hamcrest + hamcrest-library + ${org.hamcrest.version} + test + - - org.mockito - mockito-core - ${mockito.version} - test - - - com.github.tomakehurst - wiremock - ${wiremock.version} - test - + + org.mockito + mockito-core + ${mockito.version} + test + + + com.github.tomakehurst + wiremock + ${wiremock.version} + test + - - info.cukes - cucumber-java - ${cucumber.version} - test - - - info.cukes - cucumber-junit - ${cucumber.version} - - + + info.cukes + cucumber-java + ${cucumber.version} + test + + + info.cukes + cucumber-junit + ${cucumber.version} + - - rest-testing - - - src/main/resources - true - - + + org.jbehave + jbehave-core + ${jbehave.version} + test + + - + + rest-testing + + + src/main/resources + true + + - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - 1.8 - 1.8 - - + - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + **/*IntegrationTest.java **/*LiveTest.java - + - + - + @@ -177,10 +184,10 @@ **/*UnitTest.java + **/*LiveTest.java **/*IntegrationTest.java - **/*LiveTest.java @@ -195,37 +202,38 @@ - - - - 2.8.5 - - 1.7.21 - 1.1.7 + + + 2.8.5 - - 19.0 - 3.5 - 2.5 + + 1.7.21 + 1.1.7 - - 1.3 - 4.12 - 1.10.19 + + 19.0 + 3.5 + 2.5 + + + 1.3 + 4.12 + 1.10.19 2.9.0 1.2.5 2.4.1 - 4.4.5 - 4.5.2 + 4.4.5 + 4.5.2 + 4.1 - - 3.6.0 - 2.6 - 2.19.1 + + 3.6.0 + 2.6 + 2.19.1 - + \ No newline at end of file diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/AbstractStory.java b/rest-testing/src/test/java/com/baeldung/rest/jbehave/AbstractStory.java new file mode 100644 index 0000000000..ce3c98d07e --- /dev/null +++ b/rest-testing/src/test/java/com/baeldung/rest/jbehave/AbstractStory.java @@ -0,0 +1,45 @@ +package com.baeldung.rest.jbehave; + +import org.jbehave.core.configuration.Configuration; +import org.jbehave.core.configuration.MostUsefulConfiguration; +import org.jbehave.core.io.LoadFromClasspath; +import org.jbehave.core.junit.JUnitStories; +import org.jbehave.core.reporters.StoryReporterBuilder; +import org.jbehave.core.steps.InjectableStepsFactory; +import org.jbehave.core.steps.InstanceStepsFactory; + +import java.util.Arrays; +import java.util.List; + +import static org.jbehave.core.io.CodeLocations.codeLocationFromClass; +import static org.jbehave.core.reporters.Format.CONSOLE; + +/** + * @author aiet + */ +public abstract class AbstractStory extends JUnitStories { + + abstract String storyName(); + + @Override + public Configuration configuration() { + return new MostUsefulConfiguration() + .useStoryLoader(new LoadFromClasspath(this.getClass())) + .useStoryReporterBuilder(new StoryReporterBuilder() + .withCodeLocation(codeLocationFromClass(this.getClass())) + .withFormats(CONSOLE)); + } + + abstract Object stepInstance(); + + @Override + public InjectableStepsFactory stepsFactory() { + return new InstanceStepsFactory(configuration(), stepInstance()); + } + + @Override + protected List storyPaths() { + return Arrays.asList(storyName()); + } + +} diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserNotFoundSteps.java b/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserNotFoundSteps.java new file mode 100644 index 0000000000..54d3b0b155 --- /dev/null +++ b/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserNotFoundSteps.java @@ -0,0 +1,59 @@ +package com.baeldung.rest.jbehave; + +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.impl.client.HttpClientBuilder; +import org.jbehave.core.annotations.Given; +import org.jbehave.core.annotations.Then; +import org.jbehave.core.annotations.When; + +import java.io.IOException; + +import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; +import static org.apache.http.HttpStatus.SC_NOT_FOUND; +import static org.junit.Assert.assertTrue; + +public class GithubUserNotFoundSteps { + + private String api; + private String nonExistentUser; + private int githubResponseCode; + + @Given("github user profile api") + public void givenGithubUserProfileApi() { + api = "https://api.github.com/users/%s"; + } + + @Given("a random non-existent username") + public void givenANonexistentUsername() { + nonExistentUser = randomAlphabetic(8); + } + + @When("I look for the random user via the api") + public void whenILookForTheUserViaTheApi() throws IOException { + githubResponseCode = getGithubUserProfile(api, nonExistentUser) + .getStatusLine() + .getStatusCode(); + } + + @When("I look for $user via the api") + public void whenILookForSomeNonExistentUserViaTheApi(String user) throws IOException { + githubResponseCode = getGithubUserProfile(api, user) + .getStatusLine() + .getStatusCode(); + } + + static HttpResponse getGithubUserProfile(String api, String username) throws IOException { + HttpUriRequest request = new HttpGet(String.format(api, username)); + return HttpClientBuilder + .create() + .build() + .execute(request); + } + + @Then("github respond: 404 not found") + public void thenGithubRespond404NotFound() { + assertTrue(SC_NOT_FOUND == githubResponseCode); + } +} diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserNotFoundStoryLiveTest.java b/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserNotFoundStoryLiveTest.java new file mode 100644 index 0000000000..f681fb085a --- /dev/null +++ b/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserNotFoundStoryLiveTest.java @@ -0,0 +1,18 @@ +package com.baeldung.rest.jbehave; + +/** + * @author aiet + */ +public class GithubUserNotFoundStoryLiveTest extends AbstractStory { + + @Override + String storyName() { + return "github_user_not_found.story"; + } + + @Override + Object stepInstance() { + return new GithubUserNotFoundSteps(); + } + +} diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponseMediaTypeSteps.java b/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponseMediaTypeSteps.java new file mode 100644 index 0000000000..a1a9aceee5 --- /dev/null +++ b/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponseMediaTypeSteps.java @@ -0,0 +1,40 @@ +package com.baeldung.rest.jbehave; + +import org.apache.http.entity.ContentType; +import org.jbehave.core.annotations.Given; +import org.jbehave.core.annotations.Then; +import org.jbehave.core.annotations.When; + +import java.io.IOException; + +import static com.baeldung.rest.jbehave.GithubUserNotFoundSteps.getGithubUserProfile; +import static org.junit.Assert.assertEquals; + +public class GithubUserResponseMediaTypeSteps { + + private String api; + private String validUser; + private String mediaType; + + @Given("github user profile api") + public void givenGithubUserProfileApi() { + api = "https://api.github.com/users/%s"; + } + + @Given("a valid username") + public void givenAValidUsername() { + validUser = "eugenp"; + } + + @When("I look for the user via the api") + public void whenILookForTheUserViaTheApi() throws IOException { + mediaType = ContentType + .getOrDefault(getGithubUserProfile(api, validUser).getEntity()) + .getMimeType(); + } + + @Then("github respond data of type json") + public void thenGithubRespondDataOfTypeJson() { + assertEquals("application/json", mediaType); + } +} diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponseMediaTypeStoryLiveTest.java b/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponseMediaTypeStoryLiveTest.java new file mode 100644 index 0000000000..c14f7aad75 --- /dev/null +++ b/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponseMediaTypeStoryLiveTest.java @@ -0,0 +1,18 @@ +package com.baeldung.rest.jbehave; + +/** + * @author aiet + */ +public class GithubUserResponseMediaTypeStoryLiveTest extends AbstractStory { + + @Override + String storyName() { + return "github_user_response_mediatype.story"; + } + + @Override + Object stepInstance() { + return new GithubUserResponseMediaTypeSteps(); + } + +} diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponsePayloadSteps.java b/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponsePayloadSteps.java new file mode 100644 index 0000000000..d9401a5d00 --- /dev/null +++ b/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponsePayloadSteps.java @@ -0,0 +1,40 @@ +package com.baeldung.rest.jbehave; + +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.impl.client.HttpClientBuilder; +import org.baeldung.rest.GitHubUser; +import org.baeldung.rest.RetrieveUtil; +import org.hamcrest.Matchers; +import org.jbehave.core.annotations.Given; +import org.jbehave.core.annotations.Then; +import org.jbehave.core.annotations.When; + +import java.io.IOException; + +import static com.baeldung.rest.jbehave.GithubUserNotFoundSteps.getGithubUserProfile; +import static org.hamcrest.MatcherAssert.assertThat; + +public class GithubUserResponsePayloadSteps { + + private String api; + private GitHubUser resource; + + @Given("github user profile api") + public void givenGithubUserProfileApi() { + api = "https://api.github.com/users/%s"; + } + + @When("I look for $user via the api") + public void whenILookForEugenpViaTheApi(String user) throws IOException { + HttpResponse httpResponse = getGithubUserProfile(api, user); + resource = RetrieveUtil.retrieveResourceFromResponse(httpResponse, GitHubUser.class); + } + + @Then("github's response contains a 'login' payload same as $username") + public void thenGithubsResponseContainsAloginPayloadSameAsEugenp(String username) { + assertThat(username, Matchers.is(resource.getLogin())); + } + +} diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponsePayloadStoryLiveTest.java b/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponsePayloadStoryLiveTest.java new file mode 100644 index 0000000000..cd7974869a --- /dev/null +++ b/rest-testing/src/test/java/com/baeldung/rest/jbehave/GithubUserResponsePayloadStoryLiveTest.java @@ -0,0 +1,18 @@ +package com.baeldung.rest.jbehave; + +/** + * @author aiet + */ +public class GithubUserResponsePayloadStoryLiveTest extends AbstractStory { + + @Override + String storyName() { + return "github_user_response_payload.story"; + } + + @Override + Object stepInstance() { + return new GithubUserResponsePayloadSteps(); + } + +} diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/IncreaseSteps.java b/rest-testing/src/test/java/com/baeldung/rest/jbehave/IncreaseSteps.java new file mode 100644 index 0000000000..3bc6fb2aa2 --- /dev/null +++ b/rest-testing/src/test/java/com/baeldung/rest/jbehave/IncreaseSteps.java @@ -0,0 +1,34 @@ +package com.baeldung.rest.jbehave; + +import org.jbehave.core.annotations.Given; +import org.jbehave.core.annotations.Then; +import org.jbehave.core.annotations.When; + +import java.util.Random; + +import static org.junit.Assert.assertTrue; + +public class IncreaseSteps { + private int counter; + private int previousValue; + + @Given("a counter") + public void aCounter() { + } + + @Given("the counter has any integral value") + public void counterHasAnyIntegralValue() { + counter = new Random().nextInt(); + previousValue = counter; + } + + @When("the user increases the counter") + public void increasesTheCounter() { + counter++; + } + + @Then("the value of the counter must be 1 greater than previous value") + public void theValueOfTheCounterMustBe1Greater() { + assertTrue(1 == counter - previousValue); + } +} diff --git a/rest-testing/src/test/java/com/baeldung/rest/jbehave/IncreaseStoryLiveTest.java b/rest-testing/src/test/java/com/baeldung/rest/jbehave/IncreaseStoryLiveTest.java new file mode 100644 index 0000000000..9033dbfbdc --- /dev/null +++ b/rest-testing/src/test/java/com/baeldung/rest/jbehave/IncreaseStoryLiveTest.java @@ -0,0 +1,38 @@ +package com.baeldung.rest.jbehave; + +import org.jbehave.core.configuration.Configuration; +import org.jbehave.core.configuration.MostUsefulConfiguration; +import org.jbehave.core.io.LoadFromClasspath; +import org.jbehave.core.junit.JUnitStories; +import org.jbehave.core.reporters.StoryReporterBuilder; +import org.jbehave.core.steps.InjectableStepsFactory; +import org.jbehave.core.steps.InstanceStepsFactory; + +import java.util.Arrays; +import java.util.List; + +import static org.jbehave.core.io.CodeLocations.codeLocationFromClass; +import static org.jbehave.core.reporters.Format.CONSOLE; + +public class IncreaseStoryLiveTest extends JUnitStories { + + @Override + public Configuration configuration() { + return new MostUsefulConfiguration() + .useStoryLoader(new LoadFromClasspath(this.getClass())) + .useStoryReporterBuilder(new StoryReporterBuilder() + .withCodeLocation(codeLocationFromClass(this.getClass())) + .withFormats(CONSOLE)); + } + + @Override + public InjectableStepsFactory stepsFactory() { + return new InstanceStepsFactory(configuration(), new IncreaseSteps()); + } + + @Override + protected List storyPaths() { + return Arrays.asList("increase.story"); + } + +} diff --git a/rest-testing/src/test/resources/github_user_not_found.story b/rest-testing/src/test/resources/github_user_not_found.story new file mode 100644 index 0000000000..1ab6920eee --- /dev/null +++ b/rest-testing/src/test/resources/github_user_not_found.story @@ -0,0 +1,19 @@ +Meta: + +Narrative: +As a user +I want to look up a non-existent user's profile on github +So that I can be sure that the username can not be found on github + +Scenario: when a user checks a non-existent user on github, github would respond 'not found' + +Given github user profile api +And a random non-existent username +When I look for the random user via the api +Then github respond: 404 not found + +When I look for eugenp1 via the api +Then github respond: 404 not found + +When I look for eugenp2 via the api +Then github respond: 404 not found diff --git a/rest-testing/src/test/resources/github_user_response_mediatype.story b/rest-testing/src/test/resources/github_user_response_mediatype.story new file mode 100644 index 0000000000..7c4a0b9e2d --- /dev/null +++ b/rest-testing/src/test/resources/github_user_response_mediatype.story @@ -0,0 +1,13 @@ +Meta: + +Narrative: +As a user +I want to look up a valid user's profile on github +So that I can know that github responds data of type json + +Scenario: when a user checks a valid user's profile on github, github would respond json data + +Given github user profile api +And a valid username +When I look for the user via the api +Then github respond data of type json \ No newline at end of file diff --git a/rest-testing/src/test/resources/github_user_response_payload.story b/rest-testing/src/test/resources/github_user_response_payload.story new file mode 100644 index 0000000000..788b43eba6 --- /dev/null +++ b/rest-testing/src/test/resources/github_user_response_payload.story @@ -0,0 +1,12 @@ +Meta: + +Narrative: +As a user +I want to look up a valid user's profile on github +So that I can know the login payload should be the same as username + +Scenario: when a user checks a valid user's profile on github, github's response json should include a login payload with the same username + +Given github user profile api +When I look for eugenp via the api +Then github's response contains a 'login' payload same as eugenp diff --git a/rest-testing/src/test/resources/increase.story b/rest-testing/src/test/resources/increase.story new file mode 100644 index 0000000000..fef91298bc --- /dev/null +++ b/rest-testing/src/test/resources/increase.story @@ -0,0 +1,15 @@ +JBehave Story - An increase test + +Meta: + +Narrative: +As a user +I want to increase a counter +So that I can have the counter's value increase by 1 + +Scenario: when a user increases a counter, its value is increased by 1 + +Given a counter +And the counter has any integral value +When the user increases the counter +Then the value of the counter must be 1 greater than previous value \ No newline at end of file