All Projects → sskorol → Test Data Supplier

sskorol / Test Data Supplier

Licence: apache-2.0
Extended TestNG DataProvider

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Test Data Supplier

carina
Carina automation framework: Web, Mobile, API, DB etc testing...
Stars: ✭ 652 (+520.95%)
Mutual labels:  test-automation, testng
Automation Arsenal
Curated list of popular Java and Kotlin frameworks, libraries and tools related to software testing, quality assurance and adjacent processes automation.
Stars: ✭ 105 (+0%)
Mutual labels:  test-automation, qa
pysys-test
PySys System Test Framework
Stars: ✭ 14 (-86.67%)
Mutual labels:  qa, test-automation
SeLite
Automated database-enabled navigation ✔️ of web applications
Stars: ✭ 34 (-67.62%)
Mutual labels:  qa, test-automation
Carina
Carina automation framework: Web, Mobile, API, DB
Stars: ✭ 549 (+422.86%)
Mutual labels:  test-automation, testng
test junkie
Highly configurable testing framework for Python
Stars: ✭ 72 (-31.43%)
Mutual labels:  qa, test-automation
selenified
The Selenified Test Framework provides mechanisms for simply testing applications at multiple tiers while easily integrating into DevOps build environments. Selenified provides traceable reporting for both web and API testing, wraps and extends Selenium calls to more appropriately handle testing errors, and supports testing over multiple browser…
Stars: ✭ 38 (-63.81%)
Mutual labels:  test-automation, testng
MasterSeleniumFramework
Automation Testing | Web | Java | OOPS | Selenium WebDriver | TestNG | Maven | ExtentReport | Allure Reports | Java mail API | Design Patterns (Page Object Model, Singleton) | Jenkins | Data-Driven Testing using JSON file
Stars: ✭ 52 (-50.48%)
Mutual labels:  test-automation, testng
DeepfakeHTTP
DeepfakeHTTP is a web server that uses HTTP dumps as a source for responses.
Stars: ✭ 373 (+255.24%)
Mutual labels:  qa, test-automation
Python-Test-Automation-Framework
Test Automation Framework using selenium and Python
Stars: ✭ 41 (-60.95%)
Mutual labels:  qa, test-automation
Reporting
Zebrunner Reporting Tool
Stars: ✭ 198 (+88.57%)
Mutual labels:  qa, testng
Ghpr.nunit
Adapter for NUnit 3 (generate HTML report for NUnit 3)
Stars: ✭ 33 (-68.57%)
Mutual labels:  test-automation, qa
MasterAppiumFramework
Automation Testing | Mobile | Java | OOPS | Appium | TestNG | Maven | ExtentReport | Java mail API | Logging (Log4J2) | Design Patterns (Page Object Model, Singleton) | Page Factories | Jenkins | Data-Driven Testing using JSON file | Expected Data using XML file
Stars: ✭ 27 (-74.29%)
Mutual labels:  test-automation, testng
request-baskets
HTTP requests collector to test webhooks, notifications, REST clients and more ...
Stars: ✭ 149 (+41.9%)
Mutual labels:  qa, test-automation
Testlogcollectors
A framework for capturing log statements during tests. Compatible with most popular logging frameworks. Works with JUnit and TestNG
Stars: ✭ 31 (-70.48%)
Mutual labels:  test-automation, testng
Mobileautomationframework
Single code base framework to test android and iOS app using appium (v6.1.0), maven, testng,java. Option to start appium server programmatically.
Stars: ✭ 66 (-37.14%)
Mutual labels:  test-automation, testng
Dspot
Automatically detect and generate missing assertions for Junit test cases (also known as test amplification)
Stars: ✭ 83 (-20.95%)
Mutual labels:  test-automation
Cucumberjvmexamples
Cucumber JVM with Selenium Java
Stars: ✭ 98 (-6.67%)
Mutual labels:  test-automation
Testcafe
A Node.js tool to automate end-to-end web testing.
Stars: ✭ 9,176 (+8639.05%)
Mutual labels:  test-automation
Awesome K6
A curated list of resources on automated load- and performance testing using k6 🗻
Stars: ✭ 78 (-25.71%)
Mutual labels:  test-automation

Test Data Supplier

Build Status Quality Gate Code Coverage Maven Central Bintray GitHub license Twitter

This repository contains TestNG DataProvider wrapper (latest version is based on TestNG 7.0.0) which helps to supply test data in a more flexible way.

Common DataProvider forces using quite old and ugly syntax which expects one of the following types to be returned from DP method's body:

  • Object[][]
  • Iterator<Object[]>

That's weird, as developers tend to use Stream and Collection API for data manipulation in the modern Java world.

Just imaging if you could use the following syntax to supply some filtered and sorted data into test method's signature:

