├── python-tdd-singleton
├── tests
│ ├── __init__.py
│ └── my_singleton_test.py
├── requirements.txt
├── singleton
│ ├── __init__.py
│ └── my_singleton.py
└── .gitignore
├── python-requests-graphql
├── tests
│ ├── __init__.py
│ ├── building_queries.py
│ └── basic_examples.py
├── requirements.txt
└── .gitignore
├── python-introduction-to-tavern
├── zippopotamus_api_tests
│ ├── __init__.py
│ └── test_examples.tavern.yaml
└── .gitignore
├── python-requests
├── requirements.txt
├── test_data
│ └── test_data_zip_codes.csv
├── tests
│ ├── 01_basic_tests.py
│ ├── 02_data_driven_tests.py
│ ├── 04_mocking_responses.py
│ └── 03_working_with_xml.py
└── .gitignore
├── golang-resty
├── locationresponse.go
├── .gitignore
├── zippopotamus_api_suite_test.go
└── zippopotamus_api_test.go
├── readable-selenium
├── src
│ └── test
│ │ └── java
│ │ ├── dataentities
│ │ ├── AccountType.java
│ │ ├── DriverType.java
│ │ ├── Account.java
│ │ ├── Credentials.java
│ │ ├── Address.java
│ │ ├── LoanRequest.java
│ │ └── Customer.java
│ │ ├── helpers
│ │ ├── ApiHelpers.java
│ │ ├── DriverHelpers.java
│ │ └── SeleniumHelpers.java
│ │ ├── pages
│ │ ├── RequestLoanResultPage.java
│ │ ├── RegisterCustomerResultPage.java
│ │ ├── AccountsOverviewPage.java
│ │ ├── OpenAccountResultPage.java
│ │ ├── LoginPage.java
│ │ ├── OpenAccountPage.java
│ │ ├── RequestLoanPage.java
│ │ └── RegisterCustomerPage.java
│ │ ├── RegisterCustomerTest.java
│ │ ├── OpenAccountTest.java
│ │ └── RequestLoanTest.java
├── .gitignore
└── pom.xml
├── cucumber-data-tables
├── src
│ └── test
│ │ ├── java
│ │ ├── RunCucumberTest.java
│ │ ├── datatypes
│ │ │ └── Book.java
│ │ └── stepdefinitions
│ │ │ ├── DataTableTypesSteps.java
│ │ │ └── DataTablesSteps.java
│ │ └── resources
│ │ ├── DataTableTypes.feature
│ │ └── DataTables.feature
├── .gitignore
└── pom.xml
└── RestSharpDataDriven
├── RestSharpDataDriven
├── packages.config
├── DataTypes
│ ├── LocationResponse.cs
│ └── Place.cs
├── DataDrivenUsingAttributesTests.cs
├── Properties
│ └── AssemblyInfo.cs
├── DataDrivenUsingTestCaseSourceTests.cs
├── NonDataDrivenTests.cs
└── RestSharpDataDriven.csproj
├── RestSharpDataDriven.sln
└── .gitignore
/python-tdd-singleton/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/python-requests-graphql/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/python-tdd-singleton/requirements.txt:
--------------------------------------------------------------------------------
1 | pytest==5.4.2
--------------------------------------------------------------------------------
/python-introduction-to-tavern/zippopotamus_api_tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/python-tdd-singleton/singleton/__init__.py:
--------------------------------------------------------------------------------
1 | from .my_singleton import MySingleton
2 |
--------------------------------------------------------------------------------
/python-requests-graphql/requirements.txt:
--------------------------------------------------------------------------------
1 | requests==2.25.1
2 | pytest==6.2.2
3 | sgqlc==12.1
--------------------------------------------------------------------------------
/python-requests/requirements.txt:
--------------------------------------------------------------------------------
1 | pytest==5.4.2
2 | requests==2.23.0
3 | responses==0.10.14
--------------------------------------------------------------------------------
/golang-resty/locationresponse.go:
--------------------------------------------------------------------------------
1 | package golang_resty_examples
2 |
3 | type LocationResponse struct {
4 | Country string `json:"country"`
5 | }
6 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/dataentities/AccountType.java:
--------------------------------------------------------------------------------
1 | package dataentities;
2 |
3 | public enum AccountType {
4 | CHECKING,
5 | SAVINGS
6 | }
7 |
--------------------------------------------------------------------------------
/python-requests/test_data/test_data_zip_codes.csv:
--------------------------------------------------------------------------------
1 | country_code,zip_code,expected_place_name
2 | us,90210,Beverly Hills
3 | ca,B2A,North Sydney South Central
4 | it,50123,Firenze
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/dataentities/DriverType.java:
--------------------------------------------------------------------------------
1 | package dataentities;
2 |
3 | public enum DriverType {
4 | CHROME,
5 | FIREFOX,
6 | SAFARI
7 | }
8 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/dataentities/Account.java:
--------------------------------------------------------------------------------
1 | package dataentities;
2 |
3 | import lombok.*;
4 |
5 | @Data
6 | @Builder
7 | @AllArgsConstructor
8 | public class Account {
9 |
10 | private AccountType type;
11 | private int id;
12 | private double balance;
13 |
14 | public Account(){}
15 | }
16 |
--------------------------------------------------------------------------------
/cucumber-data-tables/src/test/java/RunCucumberTest.java:
--------------------------------------------------------------------------------
1 | import io.cucumber.junit.Cucumber;
2 | import io.cucumber.junit.CucumberOptions;
3 | import org.junit.runner.RunWith;
4 |
5 | @RunWith(Cucumber.class)
6 | @CucumberOptions(
7 | plugin = {"pretty"},
8 | features = "src/test/resources")
9 | public class RunCucumberTest {
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/cucumber-data-tables/src/test/java/datatypes/Book.java:
--------------------------------------------------------------------------------
1 | package datatypes;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | @Data
8 | @NoArgsConstructor
9 | @AllArgsConstructor
10 | public class Book {
11 |
12 | private String title;
13 | private String author;
14 | private int yearOfPublishing;
15 | }
16 |
--------------------------------------------------------------------------------
/golang-resty/.gitignore:
--------------------------------------------------------------------------------
1 | # Binaries for programs and plugins
2 | *.exe
3 | *.exe~
4 | *.dll
5 | *.so
6 | *.dylib
7 |
8 | # Test binary, built with `go test -c`
9 | *.test
10 |
11 | # Output of the go coverage tool, specifically when used with LiteIDE
12 | *.out
13 |
14 | # Dependency directories (remove the comment below to include it)
15 | # vendor/
16 |
17 | # Goland stuff
18 | .idea/
--------------------------------------------------------------------------------
/RestSharpDataDriven/RestSharpDataDriven/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/helpers/ApiHelpers.java:
--------------------------------------------------------------------------------
1 | package helpers;
2 |
3 | import static io.restassured.RestAssured.given;
4 |
5 | public class ApiHelpers {
6 |
7 | public static void initializeDatabaseBeforeTest() {
8 |
9 | given().
10 | when().
11 | post("http://parabank.parasoft.com/parabank/services/bank/initializeDB").
12 | then().
13 | assertThat().
14 | statusCode(204);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/dataentities/Credentials.java:
--------------------------------------------------------------------------------
1 | package dataentities;
2 |
3 | import com.github.javafaker.Faker;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 |
8 | import java.util.UUID;
9 |
10 | @Data
11 | @Builder(toBuilder = true)
12 | @AllArgsConstructor
13 | public class Credentials {
14 |
15 | private String username = new Faker().name().username();
16 | private String password = "demo";
17 |
18 | public Credentials(){}
19 | }
20 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/dataentities/Address.java:
--------------------------------------------------------------------------------
1 | package dataentities;
2 |
3 | import com.github.javafaker.Faker;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 |
8 | @Data
9 | @Builder(toBuilder = true)
10 | @AllArgsConstructor
11 | public class Address {
12 |
13 | private String streetAndHouseNumber = new Faker().address().streetAddress();
14 | private String city = new Faker().address().city();
15 | private String state = new Faker().address().state();
16 | private String zipCode = new Faker().address().zipCode();
17 |
18 | public Address(){}
19 | }
20 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/dataentities/LoanRequest.java:
--------------------------------------------------------------------------------
1 | package dataentities;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Builder;
5 | import lombok.Data;
6 |
7 | @Builder
8 | @Data
9 | @AllArgsConstructor
10 | public class LoanRequest {
11 |
12 | private String loanAmount;
13 | private String downPayment;
14 | private String fromAccountId;
15 |
16 | public LoanRequest(){}
17 |
18 | public static LoanRequest createALoanRequestWithSufficientFunds() {
19 |
20 | return LoanRequest.builder().loanAmount("1000").downPayment("100").fromAccountId("54321").build();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/RestSharpDataDriven/RestSharpDataDriven/DataTypes/LocationResponse.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System.Collections.Generic;
3 |
4 | namespace RestSharpDataDriven.DataTypes
5 | {
6 | public class LocationResponse
7 | {
8 | [JsonProperty("post code")]
9 | public string PostCode { get; set; }
10 | [JsonProperty("country")]
11 | public string Country { get; set; }
12 | [JsonProperty("country abbreviation")]
13 | public string CountryAbbreviation { get; set; }
14 | [JsonProperty("places")]
15 | public List Places { get; set; }
16 | }
17 | }
18 |
19 |
20 |
--------------------------------------------------------------------------------
/RestSharpDataDriven/RestSharpDataDriven/DataTypes/Place.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 |
3 | namespace RestSharpDataDriven.DataTypes
4 | {
5 | public class Place
6 | {
7 | [JsonProperty("place name")]
8 | public string PlaceName { get; set; }
9 | [JsonProperty("longitude")]
10 | public string Longitude { get; set; }
11 | [JsonProperty("state")]
12 | public string State { get; set; }
13 | [JsonProperty("state abbreviation")]
14 | public string StateAbbreviation { get; set; }
15 | [JsonProperty("latitude")]
16 | public string Latitude { get; set; }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/python-requests-graphql/tests/building_queries.py:
--------------------------------------------------------------------------------
1 | import requests
2 |
3 | from sgqlc.types import String, Type, Field
4 | from sgqlc.operation import Operation
5 |
6 |
7 | class MissionNode(Type):
8 | id = String
9 | name = String
10 | description = String
11 |
12 |
13 | class Query(Type):
14 | missions = Field(MissionNode)
15 |
16 |
17 | def test_create_graphql_query_programmatically():
18 |
19 | query = Operation(Query)
20 | query.missions()
21 |
22 | response = requests.post("https://api.spacex.land/graphql/", json={'query': str(query)})
23 | assert response.status_code == 200
24 | assert len(response.json()['data']['missions']) == 10
25 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/pages/RequestLoanResultPage.java:
--------------------------------------------------------------------------------
1 | package pages;
2 |
3 | import helpers.SeleniumHelpers;
4 | import org.openqa.selenium.By;
5 | import org.openqa.selenium.WebDriver;
6 |
7 | public class RequestLoanResultPage {
8 |
9 | private WebDriver driver;
10 | private SeleniumHelpers selenium = new SeleniumHelpers();
11 |
12 | private By textfieldApplicationResult = By.id("loanStatus");
13 |
14 | public RequestLoanResultPage(WebDriver driver) {
15 | this.driver = driver;
16 | }
17 |
18 | public String getLoanApplicationResult() {
19 | return selenium.getElementText(driver, textfieldApplicationResult);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/dataentities/Customer.java:
--------------------------------------------------------------------------------
1 | package dataentities;
2 |
3 | import com.github.javafaker.Faker;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 |
8 | @Builder(toBuilder = true)
9 | @Data
10 | @AllArgsConstructor
11 | public class Customer {
12 |
13 | private String firstName = new Faker().name().firstName();
14 | private String lastName = new Faker().name().lastName();
15 | private Address address = new Address().toBuilder().build();
16 | private String phoneNumber = new Faker().phoneNumber().phoneNumber();
17 | private String ssn = new Faker().idNumber().validSvSeSsn();
18 | private Credentials credentials = new Credentials().toBuilder().build();
19 |
20 | public Customer(){}
21 | }
22 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/pages/RegisterCustomerResultPage.java:
--------------------------------------------------------------------------------
1 | package pages;
2 |
3 | import dataentities.Customer;
4 | import helpers.SeleniumHelpers;
5 | import org.openqa.selenium.By;
6 | import org.openqa.selenium.WebDriver;
7 |
8 | public class RegisterCustomerResultPage {
9 |
10 | private WebDriver driver;
11 | private SeleniumHelpers selenium = new SeleniumHelpers();
12 |
13 | private By textlabelConfirmation = By.xpath("//p[text()='Your account was created successfully. You are now logged in.']");
14 |
15 | public RegisterCustomerResultPage(WebDriver driver) {
16 | this.driver = driver;
17 | }
18 |
19 | public boolean registrationConfirmationIsVisible() {
20 | return selenium.isDisplayed(driver, textlabelConfirmation);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/pages/AccountsOverviewPage.java:
--------------------------------------------------------------------------------
1 | package pages;
2 |
3 | import helpers.SeleniumHelpers;
4 | import org.openqa.selenium.By;
5 | import org.openqa.selenium.WebDriver;
6 |
7 | public class AccountsOverviewPage {
8 |
9 | private WebDriver driver;
10 | private SeleniumHelpers selenium = new SeleniumHelpers();
11 |
12 | private By textlabelPageHeader = By.xpath("//h1[text()='Accounts Overview']");
13 |
14 | public AccountsOverviewPage(WebDriver driver) {
15 | this.driver = driver;
16 | }
17 |
18 | public boolean isLoaded() {
19 | return selenium.isDisplayed(driver, textlabelPageHeader);
20 | }
21 |
22 | public void selectMenuItem(String menuItem) {
23 | selenium.click(driver, By.linkText(menuItem));
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/helpers/DriverHelpers.java:
--------------------------------------------------------------------------------
1 | package helpers;
2 |
3 | import dataentities.DriverType;
4 | import org.junit.Assert;
5 | import org.openqa.selenium.WebDriver;
6 | import org.openqa.selenium.chrome.ChromeDriver;
7 |
8 | public class DriverHelpers {
9 |
10 | public static WebDriver createADriverOfType(DriverType driverType) {
11 |
12 | switch(driverType) {
13 | case CHROME:
14 | System.setProperty("webdriver.chrome.driver", "src/test/resources/drivers/chromedriver.exe");
15 | WebDriver driver = new ChromeDriver();
16 | driver.manage().window().maximize();
17 | return driver;
18 | default:
19 | Assert.fail("Unsupported driver type: " + driverType.toString());
20 | return null;
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/pages/OpenAccountResultPage.java:
--------------------------------------------------------------------------------
1 | package pages;
2 |
3 | import dataentities.Account;
4 | import helpers.SeleniumHelpers;
5 | import org.openqa.selenium.By;
6 | import org.openqa.selenium.WebDriver;
7 |
8 | public class OpenAccountResultPage {
9 |
10 | private WebDriver driver;
11 | private SeleniumHelpers selenium = new SeleniumHelpers();
12 |
13 | private By textfieldNewAccountId = By.id("newAccountId");
14 |
15 | public OpenAccountResultPage(WebDriver driver) {
16 | this.driver = driver;
17 | }
18 |
19 | public OpenAccountResultPage load() {
20 | selenium.gotoUrl(driver, "http://parabank.parasoft.com/parabank/openaccount.htm");
21 | return this;
22 | }
23 |
24 | public boolean newAccountIdIsDisplayed() {
25 | return selenium.isDisplayed(driver, textfieldNewAccountId);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/pages/LoginPage.java:
--------------------------------------------------------------------------------
1 | package pages;
2 |
3 | import dataentities.Credentials;
4 | import helpers.SeleniumHelpers;
5 | import org.openqa.selenium.By;
6 | import org.openqa.selenium.WebDriver;
7 |
8 | public class LoginPage {
9 |
10 | private WebDriver driver;
11 | private SeleniumHelpers selenium = new SeleniumHelpers();
12 |
13 | private By textfieldUsername = By.name("username");
14 | private By textfieldPassword = By.name("password");
15 | private By buttonDoLogin = By.xpath("//input[@value='Log In']");
16 |
17 | public LoginPage(WebDriver driver) {
18 | this.driver = driver;
19 | }
20 |
21 | public LoginPage load() {
22 | selenium.gotoUrl(driver,"http://parabank.parasoft.com");
23 | return this;
24 | }
25 |
26 | public void loginUsing(Credentials credentials) {
27 | selenium.sendKeys(driver, textfieldUsername, credentials.getUsername());
28 | selenium.sendKeys(driver, textfieldPassword, credentials.getPassword());
29 | selenium.click(driver, buttonDoLogin);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/RegisterCustomerTest.java:
--------------------------------------------------------------------------------
1 | import dataentities.*;
2 | import helpers.DriverHelpers;
3 | import org.junit.*;
4 | import org.openqa.selenium.WebDriver;
5 | import pages.*;
6 |
7 | import static org.assertj.core.api.Assertions.assertThat;
8 |
9 | public class RegisterCustomerTest {
10 |
11 | private WebDriver driver;
12 |
13 | @Before
14 | public void createBrowser() {
15 |
16 | driver = DriverHelpers.createADriverOfType(DriverType.CHROME);
17 | }
18 |
19 | @Test
20 | public void createCustomer_withValidData_shouldSeeConfirmation() {
21 |
22 | Customer aCustomerWithValidDetails = new Customer().toBuilder().build();
23 |
24 | new RegisterCustomerPage(driver).
25 | load().
26 | register(aCustomerWithValidDetails);
27 |
28 | boolean customerWasRegisteredSuccessfully =
29 | new RegisterCustomerResultPage(driver).registrationConfirmationIsVisible();
30 |
31 | assertThat(customerWasRegisteredSuccessfully).isTrue();
32 | }
33 |
34 | @After
35 | public void closeBrowser() {
36 |
37 | driver.quit();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/pages/OpenAccountPage.java:
--------------------------------------------------------------------------------
1 | package pages;
2 |
3 | import dataentities.Account;
4 | import helpers.SeleniumHelpers;
5 | import org.openqa.selenium.*;
6 |
7 | public class OpenAccountPage {
8 |
9 | private WebDriver driver;
10 | private SeleniumHelpers selenium = new SeleniumHelpers();
11 |
12 | private By dropdownAccountType = By.id("type");
13 | private By dropdownFromAccountId = By.id("fromAccountId");
14 | private By buttonOpenNewAccount = By.xpath("//input[@value='Open New Account']");
15 |
16 | public OpenAccountPage(WebDriver driver) {
17 | this.driver = driver;
18 | }
19 |
20 | public OpenAccountPage load() {
21 | selenium.gotoUrl(driver, "http://parabank.parasoft.com/parabank/openaccount.htm");
22 | return this;
23 | }
24 |
25 | public void open(Account newAccount, Account depositFromAccount) {
26 | selenium.select(driver, dropdownAccountType, newAccount.getType().toString());
27 | selenium.selectWithWait(driver, dropdownFromAccountId, Integer.toString(depositFromAccount.getId()));
28 | selenium.click(driver, buttonOpenNewAccount);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/python-requests/tests/01_basic_tests.py:
--------------------------------------------------------------------------------
1 | import requests
2 |
3 |
4 | def test_get_locations_for_us_90210_check_status_code_equals_200():
5 | response = requests.get("http://api.zippopotam.us/us/90210")
6 | assert response.status_code == 200
7 |
8 |
9 | def test_get_locations_for_us_90210_check_content_type_equals_json():
10 | response = requests.get("http://api.zippopotam.us/us/90210")
11 | assert response.headers['Content-Type'] == "application/json"
12 |
13 |
14 | def test_get_locations_for_us_90210_check_country_equals_united_states():
15 | response = requests.get("http://api.zippopotam.us/us/90210")
16 | response_body = response.json()
17 | assert response_body["country"] == "United States"
18 |
19 |
20 | def test_get_locations_for_us_90210_check_city_equals_beverly_hills():
21 | response = requests.get("http://api.zippopotam.us/us/90210")
22 | response_body = response.json()
23 | assert response_body["places"][0]["place name"] == "Beverly Hills"
24 |
25 |
26 | def test_get_locations_for_us_90210_check_one_place_is_returned():
27 | response = requests.get("http://api.zippopotam.us/us/90210")
28 | response_body = response.json()
29 | assert len(response_body["places"]) == 1
30 |
--------------------------------------------------------------------------------
/cucumber-data-tables/src/test/resources/DataTableTypes.feature:
--------------------------------------------------------------------------------
1 | Feature: Data table types examples
2 | As a Cucumber scholar
3 | I want to learn more about converting data tables to types
4 | So I can process data tables more efficiently
5 |
6 | Scenario: Listing book details
7 | Given the following books
8 | | title | author | yearOfPublishing |
9 | | To kill a mockingbird | Harper Lee | 1960 |
10 | | The catcher in the rye | J.D. Salinger | 1951 |
11 | | The great Gatsby | F. Scott Fitzgerald | 1925 |
12 | | The life of Lazarillo de Tormes | [anonymous] | 1544 |
13 | When I do nothing
14 | Then I expect to have the following books
15 | | title | author | yearOfPublishing |
16 | | The life of Lazarillo de Tormes | [anonymous] | 1544 |
17 | | The great Gatsby | F. Scott Fitzgerald | 1925 |
18 | | To kill a mockingbird | Harper Lee | 1960 |
19 | | The catcher in the rye | J.D. Salinger | 1951 |
20 |
--------------------------------------------------------------------------------
/RestSharpDataDriven/RestSharpDataDriven.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29102.190
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestSharpDataDriven", "RestSharpDataDriven\RestSharpDataDriven.csproj", "{A7D52D92-08F5-49A7-B55D-CE1A4C7AA7D6}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {A7D52D92-08F5-49A7-B55D-CE1A4C7AA7D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {A7D52D92-08F5-49A7-B55D-CE1A4C7AA7D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {A7D52D92-08F5-49A7-B55D-CE1A4C7AA7D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {A7D52D92-08F5-49A7-B55D-CE1A4C7AA7D6}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {06C091D0-F849-4C87-AADD-BF845DE4020D}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/pages/RequestLoanPage.java:
--------------------------------------------------------------------------------
1 | package pages;
2 |
3 | import dataentities.LoanRequest;
4 | import helpers.SeleniumHelpers;
5 | import org.openqa.selenium.By;
6 | import org.openqa.selenium.WebDriver;
7 |
8 | public class RequestLoanPage {
9 |
10 | private WebDriver driver;
11 | private SeleniumHelpers selenium = new SeleniumHelpers();
12 |
13 | private By textfieldLoanAmount = By.id("amount");
14 | private By textfieldDownPayment = By.id("downPayment");
15 | private By dropdownFromAccountId = By.id("fromAccountId");
16 | private By buttonApplyForLoan = By.xpath("//input[@value='Apply Now']");
17 |
18 | public RequestLoanPage(WebDriver driver) {
19 | this.driver = driver;
20 | }
21 |
22 | public RequestLoanPage load() {
23 | selenium.gotoUrl(driver, "http://parabank.parasoft.com/parabank/requestloan.htm");
24 | return this;
25 | }
26 |
27 | public void submit(LoanRequest loanRequest) {
28 | selenium.sendKeys(driver, textfieldLoanAmount, loanRequest.getLoanAmount());
29 | selenium.sendKeys(driver, textfieldDownPayment, loanRequest.getDownPayment());
30 | selenium.select(driver, dropdownFromAccountId, loanRequest.getFromAccountId());
31 | selenium.click(driver, buttonApplyForLoan);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/cucumber-data-tables/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | pom.xml.tag
3 | pom.xml.releaseBackup
4 | pom.xml.versionsBackup
5 | pom.xml.next
6 | release.properties
7 | dependency-reduced-pom.xml
8 | buildNumber.properties
9 | .mvn/timing.properties
10 |
11 | # Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
12 | !/.mvn/wrapper/maven-wrapper.jar
13 |
14 |
15 | .metadata
16 | bin/
17 | tmp/
18 | *.tmp
19 | *.bak
20 | *.swp
21 | *~.nib
22 | local.properties
23 | .settings/
24 | .loadpath
25 | .recommenders
26 | .classpath
27 | .project
28 |
29 | # TestNG reporting
30 | test-output/
31 |
32 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
33 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
34 |
35 | .idea/
36 |
37 | # CMake
38 | cmake-build-debug/
39 |
40 | ## File-based project format:
41 | *.iws
42 |
43 | *.iml
44 |
45 | ## Plugin-specific files:
46 |
47 | # IntelliJ
48 | out/
49 |
50 | # mpeltonen/sbt-idea plugin
51 | .idea_modules/
52 |
53 | # JIRA plugin
54 | atlassian-ide-plugin.xml
55 |
56 | # Cursive Clojure plugin
57 | .idea/replstate.xml
58 |
59 | # Crashlytics plugin (for Android Studio and IntelliJ)
60 | com_crashlytics_export_strings.xml
61 | crashlytics.properties
62 | crashlytics-build.properties
63 | fabric.properties
--------------------------------------------------------------------------------
/readable-selenium/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | pom.xml.tag
3 | pom.xml.releaseBackup
4 | pom.xml.versionsBackup
5 | pom.xml.next
6 | release.properties
7 | dependency-reduced-pom.xml
8 | buildNumber.properties
9 | .mvn/timing.properties
10 |
11 | # Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
12 | !/.mvn/wrapper/maven-wrapper.jar
13 |
14 |
15 | .metadata
16 | bin/
17 | tmp/
18 | *.tmp
19 | *.bak
20 | *.swp
21 | *~.nib
22 | local.properties
23 | .settings/
24 | .loadpath
25 | .recommenders
26 | .classpath
27 | .project
28 |
29 | # TestNG reporting
30 | test-output/
31 |
32 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
33 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
34 |
35 | .idea/
36 |
37 | # CMake
38 | cmake-build-debug/
39 |
40 | ## File-based project format:
41 | *.iws
42 |
43 | *.iml
44 |
45 | ## Plugin-specific files:
46 |
47 | # IntelliJ
48 | out/
49 |
50 | # mpeltonen/sbt-idea plugin
51 | .idea_modules/
52 |
53 | # JIRA plugin
54 | atlassian-ide-plugin.xml
55 |
56 | # Cursive Clojure plugin
57 | .idea/replstate.xml
58 |
59 | # Crashlytics plugin (for Android Studio and IntelliJ)
60 | com_crashlytics_export_strings.xml
61 | crashlytics.properties
62 | crashlytics-build.properties
63 | fabric.properties
64 |
65 | src/test/resources/drivers/
--------------------------------------------------------------------------------
/python-requests/tests/02_data_driven_tests.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import pytest
3 | import csv
4 |
5 | test_data_zip_codes = [
6 | ("us", "90210", "Beverly Hills"),
7 | ("ca", "B2A", "North Sydney South Central"),
8 | ("it", "50123", "Firenze")
9 | ]
10 |
11 |
12 | @pytest.mark.parametrize("country_code, zip_code, expected_place_name", test_data_zip_codes)
13 | def test_using_test_data_object_get_location_data_check_place_name(country_code, zip_code, expected_place_name):
14 | response = requests.get(f"http://api.zippopotam.us/{country_code}/{zip_code}")
15 | response_body = response.json()
16 | assert response_body["places"][0]["place name"] == expected_place_name
17 |
18 |
19 | def read_test_data_from_csv():
20 | test_data = []
21 | with open('test_data/test_data_zip_codes.csv', newline='') as csvfile:
22 | data = csv.reader(csvfile, delimiter=',')
23 | next(data) # skip header row
24 | for row in data:
25 | test_data.append(row)
26 | return test_data
27 |
28 |
29 | @pytest.mark.parametrize("country_code, zip_code, expected_place_name", read_test_data_from_csv())
30 | def test_using_csv_get_location_data_check_place_name(country_code, zip_code, expected_place_name):
31 | response = requests.get(f"http://api.zippopotam.us/{country_code}/{zip_code}")
32 | response_body = response.json()
33 | assert response_body["places"][0]["place name"] == expected_place_name
34 |
--------------------------------------------------------------------------------
/golang-resty/zippopotamus_api_suite_test.go:
--------------------------------------------------------------------------------
1 | package golang_resty_examples
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "github.com/go-resty/resty"
7 | "github.com/stretchr/testify/assert"
8 | "github.com/stretchr/testify/suite"
9 | "testing"
10 | )
11 |
12 | type ZippopotamUsTestSuite struct {
13 | suite.Suite
14 | ApiClient *resty.Client
15 | }
16 |
17 | func (suite *ZippopotamUsTestSuite) SetupTest() {
18 | suite.ApiClient = resty.New()
19 | }
20 |
21 | func (suite *ZippopotamUsTestSuite) Test_GetUs90210_StatusCodeShouldEqual200() {
22 | resp, _ := suite.ApiClient.R().Get("http://api.zippopotam.us/us/90210")
23 |
24 | assert.Equal(suite.T(), 200, resp.StatusCode())
25 | }
26 |
27 | func (suite *ZippopotamUsTestSuite) Test_GetUs90210_ContentTypeShouldEqualApplicationJson() {
28 |
29 | resp, _ := suite.ApiClient.R().Get("http://api.zippopotam.us/us/90210")
30 |
31 | assert.Equal(suite.T(), "application/json", resp.Header().Get("Content-Type"))
32 | }
33 |
34 | func (suite *ZippopotamUsTestSuite) Test_GetUs90210_CountryShouldEqualUnitedStates() {
35 |
36 | resp, _ := suite.ApiClient.R().Get("http://api.zippopotam.us/us/90210")
37 |
38 | myResponse := LocationResponse{}
39 |
40 | err := json.Unmarshal(resp.Body(), &myResponse)
41 |
42 | if err != nil {
43 | fmt.Println(err)
44 | return
45 | }
46 |
47 | assert.Equal(suite.T(), "United States", myResponse.Country)
48 | }
49 |
50 | func TestZippopotamUsSuite(t *testing.T) {
51 | suite.Run(t, new(ZippopotamUsTestSuite))
52 | }
--------------------------------------------------------------------------------
/golang-resty/zippopotamus_api_test.go:
--------------------------------------------------------------------------------
1 | package golang_resty_examples
2 |
3 | import (
4 | "encoding/json"
5 | "fmt"
6 | "github.com/go-resty/resty"
7 | "github.com/stretchr/testify/assert"
8 | "testing"
9 | )
10 |
11 | func Test_GetUs90210_StatusCodeShouldEqual200(t *testing.T) {
12 |
13 | client := resty.New()
14 |
15 | resp, _ := client.R().Get("http://api.zippopotam.us/us/90210")
16 |
17 | assert.Equal(t, 200, resp.StatusCode())
18 | }
19 |
20 | func Test_GetUs90210_StatusCodeShouldEqual200_WithoutAssert(t *testing.T) {
21 |
22 | client := resty.New()
23 |
24 | resp, _ := client.R().Get("http://api.zippopotam.us/us/90210")
25 |
26 | if resp.StatusCode() != 200 {
27 | t.Errorf("Unexpected status code, expected %d, got %d instead", 200, resp.StatusCode())
28 | }
29 | }
30 |
31 | func Test_GetUs90210_ContentTypeShouldEqualApplicationJson(t *testing.T) {
32 |
33 | client := resty.New()
34 |
35 | resp, _ := client.R().Get("http://api.zippopotam.us/us/90210")
36 |
37 | assert.Equal(t, "application/json", resp.Header().Get("Content-Type"))
38 | }
39 |
40 | func Test_GetUs90210_CountryShouldEqualUnitedStates(t *testing.T) {
41 |
42 | client := resty.New()
43 |
44 | resp, _ := client.R().Get("http://api.zippopotam.us/us/90210")
45 |
46 | myResponse := LocationResponse{}
47 |
48 | err := json.Unmarshal(resp.Body(), &myResponse)
49 |
50 | if err != nil {
51 | fmt.Println(err)
52 | return
53 | }
54 |
55 | assert.Equal(t, "United States", myResponse.Country)
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/python-tdd-singleton/singleton/my_singleton.py:
--------------------------------------------------------------------------------
1 | # class MySingleton:
2 | #
3 | # def __init__(self):
4 | # pass
5 |
6 | # -------------------------------------
7 |
8 | # class MySingleton:
9 | #
10 | # def __init__(self, fruit: str):
11 | # self.fruit = fruit
12 |
13 | # -------------------------------------
14 |
15 | # class MySingleton:
16 | #
17 | # instance = None
18 | #
19 | # def __init__(self, fruit: str):
20 | # MySingleton.instance = self
21 |
22 | # -------------------------------------
23 |
24 | # class MySingleton:
25 | #
26 | # instance = None
27 | #
28 | # def __init__(self, fruit: str):
29 | # MySingleton.instance = self
30 | # MySingleton.instance.fruit = fruit
31 |
32 | # -------------------------------------
33 |
34 | # class MySingleton:
35 | #
36 | # instance = None
37 | #
38 | # def __init__(self, fruit: str):
39 | # if self.instance is not None:
40 | # raise RuntimeError('Already instantiated!')
41 | # MySingleton.instance = self
42 | # MySingleton.instance.fruit = fruit
43 |
44 | # ---------------------------------------
45 |
46 | class MySingleton:
47 |
48 | __instance = None
49 |
50 | def __init__(self, fruit: str):
51 | if MySingleton.__instance is not None:
52 | raise RuntimeError('Already instantiated!')
53 | MySingleton.__instance = self
54 | MySingleton.__instance.fruit = fruit
55 |
56 | @classmethod
57 | def instance(cls):
58 | return cls.__instance
59 |
--------------------------------------------------------------------------------
/RestSharpDataDriven/RestSharpDataDriven/DataDrivenUsingAttributesTests.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using RestSharp;
3 | using RestSharp.Serialization.Json;
4 | using RestSharpDataDriven.DataTypes;
5 |
6 | namespace RestSharpDataDriven
7 | {
8 | [TestFixture]
9 | public class DataDrivenUsingAttributesTests
10 | {
11 | private const string BASE_URL = "http://api.zippopotam.us";
12 |
13 | [TestCase("us", "90210", "Beverly Hills", TestName = "Check that US zipcode 90210 yields Beverly Hills")]
14 | [TestCase("us", "12345", "Schenectady", TestName = "Check that US zipcode 12345 yields Schenectady")]
15 | [TestCase("ca", "Y1A", "Whitehorse", TestName = "Check that CA zipcode Y1A yields Whitehorse")]
16 | public void RetrieveDataFor_ShouldYield
17 | (string countryCode, string zipCode, string expectedPlaceName)
18 | {
19 | // arrange
20 | RestClient client = new RestClient(BASE_URL);
21 | RestRequest request =
22 | new RestRequest($"{countryCode}/{zipCode}", Method.GET);
23 |
24 | // act
25 | IRestResponse response = client.Execute(request);
26 | LocationResponse locationResponse =
27 | new JsonDeserializer().
28 | Deserialize(response);
29 |
30 | // assert
31 | Assert.That(
32 | locationResponse.Places[0].PlaceName,
33 | Is.EqualTo(expectedPlaceName)
34 | );
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/python-requests-graphql/tests/basic_examples.py:
--------------------------------------------------------------------------------
1 | import requests
2 |
3 |
4 | query_company_ceo_coo_name = """
5 | {
6 | company {
7 | ceo
8 | coo
9 | name
10 | }
11 | }
12 | """
13 |
14 |
15 | def test_retrieve_graphql_data_should_yield_http_200():
16 | response = requests.post("https://api.spacex.land/graphql/", json={'query': query_company_ceo_coo_name})
17 | assert response.status_code == 200
18 |
19 |
20 | def test_retrieve_graphql_data_should_yield_server_cowboy():
21 | response = requests.post("https://api.spacex.land/graphql/", json={'query': query_company_ceo_coo_name})
22 | assert response.headers['Server'] == 'Cowboy'
23 |
24 |
25 | def test_retrieve_graphql_data_should_yield_encoding_utf8():
26 | response = requests.post("https://api.spacex.land/graphql/", json={'query': query_company_ceo_coo_name})
27 | assert response.encoding == 'utf-8'
28 |
29 |
30 | def test_retrieve_graphql_data_should_yield_ceo_elon_musk():
31 | response = requests.post("https://api.spacex.land/graphql/", json={'query': query_company_ceo_coo_name})
32 | response_body = response.json()
33 | assert response_body['data']['company']['ceo'] == 'Elon Musk'
34 |
35 |
36 | query_missions = """
37 | {
38 | missions {
39 | id
40 | }
41 | }
42 | """
43 |
44 |
45 | def test_retrieve_mission_ids_count_should_be_10():
46 | response = requests.post("https://api.spacex.land/graphql/", json={'query': query_missions})
47 |
48 | response_body = response.json()
49 | assert len(response_body['data']['missions']) == 10
50 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/OpenAccountTest.java:
--------------------------------------------------------------------------------
1 | import dataentities.*;
2 | import helpers.ApiHelpers;
3 | import helpers.DriverHelpers;
4 | import org.junit.*;
5 | import org.openqa.selenium.WebDriver;
6 | import pages.*;
7 |
8 | import static org.assertj.core.api.Assertions.assertThat;
9 |
10 | public class OpenAccountTest {
11 |
12 | private WebDriver driver;
13 |
14 | @Before
15 | public void initializeDatabaseAndLogin() {
16 |
17 | ApiHelpers.initializeDatabaseBeforeTest();
18 |
19 | driver = DriverHelpers.createADriverOfType(DriverType.CHROME);
20 |
21 | Credentials johnsCredentials = Credentials.builder().username("john").password("demo").build();
22 |
23 | new LoginPage(driver).
24 | load().
25 | loginUsing(johnsCredentials);
26 | }
27 |
28 | @Test
29 | public void openAccount_withSufficientFunds_shouldSucceed() {
30 |
31 | Account aNewCheckingAccount =
32 | Account.builder().type(AccountType.CHECKING).build();
33 |
34 | Account depositingFromAccount =
35 | Account.builder().id(12345).build();
36 |
37 | new OpenAccountPage(driver).
38 | load().
39 | open(aNewCheckingAccount, depositingFromAccount);
40 |
41 | boolean newAccountIdIsDisplayed = new OpenAccountResultPage(driver).newAccountIdIsDisplayed();
42 |
43 | assertThat(newAccountIdIsDisplayed).isTrue();
44 | }
45 |
46 | @After
47 | public void closeBrowser() {
48 |
49 | driver.quit();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/RestSharpDataDriven/RestSharpDataDriven/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("RestSharpDataDriven")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("RestSharpDataDriven")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("a7d52d92-08f5-49a7-b55d-ce1a4c7aa7d6")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/cucumber-data-tables/src/test/java/stepdefinitions/DataTableTypesSteps.java:
--------------------------------------------------------------------------------
1 | package stepdefinitions;
2 |
3 | import datatypes.Book;
4 | import io.cucumber.java.DataTableType;
5 | import io.cucumber.java.en.Given;
6 | import io.cucumber.java.en.Then;
7 | import io.cucumber.java.en.When;
8 | import org.junit.Assert;
9 |
10 | import java.util.List;
11 | import java.util.Map;
12 | import org.apache.commons.collections4.CollectionUtils;
13 |
14 | public class DataTableTypesSteps {
15 |
16 | private List actualBooks;
17 |
18 | @DataTableType(replaceWithEmptyString = "[anonymous]")
19 | public Book bookEntryTransformer(Map row) {
20 | return new Book(
21 | row.get("title"),
22 | row.get("author"),
23 | Integer.parseInt(row.get("yearOfPublishing"))
24 | );
25 | }
26 |
27 | @Given("the following books")
28 | public void theFollowingBooks(List books) {
29 |
30 | actualBooks = books;
31 |
32 | for(Book book: actualBooks) {
33 | System.out.printf(
34 | "'%s', published in %d, was written by %s\n",
35 | book.getTitle(),
36 | book.getYearOfPublishing(),
37 | book.getAuthor()
38 | );
39 | }
40 | }
41 |
42 | @When("I do nothing")
43 | public void iDoNothing() {
44 |
45 | }
46 |
47 | @Then("I expect to have the following books")
48 | public void iExpectToHaveTheFollowingBooks(List expectedBooks) {
49 |
50 | Assert.assertTrue(CollectionUtils.isEqualCollection(expectedBooks, actualBooks));
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/python-tdd-singleton/tests/my_singleton_test.py:
--------------------------------------------------------------------------------
1 | from singleton import MySingleton
2 |
3 | import pytest
4 |
5 | # def test_singleton_can_be_instantiated():
6 | # my_singleton = MySingleton()
7 | # assert my_singleton is not None
8 |
9 |
10 | # def test_singleton_can_take_an_argument():
11 | # my_singleton = MySingleton(fruit='banana')
12 | # assert my_singleton.fruit == 'banana'
13 |
14 |
15 | # def test_singleton_instance_is_stored_as_a_class_variable():
16 | # my_singleton = MySingleton(fruit='pear')
17 | # assert my_singleton.instance is not None
18 |
19 |
20 | # def test_singleton_class_variable_exposes_properties():
21 | # my_singleton = MySingleton(fruit='apple')
22 | # assert my_singleton.instance.fruit == 'apple'
23 |
24 |
25 | def test_singleton_cannot_be_instantiated_twice():
26 | MySingleton(fruit='grape')
27 | with pytest.raises(RuntimeError) as re:
28 | MySingleton(fruit='pineapple')
29 | assert str(re.value) == 'Already instantiated!'
30 |
31 |
32 | def test_singleton_retains_initial_property_values_after_subsequent_init_calls():
33 | MySingleton(fruit='lychee')
34 | with pytest.raises(RuntimeError):
35 | MySingleton(fruit='orange')
36 | assert MySingleton.instance().fruit == 'lychee'
37 |
38 |
39 | def test_singleton_instance_is_accessible_using_class_method():
40 | MySingleton(fruit='raspberry')
41 | my_singleton_instance = MySingleton.instance()
42 | assert my_singleton_instance.fruit == 'raspberry'
43 |
44 |
45 | def test_singleton_instance_field_is_not_directly_accessible():
46 | with pytest.raises(AttributeError) as ae:
47 | MySingleton(fruit='peach').__instance
48 | assert str(ae.value) == "'MySingleton' object has no attribute '__instance'"
49 |
--------------------------------------------------------------------------------
/RestSharpDataDriven/RestSharpDataDriven/DataDrivenUsingTestCaseSourceTests.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using RestSharp;
3 | using RestSharp.Serialization.Json;
4 | using RestSharpDataDriven.DataTypes;
5 | using System.Collections.Generic;
6 |
7 | namespace RestSharpDataDriven
8 | {
9 | [TestFixture]
10 | public class DataDrivenUsingTestCaseSourceTests
11 | {
12 | private const string BASE_URL = "http://api.zippopotam.us";
13 |
14 | [Test, TestCaseSource("LocationTestData")]
15 | public void RetrieveDataFor_ShouldYield
16 | (string countryCode, string zipCode, string expectedPlaceName)
17 | {
18 | // arrange
19 | RestClient client = new RestClient(BASE_URL);
20 | RestRequest request =
21 | new RestRequest($"{countryCode}/{zipCode}", Method.GET);
22 |
23 | // act
24 | IRestResponse response = client.Execute(request);
25 | LocationResponse locationResponse =
26 | new JsonDeserializer().
27 | Deserialize(response);
28 |
29 | // assert
30 | Assert.That(
31 | locationResponse.Places[0].PlaceName,
32 | Is.EqualTo(expectedPlaceName)
33 | );
34 | }
35 |
36 | private static IEnumerable LocationTestData()
37 | {
38 | yield return new TestCaseData("us", "90210", "Beverly Hills").
39 | SetName("Check that US zipcode 90210 yields Beverly Hills");
40 | yield return new TestCaseData("us", "12345", "Schenectady").
41 | SetName("Check that US zipcode 12345 yields Schenectady");
42 | yield return new TestCaseData("ca", "Y1A", "Whitehorse").
43 | SetName("Check that CA zipcode Y1A yields Whitehorse");
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/readable-selenium/src/test/java/RequestLoanTest.java:
--------------------------------------------------------------------------------
1 | import dataentities.*;
2 | import helpers.DriverHelpers;
3 | import pages.*;
4 | import org.junit.*;
5 | import org.openqa.selenium.WebDriver;
6 |
7 | import static org.assertj.core.api.Assertions.assertThat;
8 |
9 | public class RequestLoanTest {
10 |
11 | private WebDriver driver;
12 |
13 | @Before
14 | public void createBrowser() {
15 |
16 | driver = DriverHelpers.createADriverOfType(DriverType.CHROME);
17 |
18 | Credentials johnsCredentials = Credentials.builder().username("john").password("demo").build();
19 |
20 | new LoginPage(driver).
21 | load().
22 | loginUsing(johnsCredentials);
23 | }
24 |
25 | @Test
26 | public void requestLoan_withInsufficientFunds_shouldBeDenied() {
27 |
28 | LoanRequest aLoanRequestWithInsufficientFunds =
29 | LoanRequest.builder().loanAmount("10000").downPayment("100").fromAccountId("54321").build();
30 |
31 | new RequestLoanPage(driver).
32 | load().
33 | submit(aLoanRequestWithInsufficientFunds);
34 |
35 | String theDisplayedApplicationResult = new RequestLoanResultPage(driver).getLoanApplicationResult();
36 |
37 | assertThat(theDisplayedApplicationResult).isEqualTo("Denied");
38 | }
39 |
40 | @Test
41 | public void requestLoan_withSufficientFunds_shouldBeApproved() {
42 |
43 | LoanRequest aLoanRequestWithSufficientFunds =
44 | LoanRequest.createALoanRequestWithSufficientFunds();
45 |
46 | new RequestLoanPage(driver).
47 | load().
48 | submit(aLoanRequestWithSufficientFunds);
49 |
50 | String theDisplayedApplicationResult =
51 | new RequestLoanResultPage(driver).getLoanApplicationResult();
52 |
53 | assertThat(theDisplayedApplicationResult).isEqualTo("Approved");
54 | }
55 |
56 | @After
57 | public void closeBrowser() {
58 |
59 | driver.quit();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/python-introduction-to-tavern/zippopotamus_api_tests/test_examples.tavern.yaml:
--------------------------------------------------------------------------------
1 | test_name: Get location for US zip code 90210 and check response status code
2 |
3 | stages:
4 | - name: Check that HTTP status code equals 200
5 | request:
6 | url: http://api.zippopotam.us/us/90210
7 | method: GET
8 | response:
9 | status_code: 200
10 |
11 | ---
12 | test_name: Get location for US zip code 90210 and check response content type
13 |
14 | stages:
15 | - name: Check that content type equals application/json
16 | request:
17 | url: http://api.zippopotam.us/us/90210
18 | method: GET
19 | response:
20 | headers:
21 | content-type: application/json
22 |
23 | ---
24 | test_name: Get location for US zip code 90210 and check response body content
25 |
26 | stages:
27 | - name: Check that place name equals Beverly Hills
28 | request:
29 | url: http://api.zippopotam.us/us/90210
30 | method: GET
31 | response:
32 | body:
33 | places:
34 | - place name: Beverly Hills
35 |
36 | ---
37 | test_name: Check place name for multiple combinations of country code and zip code
38 |
39 | marks:
40 | - parametrize:
41 | key:
42 | - country_code
43 | - zip_code
44 | - place_name
45 | vals:
46 | - [us, 12345, Schenectady]
47 | - [ca, B2A, North Sydney South Central]
48 | - [nl, 3825, Vathorst]
49 |
50 | stages:
51 | - name: Verify place name in response body
52 | request:
53 | url: http://api.zippopotam.us/{country_code}/{zip_code}
54 | method: GET
55 | response:
56 | body:
57 | places:
58 | - place name: "{place_name}"
59 |
60 | ---
61 | test_name: Check response status code for a very simple addition API
62 |
63 | stages:
64 | - name: Verify that status code equals 200 when two integers are specified
65 | request:
66 | url: http://localhost:5000/add
67 | json:
68 | first_number: 5
69 | second_number: 6
70 | method: POST
71 | response:
72 | status_code: 200
--------------------------------------------------------------------------------
/cucumber-data-tables/src/test/resources/DataTables.feature:
--------------------------------------------------------------------------------
1 | Feature: Data table examples
2 | As a Cucumber scholar
3 | I want to learn more about using data tables as arguments
4 | So I can write better executable specifications
5 |
6 | Scenario: Listing football club stadiums - the verbose way
7 | Given Juventus play their home games at Allianz Stadium
8 | And AC Milan play their home games at San Siro
9 | And AS Roma play their home games at Stadio Olimpico
10 |
11 | Scenario: Listing football club stadiums - the clear way
12 | Given the following clubs and their stadiums
13 | | Juventus | Allianz Stadium |
14 | | AC Milan | San Siro |
15 | | AS Roma | Stadio Olimpico |
16 |
17 | Scenario: Listing football squad players - the verbose way
18 | Given Cristiano Ronaldo of Portugal, born on 05-02-1985, plays for Juventus since the 2018/2019 season
19 | And Matthijs de Ligt of the Netherlands, born on 12-08-1999, plays for Juventus since the 2019/2020 season
20 | And Giorgio Chiellini of Italy, born on 14-08-1984, plays for Juventus since the 2005/2006 season
21 |
22 | Scenario: Listing football squad players - the clear way
23 | Given the following Juventus players
24 | | name | nationality | dateOfBirth | atJuventusSince |
25 | | Cristiano Ronaldo | Portugal | 05-02-1985 | 2018/2019 |
26 | | Matthijs de Ligt | the Netherlands | 12-08-1999 | 2019/2020 |
27 | | Giorgio Chiellini | Italy | 14-08-1984 | 2005/2006 |
28 |
29 | Scenario: Listing historic football match results - the verbose way
30 | Given the final score of the Derby d'Italia played on 17-01-2021 was Internazionale 2, Juventus 0
31 | And the final score of the Derby d'Italia played on 08-03-2020 was Internazionale 0, Juventus 2
32 | And the final score of the Derby d'Italia played on 06-10-2019 was Internazionale 1, Juventus 2
33 |
34 | Scenario: Listing historic football match results - the clear way
35 | Given the following historic Derby d'Italia results
36 | | | Internazionale | Juventus |
37 | | 17-01-2021 | 2 | 0 |
38 | | 08-03-2020 | 0 | 2 |
39 | | 06-10-2019 | 1 | 2 |
--------------------------------------------------------------------------------
/python-introduction-to-tavern/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | .hypothesis/
51 | .pytest_cache/
52 |
53 | # Translations
54 | *.mo
55 | *.pot
56 |
57 | # Django stuff:
58 | *.log
59 | local_settings.py
60 | db.sqlite3
61 |
62 | # Flask stuff:
63 | instance/
64 | .webassets-cache
65 |
66 | # Scrapy stuff:
67 | .scrapy
68 |
69 | # Sphinx documentation
70 | docs/_build/
71 |
72 | # PyBuilder
73 | target/
74 |
75 | # Jupyter Notebook
76 | .ipynb_checkpoints
77 |
78 | # IPython
79 | profile_default/
80 | ipython_config.py
81 |
82 | # pyenv
83 | .python-version
84 |
85 | # pipenv
86 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
87 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
88 | # having no cross-platform support, pipenv may install dependencies that don’t work, or not
89 | # install all needed dependencies.
90 | #Pipfile.lock
91 |
92 | # celery beat schedule file
93 | celerybeat-schedule
94 |
95 | # SageMath parsed files
96 | *.sage.py
97 |
98 | # Environments
99 | .env
100 | .venv
101 | env/
102 | venv/
103 | ENV/
104 | env.bak/
105 | venv.bak/
106 |
107 | # Spyder project settings
108 | .spyderproject
109 | .spyproject
110 |
111 | # Rope project settings
112 | .ropeproject
113 |
114 | # mkdocs documentation
115 | /site
116 |
117 | # mypy
118 | .mypy_cache/
119 | .dmypy.json
120 | dmypy.json
121 |
122 | # Pyre type checker
123 | .pyre/
124 |
125 | # PyCharm
126 | .idea/
--------------------------------------------------------------------------------
/python-requests/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # celery beat schedule file
95 | celerybeat-schedule
96 |
97 | # SageMath parsed files
98 | *.sage.py
99 |
100 | # Environments
101 | .env
102 | .venv
103 | env/
104 | venv/
105 | ENV/
106 | env.bak/
107 | venv.bak/
108 |
109 | # Spyder project settings
110 | .spyderproject
111 | .spyproject
112 |
113 | # Rope project settings
114 | .ropeproject
115 |
116 | # mkdocs documentation
117 | /site
118 |
119 | # mypy
120 | .mypy_cache/
121 | .dmypy.json
122 | dmypy.json
123 |
124 | # Pyre type checker
125 | .pyre/
126 |
127 | # PyCharm
128 | .idea/
--------------------------------------------------------------------------------
/python-requests/tests/04_mocking_responses.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import responses
3 | import pytest
4 | import json
5 |
6 | from requests.exceptions import ConnectionError
7 | from urllib.parse import urlparse
8 |
9 |
10 | @responses.activate
11 | def test_simulate_data_cannot_be_found():
12 | responses.add(
13 | responses.GET,
14 | 'http://api.zippopotam.us/us/90210',
15 | json={"error": "No data exists for US zip code 90210"},
16 | status=404
17 | )
18 |
19 | response = requests.get('http://api.zippopotam.us/us/90210')
20 | assert response.status_code == 404
21 | response_body = response.json()
22 | assert response_body['error'] == 'No data exists for US zip code 90210'
23 |
24 |
25 | @responses.activate
26 | def test_unmatched_endpoint_raises_connectionerror():
27 | with pytest.raises(ConnectionError):
28 | requests.get('http://api.zippopotam.us/us/12345')
29 |
30 |
31 | @responses.activate
32 | def test_responses_can_raise_error_on_demand():
33 | responses.add(
34 | responses.GET,
35 | 'http://api.zippopotam.us/us/99999',
36 | body=RuntimeError('A runtime error occurred')
37 | )
38 |
39 | with pytest.raises(RuntimeError) as re:
40 | requests.get('http://api.zippopotam.us/us/99999')
41 | assert str(re.value) == 'A runtime error occurred'
42 |
43 |
44 | @responses.activate
45 | def test_using_a_callback_for_dynamic_responses():
46 |
47 | def request_callback(request):
48 | request_url = request.url
49 | resp_body = {'value': generate_response_from(request_url)}
50 | return 200, {}, json.dumps(resp_body)
51 |
52 | responses.add_callback(
53 | responses.GET, 'http://api.zippopotam.us/us/55555',
54 | callback=request_callback,
55 | content_type='application/json',
56 | )
57 |
58 | response = requests.get('http://api.zippopotam.us/us/55555')
59 | assert response.json() == {'value': 'You requested data for US zip code 55555'}
60 |
61 | assert len(responses.calls) == 1
62 | assert responses.calls[0].request.url == 'http://api.zippopotam.us/us/55555'
63 | assert responses.calls[0].response.text == '{"value": "You requested data for US zip code 55555"}'
64 |
65 |
66 | def generate_response_from(url):
67 | parsed_url = urlparse(url).path
68 | split_url = parsed_url.split('/')
69 | return f'You requested data for {split_url[1].upper()} zip code {split_url[2]}'
70 |
--------------------------------------------------------------------------------
/python-tdd-singleton/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # celery beat schedule file
95 | celerybeat-schedule
96 |
97 | # SageMath parsed files
98 | *.sage.py
99 |
100 | # Environments
101 | .env
102 | .venv
103 | env/
104 | venv/
105 | ENV/
106 | env.bak/
107 | venv.bak/
108 |
109 | # Spyder project settings
110 | .spyderproject
111 | .spyproject
112 |
113 | # Rope project settings
114 | .ropeproject
115 |
116 | # mkdocs documentation
117 | /site
118 |
119 | # mypy
120 | .mypy_cache/
121 | .dmypy.json
122 | dmypy.json
123 |
124 | # Pyre type checker
125 | .pyre/
126 |
127 | # PyCharm
128 | .idea/
--------------------------------------------------------------------------------
/readable-selenium/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.ontestautomation.selenium
8 | ReadableSelenium
9 | 1.0-SNAPSHOT
10 |
11 | 1.8
12 | 1.8
13 | 4.13.1
14 | 3.141.59
15 | 4.2.0
16 | 1.18.12
17 | 3.15.0
18 | 1.0.2
19 |
20 |
21 |
22 | junit
23 | junit
24 | ${junit.version}
25 | test
26 |
27 |
28 | org.seleniumhq.selenium
29 | selenium-java
30 | ${selenium.version}
31 | test
32 |
33 |
34 | io.rest-assured
35 | rest-assured
36 | ${restassured.version}
37 | test
38 |
39 |
40 | org.projectlombok
41 | lombok
42 | ${lombok.version}
43 | test
44 |
45 |
46 | org.assertj
47 | assertj-core
48 | ${assertj.version}
49 | test
50 |
51 |
52 | com.github.javafaker
53 | javafaker
54 | ${javafaker.version}
55 | test
56 |
57 |
58 |
--------------------------------------------------------------------------------
/python-requests-graphql/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # celery beat schedule file
95 | celerybeat-schedule
96 |
97 | # SageMath parsed files
98 | *.sage.py
99 |
100 | # Environments
101 | .env
102 | .venv
103 | env/
104 | venv/
105 | ENV/
106 | env.bak/
107 | venv.bak/
108 |
109 | # Spyder project settings
110 | .spyderproject
111 | .spyproject
112 |
113 | # Rope project settings
114 | .ropeproject
115 |
116 | # mkdocs documentation
117 | /site
118 |
119 | # mypy
120 | .mypy_cache/
121 | .dmypy.json
122 | dmypy.json
123 |
124 | # Pyre type checker
125 | .pyre/
126 |
127 | # PyCharm
128 | .idea/
129 |
130 | # Pytest
131 | pytest.ini
132 |
--------------------------------------------------------------------------------
/cucumber-data-tables/src/test/java/stepdefinitions/DataTablesSteps.java:
--------------------------------------------------------------------------------
1 | package stepdefinitions;
2 |
3 | import io.cucumber.java.en.Given;
4 |
5 | import java.util.List;
6 | import java.util.Map;
7 |
8 | public class DataTablesSteps {
9 |
10 | @Given("^(.*) play their home games at (.*)$")
11 | public void club_play_their_home_games_at_stadium(String club, String stadium) {
12 | System.out.printf("%s play their home games at %s%n", club, stadium);
13 | }
14 |
15 | @Given("the following clubs and their stadiums")
16 | public void the_following_clubs_and_their_stadiums(Map stadiums) {
17 | stadiums.forEach((club, stadium) ->
18 | System.out.printf("%s play their home games at %s%n", club, stadium)
19 | );
20 | }
21 |
22 | @Given("^(.*) of (.*), born on (.*), plays for Juventus since the (.*) season$")
23 | public void name_of_country_born_on_date_plays_for_club_since_the_years_season(String name, String nationality, String dateOfBirth, String firstSeason) {
24 | System.out.printf("%s of %s, born on %s, plays for Juventus since the %s season%n", name, nationality, dateOfBirth, firstSeason);
25 | }
26 |
27 | @Given("the following Juventus players")
28 | public void the_following_juventus_players(List