Skip to content

Commit

Permalink
Parallel Testing and Docker
Browse files Browse the repository at this point in the history
  • Loading branch information
soraiareis committed Aug 3, 2020
1 parent 6363eb1 commit 9e39e35
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 8 deletions.
69 changes: 69 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
- [Authors](#authors)
- [Pre-requisites](#pre-requisites)
- [Libraries](#libraries)
- [Running Tests](#running-tests)
- [Running Through IntelliJ](#running-through-intellij)

## Authors
* [Soraia Reis](https://github.com/soraiareis)
Expand All @@ -23,3 +25,70 @@ You should download and install these properly on your system. Visit the website
* [Cucumber](https://cucumber.io/) - library used to support Behavior-Driven Development (BDD).
* [Selenium WebDriver](https://www.selenium.dev/documentation/en/webdriver/) - drives a browser natively, as a real user would, either locally or on remote machines.
* [Hamcrest](http://hamcrest.org/JavaHamcrest/tutorial) - a framework for writing matcher objects allowing `match` rules to be defined declaratively.

## Running Tests

### Spring Profile
You can run either `default` or `test` profiles. The `default` runs on the URL `https://soraia.herokuapp.com`, and the `test` runs on `http://the-internet.herokuapp.com`.

For the `default` profile you just need to execute Gradle `test` task.
```
./gradlew test
```

To execute the `test` profile the environment variable `SPRING_PROFILES_ACTIVE` should be set. The following command line should be used:
```
SPRING_PROFILES_ACTIVE=test ./gradlew test
```

### Context
You can either run `local` (Firefox is used) or `remote` (in Docker containers). The default value is `remote`, but for `local` execution the `context` property should be set as `local`. However, the `docker-compose` is set as required every time the test task is executed, so passing `context` as `local` will bring up the Docker containers anyway, even though the execution happens locally.
In the command line we pass the following argument:
```
./gradlew test -Dcontext=local
```

### Browser
If we run remotely, we have the option of running in a Firefox or a Chrome browser. The default value is `firefox`, but for `chrome` the `browser` property should be set as `chrome`.
In the command line we pass the following argument:
```
./gradlew test -Dbrowser=chrome
```

### Parallel
The project is configured to run in parallel by default. The default `threads count` for parallel executions are `10`. We can either change the thread count to `1` and execute them sequentially, or even increase the default number if necessary. In the command line we pass the following argument with the `thread count` wanted:
```
./gradlew test -Ddataproviderthreadcount="1"
./gradlew test -Ddataproviderthreadcount="20"
```

### Tags
All the scenarios are executed unless we specify the tag group that we want to execute. In the command line, we pass the following argument with the tag(s):
```
./gradlew test -Dcucumber.filter.tags="@smoke"
```

## Running Through IntelliJ
You can also execute the test scenarios through IntelliJ and there are multiple execution options.

### Locally
In the `application.yml` file change the property `context` to `local`.

* Right-click on the feature file and select `Run 'Feature: login'`; or
* Right-click on the CucumberRunner.java file and select `Run 'CucumberRunner'`.

### Remote (Docker)
In the `application.yml` file make sure the property `context` is `remote`.

Bring the docker containers `up` by executing the command:
```
docker-compose up -d --scale firefox=2 --scale chrome=2
```

* Right-click on the feature file and select `Run 'Feature: login'`; or
* Right-click on the CucumberRunner.java file and select `Run 'CucumberRunner'`.

Bring the docker containers `down` after the test is done by executing the command:
```
docker-compose down
```
12 changes: 11 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ buildscript {
jcenter()
}
dependencies {
classpath 'net.masterthought:cucumber-reporting:5.3.0'
classpath "net.masterthought:cucumber-reporting:5.3.0"
classpath "com.avast.gradle:gradle-docker-compose-plugin:0.13.0"
}
}

Expand All @@ -15,6 +16,8 @@ plugins {
id 'idea'
}

apply plugin: 'docker-compose'

repositories {
jcenter()
}
Expand Down Expand Up @@ -78,3 +81,10 @@ task generateReport() {
}

test.finalizedBy generateReport

dockerCompose.isRequiredBy test

dockerCompose {
useComposeFiles = ['docker-compose.yml']
scale = [firefox: 2, chrome: 2]
}
25 changes: 25 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
version: "3"
services:
selenium-hub:
image: selenium/hub
container_name: selenium-hub
ports:
- "4444:4444"
chrome:
image: selenium/node-chrome
volumes:
- /dev/shm:/dev/shm
depends_on:
- selenium-hub
environment:
- HUB_HOST=selenium-hub
- HUB_PORT=4444
firefox:
image: selenium/node-firefox
volumes:
- /dev/shm:/dev/shm
depends_on:
- selenium-hub
environment:
- HUB_HOST=selenium-hub
- HUB_PORT=4444
6 changes: 6 additions & 0 deletions src/test/java/demo/spring/selenium/CucumberRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
import org.testng.annotations.DataProvider;

@CucumberOptions(
glue = "demo/spring/selenium/stepdefinitions",
Expand All @@ -13,5 +14,10 @@
})
public class CucumberRunner extends AbstractTestNGCucumberTests {

@Override
@DataProvider(parallel = true)
public Object[][] scenarios() {
return super.scenarios();
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,11 @@ public class DemoSpringSeleniumProperties {

@Value("${host}")
private String host;

@Value("${browser}")
private String browser;

@Value("${context}")
private String context;
}

27 changes: 25 additions & 2 deletions src/test/java/demo/spring/selenium/config/WebDriverManager.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,41 @@
package demo.spring.selenium.config;

import java.io.IOException;
import java.net.URL;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
public class WebDriverManager {

private static final String DOCKER_HOST = "http://127.0.0.1";
private static final String SELENIUM_PORT = "4444";
private static final String CHROME = "chrome";
private static final String CONTEXT = "local";

@Autowired
private DemoSpringSeleniumProperties properties;

@Bean
@Scope("cucumber-glue")
public WebDriver webDriverFactory() {
return new FirefoxDriver();
public WebDriver webDriverFactory() throws IOException {
return properties.getContext().equalsIgnoreCase(CONTEXT) ? new FirefoxDriver()
: getRemoteWebDriver(properties.getBrowser());
}

private WebDriver getRemoteWebDriver(String browser) throws IOException {
String remote = String.format("%s:%s/wd/hub", DOCKER_HOST, SELENIUM_PORT);
if (browser.equalsIgnoreCase(CHROME)) {
return new RemoteWebDriver(new URL(remote), new ChromeOptions());
}
return new RemoteWebDriver(new URL(remote), new FirefoxOptions());
}
}

7 changes: 2 additions & 5 deletions src/test/java/demo/spring/selenium/stepdefinitions/Hooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@
@Slf4j
public class Hooks {

@Autowired
private DemoSpringSeleniumProperties properties;
@Autowired private DemoSpringSeleniumProperties properties;

@Autowired
private WebDriver driver;
@Autowired private WebDriver driver;

@Before
public void openBrowser(Scenario scenario) {
Expand All @@ -38,4 +36,3 @@ public void closeBrowser(Scenario scenario) {
log.info("[ENDED] Scenario: " + scenario.getName());
}
}

3 changes: 3 additions & 0 deletions src/test/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
context: remote
browser: firefox

host: https://soraia.herokuapp.com

logging:
Expand Down

0 comments on commit 9e39e35

Please sign in to comment.