Skip to content

Latest commit

 

History

History
218 lines (163 loc) · 13.3 KB

Architecture.md

File metadata and controls

218 lines (163 loc) · 13.3 KB

Adobe Ride Logo

Overview

Adobe Ride is a REST API Java test automation framework. It is service-agnostic, modular and extensible, and built on top of industry-standard tools such as Rest-Assured, TestNG, Everit, and Gatling. The goal of the framework is to speed the development of tests and validation of APIs by abstracting repetitive code and standardizing calls for easier functional and end-to-end testing across micro-services

Adobe Ride has already seen heavy use in previous Adobe projects, and the intent is to utilize the experience there, leverage lessons learned, and allow the open-source community to in turn help develop it to make it more robust.

You use Adobe ride by extending it in three primary ways:

  • Extending its model-util to model, rapidly generate, and easily manipulate call payload data.
  • Provide some config information to point your tests at any endpoint that is deployed.
  • Extend the Ride core to easily fire REST calls against your service API and build intensive real-world test cases.

There are additional test options available as well:

  • Use the fuzzer-lib to quickly run tedious negative testing against the nodes in your JSON payload.
  • Use the performance-lib to quickly gather metrics on calls to your service and across services.

Architect/Driver: Ted Casey

Related Links

Document
Main Git Repository
Sample Target Server location - In provisioning
Location in Maven Central
Dependency Repository
Building Ride / Running the Samples
QuickStart
In Depth Ride Usage and Extension Creation
Using the Fuzzer
Using the Performance Library
Using Authentication with Ride

Repositories

When extending Adobe Ride, these settings need to be added to the repository node of your project(s) (or parent project) in order to post your extension to your internal artifact management system.

        <repository>
            <releases>
                <enabled>true</enabled>
                <updatePolicy>never</updatePolicy>
                <checksumPolicy>fail</checksumPolicy>
            </releases>
            <snapshots>
                <enabled>false</enabled>
                <updatePolicy>always</updatePolicy>
                <checksumPolicy>warn</checksumPolicy>
            </snapshots>
            <id>my-releases</id>
            <name>my-releases</name>
            <url>https://your.release.artifact.repository:443/some/path/</url>
        </repository>
        <repository>
            <releases>
                <enabled>false</enabled>
                <updatePolicy>always</updatePolicy>
                <checksumPolicy>warn</checksumPolicy>
            </releases>
            <snapshots>
                <enabled>true</enabled>
                <updatePolicy>never</updatePolicy>
                <checksumPolicy>fail</checksumPolicy>
            </snapshots>
            <id>my-snapshots</id>
            <name>my-snapshots</name>
            <url>https://your.snapshot.artifact.repository:443/some/path//</url>
        </repository>

Settings

Depending on your infrastructure you may need to add a settings.xml file to your local .m2 directory for you to be able to download maven dependencies and build your extension.

Modules

Module NameDescriptionMaven Snippet (snapshot version)
Configuration UtilityDesigned to configure endpoints and users for runs at runtime based on command-line flags
<dependency>
   <groupId>com.adobe.ride</groupId>
   <artifactId>ride-config-util</artifactId>
   <version>0.0.1-SNAPSHOT</version>
</dependency>
Model UtilityConsumes JSON schema for a service and generates valid data for API calls
<dependency>
   <groupId>com.adobe.ride</groupId>
   <artifactId>ride-model-util</artifactId>
   <version>0.0.1-SNAPSHOT</version>
</dependency>
CoreRolls up all of the tedious syntax to make REST API calls through rest-assured and java, speeding development
<dependency>
   <groupId>com.adobe.ride</groupId>
   <artifactId>ride-core</artifactId>
   <version>0.0.1-SNAPSHOT</version>
</dependency>
Fuzzer LibraryWorks in conjunction with the Model Utility to throw arrays of data (including edge and malicious data) at the API and determine what the right response should be
<dependency>
   <groupId>com.adobe.ride</groupId>
   <artifactId>ride-fuzzer-lib</artifactId>
   <version>0.0.1-SNAPSHOT</version>
</dependency>
Performance LibraryScala libary based on Gatling which allows you to place your scala-modified test code in a snippet block and run performance metrics
<dependency>
   <groupId>com.adobe.ride</groupId>
   <artifactId>ride-performance-lib</artifactId>
   <version>0.0.1-SNAPSHOT</version>
</dependency>

Design

Key Concepts