@DataSupplier
public Stream<User> getData() {
    return Stream.of(
        new User("Petya", "password2"),
        new User("Virus Petya", "password3"),
        new User("Mark", "password1"))
            .filter(u -> !u.getName().contains("Virus"))
            .sorted(comparing(User::getPassword));
}
    
@Test(dataProvider = "getData")
public void shouldSupplyStreamData(final User user) {
    // ...
}

Much better and flexible than two-dimensional arrays or iterators, isn't it?

And what if we don't want to iterate the same test N times depending on collection size? What if we want to extract its values and inject into test's signature like the following?

@DataSupplier(transpose = true)
public List<User> getExtractedData() {
    return StreamEx.of(
        new User("username1", "password1"),
        new User("username2", "password2"))
            .toList();
}
        
@Test(dataProvider = "getExtractedData")
public void shouldSupplyExtractedListData(final User... users) {
    // ...
}

You can do even more, if you want to perform a Java-like flatMap operation for each row:

@DataSupplier(flatMap = true)
public Map<Integer, String> getInternallyExtractedMapData() {
    return EntryStream.of(asList("user3", "user4")).toMap();
}
    
@Test(dataProvider = "getInternallyExtractedMapData")
public void supplyInternallyExtractedMapData(final Integer key, final String value) {
    // not implemented
}

Supported return types

  • Collection
  • Map
  • Entry
  • Object[]
  • double[]
  • int[]
  • long[]
  • Stream / StreamEx
  • Tuple
  • A single Object of any common or custom type

Usage

Gradle (Java < 9)

Add the following configuration into build.gradle:

repositories {
    jcenter()
}
    
dependencies {
    compile('org.testng:testng:6.14.3',
            'io.github.sskorol:test-data-supplier:1.7.0'
    )
}
    
test {
    useTestNG()
}

Check a separate project with usage examples.

Maven (Java < 9)

Add the following configuration into pom.xml:

<dependencies>
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>6.14.3</version>
    </dependency>
    <dependency>
        <groupId>io.github.sskorol</groupId>
        <artifactId>test-data-supplier</artifactId>
        <version>1.7.0</version>
    </dependency>
</dependencies>
    
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.20.1</version>
        </plugin>
    </plugins>
</build>

Check a separate project with usage examples.

Java 11 support

It's a bit tricky in terms of building and testing modular applications:

plugins {
    id 'java-library'
    id 'java'
}
    
ext {
    moduleName = 'your.module.name'
}
    
sourceCompatibility = JavaVersion.VERSION_11
    
repositories {
    jcenter()
}
    
configurations {
    agent
}
    
dependencies {
    agent 'org.aspectj:aspectjweaver:1.9.5'
    compile 'io.github.sskorol:test-data-supplier:1.9.2'
}
    
compileJava {
    inputs.property("moduleName", moduleName)
    doFirst {
        options.compilerArgs = [
                '--module-path', classpath.asPath
        ]
        classpath = files()
    }
}
   
compileTestJava {
    inputs.property("moduleName", moduleName)
    doFirst {
        options.compilerArgs = [
                '--module-path', classpath.asPath,
                '--patch-module', "$moduleName=" + files(sourceSets.test.java.srcDirs).asPath,
        ]
        classpath = files()
    }
}
   
test {
    useTestNG()
   
    inputs.property("moduleName", moduleName)
    doFirst {
        jvmArgs = [
                "-javaagent:${configurations.agent.singleFile}",
                '--module-path', classpath.asPath,
                '--add-modules', 'ALL-MODULE-PATH',
                '--add-opens', 'your.module.name/test.package.path=org.testng',
                '--add-opens', 'your.module.name/test.package.path=org.jooq.joor',
                '--patch-module', "$moduleName=" + files(sourceSets.test.java.outputDir).asPath
        ]
        classpath = files()
    }
}

Your module-info.java may look like the following:

module your.module.name {
    requires io.github.sskorol.testdatasupplier;
    requires org.testng;
   
    // Optional
    provides io.github.sskorol.core.IAnnotationTransformerInterceptor
        with path.to.transformer.ImplementationClass;
   
    provides io.github.sskorol.core.DataSupplierInterceptor
        with path.to.interceptor.ImplementationClass;
}

API

Instead of a common DataProvider annotation use the following:

@DataSupplier
public T getData() {
    //...
}

DataSupplier supports the following args: name, transpose, flatMap, runInParallel and indices.

You can refer DataSupplier the same way as with TestNG DataProvider:

@Test(dataProvider = "getData")
public void supplyData(final T data) {
    // ...
}
    
// or
    
@Test(dataProviderClass = ExternalDataProvider.class, dataProvider = "getData")
public void supplyExternalData(final T data) {
    // ...
}

Check io.github.sskorol.testcases package for more examples.

JSON, CSV and YAML processors

Test data supplier supports JSON, CSV and YML data retrieval. Assuming you have the following resources:

username,password
"admin","admin"
"sskorol","password"
"guest","123"
[
  {
    "username": "admin",
    "password": "admin"
  },
  {
    "username": "sskorol",
    "password": "password"
  },
  {
    "username": "guest",
    "password": "123"
  }
]
---
 username: admin
 password: admin
---
 username: sskorol
 password: password
---
 username: guest
 password: '123'

You can now map Java entities to these data sources using @Source annotation, which accepts either local file name or URL:

@Data
@Source(path = "users.csv")
public class User {
    @FieldName("username")
    private final String name;
    private final String password;
}
@Data
@Source(path = "users.json")
public class User {
    @SerializedName("username")
    private final String name;
    private final String password;
}
@Data
@NoArgsConstructor
@Source(path = "users.yml")
public class User {
    @JsonProperty("username")
    private final String name;
    private final String password;
}

In case if some Java field's name differs from its data source representation, you can assign a valid name via @FieldName for CSV, @SerializedName for JSON and @JsonProperty for YML data type.

Note that local data sources must be located in a classpath.

Then in DataSupplier you can call special TestDataReader builder to retrieve data from CSV, JSON or YML data source. See javadocs to get more details.

@DataSupplier
public StreamEx<User> getUsers() {
    return use(CsvReader.class).withTarget(User.class).withSource("users.csv").read();
}
@DataSupplier
public StreamEx<User> getUsers() {
    return use(JsonReader.class).withTarget(User.class).withSource("http://users.json").read();
}
@DataSupplier
public StreamEx<User> getUsers() {
    return use(YamlReader.class).withTarget(User.class).read();
}

If you want to specify custom source in runtime, you can remove @Source annotation and use withSource builder method instead.

Note that in case of a data reading error, corresponding test will be skipped.

Factory

You can specify DataSupplier for Factory annotation as well as for common test methods.

@NoArgsConstructor
public class InternalFactoryTests {
    
    @DataSupplier
    public StreamEx getConstructorData() {
        return IntStreamEx.rangeClosed(1, 3).boxed();
    }
    
    @DataSupplier
    public String getTestData() {
        return "data";
    }
    
    @Factory(dataProvider = "getConstructorData", dataProviderClass = InternalFactoryTests.class)
    public InternalFactoryTests(final int index) {
        // not implemented
    }
    
    @Test(dataProvider = "getTestData")
    public void internalFactoryTest(final String data) {
        // not implemented
    }
}

Tracking meta-data

DataSupplierInterceptor interface allows tracking original DataProvider method calls for accessing additional meta-data. You can use the following snippet for getting required info:

public class DataSupplierInterceptorImpl implements DataSupplierInterceptor {
    
    private static final Map<ITestNGMethod, DataSupplierMetaData> META_DATA = new ConcurrentHashMap<>();
    
    @Override
    public void beforeDataPreparation(final ITestContext context, final ITestNGMethod method) {
    }
    
    @Override
    public void afterDataPreparation(final ITestContext context, final ITestNGMethod method) {
    }
    
    @Override
    public void onDataPreparation(final DataSupplierMetaData testMetaData) {
        META_DATA.putIfAbsent(testMetaData.getTestMethod(), testMetaData);
    }
    
    @Override
    public Collection<DataSupplierMetaData> getMetaData() {
        return META_DATA.values();
    }
}

This class should be then loaded via SPI mechanism. Just create META-INF/services folder in resources root, and add a new file io.github.sskorol.core.DataSupplierInterceptor with a full path to implementation class.

IAnnotationTransformer restriction

TestNG restrict users in amount of IAnnotationTransformer implementations. You may have not more than a single transformer within project's scope. As test-data-supplier uses this interface for its internal staff, you won't be able to apply your own implementation.

In case if you still need to add your own IAnnotationTransformer, you have to implement the following interface:

public class IAnnotationTransformerInterceptorImpl implements IAnnotationTransformerInterceptor {

    @Override
    public void transform(IFactoryAnnotation annotation, Method testMethod) {
    }

    @Override
    public void transform(IConfigurationAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
    }

    @Override
    public void transform(IDataProviderAnnotation annotation, Method method) {
    }

    @Override
    public void transform(IListenersAnnotation annotation, Class testClass) {
    }
}

It's just an SPI wrapper for common TestNG mechanism. Use the same technique as for DataSupplierInterceptor to include it into your project.

Note that in case if you want to manage DataProviderTransformer manually, you have to use a special spi-off distribution:

dependencies {
    compile 'io.github.sskorol:test-data-supplier:1.9.1:spi-off'
}

IntelliJ IDEA support

Test Data Supplier is integrated with IntelliJ IDEA in a form of plugin. Just install test-data-supplier-plugin from the official JetBrains repository.

More information about its features could be found on the related GitHub page.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].