One of Adobe Ride's stated goals is the improved speed of REST API test development. By measuring the number of logical lines of code required to create a given test with and without Ride, we can demonstratively show improvement in this regard. We achieve this through the abstraction of repetitive code. In essence, the more basic the test, the fewer lines of code should be required to write it in the framework. This concept can be then further leveraged through extensibility. By extending the architecture implemented in the core of the framework, even complex but regularly used logical paths can be compressed to fewer lines of code to achieve the same goal through extension. Finally, we create the flexibility of usage through modularity. The architecture is based (like many java projects) on hierarchically in/dependent jars, giving framework extenders options on what to extend.

Abstraction and Optimization

As discussed above one of the main goals of the framework is to reduce the amount of code required to write tests. Below is an example of how this is achieved:

POST Default Service Object in prep for test in Rest-Assured example (partial)

JSONObject json = new JSONObject();

json.put("somekey", "someValue");
// json.put ... a bunch of other node values.

given().
contentType("application/json").
body(json).
expect().
statusCode(201).
  body(is(expectedResponseBody)).
when().
  post("/binaryBody");
  
//There is quite a bit more to define in terms of endpoints, completely define body, specify auth, etc.

POST Default Object in Ride

//create object with all metadata nodes populated with valid values
ServiceObject obj = new ServiceObject(false); 

// post object to server
CoreController.post(obj);

//All of the default config, endpoint specifying, etc. is handled in the core.  JSON data body is generated dynamically (you can change it in the test as desired).

The drastically reduced amount of code required for the test setup, allows the test author to focus on what's important to their tests to the end-user experience.

Structure and Modularity

The framework is modular and hierarchical. You can use any of the components independently, although they do rely on each other, especially when using the core or the components in the "libraries" folder in the framework structure. The diagram below lays out the structure of the architecture and how services can take advantage of it by consuming and extending it.

Ride Flow

The diagram displays the components of the framework housed in the global corporate namespace, how they are built on top of each other, extended by a library within a business unit namespace designed to test a SaaS application within that namespace.

Components and Extensibility

Adobe Ride Components are centralized and contributable through the PR process defined in this same repo. Components:

  • model-util: library which primarily consumes JSON schemas which map to a REST API call body, and generates a message to be used in a test call (explained git readme - link coming)
  • config-util: setup endpoint targeting and test user authorization based on commands given at launch time.
  • core: rolls up all of the rest-assured groovy syntax into simple RestApiController.<method> calls (i.e. RestApiController.put(req, resp) and handles the firing of the call based on the config-util input.
  • fuzzer-lib: exhaustively fuzzes a REST body with negative, edge-case, and malicious (though safe for testing) calls to the service.
  • performance-lib: Scala library based on Gatling which allows you to place your scala-modified test code in snippet block and run performance metrics

Building and Release Versions

Release versions are created as PRs are reviewed and made widely available.

Core Extensions -

When a service REST API comes online, to test it with Adobe Ride, the Core will need to be extended to a service-library. This is done to handle workflows and data specific to that API/Service.

SharedResources

Shared resource is a term used to describe a set of resources you create for your Ride extension project (just like any other resource in a java project), but specifically JSON schema for data modeling and generation, and config files for use in endpoint targeting and test user management. Ideally, your shared-resources resources live in a separate and centralized source repo outside of your extension project, built as a jar, and then used as a dependency for your project (explained in the usage docs). This is so that if, as is common, you are working in an environment creating multiple webservices/APIs, there can be one set of resources that can be used by multiple extensions for an easy end-to-end testing. However, it is just as valid to put these resources in the resources directory of your java project (src/main/resources).

Reporting

Ride relies on TestNG and log4j for the bulk of reporting. However, the use of ReportNG is a work in progress.

Usage

Usage docs can be found here: Usage

TestNG

Because TestNG is built into the framework, the functionality available there is applicable for annotating tests. More information is available here: http://testng.org/doc/

Command Line

The built-in functionality of Maven/failsafe, in addition to the aspects built into Ride, allows for simple execution of run tests as outlined below (from within the test repo root):

mvn clean verify -Dtarget=<configname> -Psmoke

In this case, the value supplied to the -Dtarget flag refers to the "xxx.config" file in your shared resources. It contains all of the information for endpoint targeting. The -Psmoke tag points to whatever information you put in your smoke profile in your maven test project pom. All of this is explained further in the usage docs.

Final Thoughts

After spending some to understand the structure and flow of the Adobe Ride framework, you should find this structure will help guide your automation strategy toward drastically quicker test writing and deployment, much more robust tests, broader coverage, and more easily maintainable end-to-end coverage.

Key Contributors:

Ted Casey, Justin Pettit, Lynn Hook, Steve Larson, Erica Norton, Tommy Zhang, Dumitru Negruta, Mekhala Sampath, Matt Stockbridge

Special Thanks to:

Michelle Dalton, Li Wha Chen, Jianlan Song, Brendan O'Shea, Fazim Mohammed, Nethra Krishnamoorthy