• Stars
    star
    115
  • Rank 305,916 (Top 7 %)
  • Language
    Java
  • License
    Apache License 2.0
  • Created over 7 years ago
  • Updated 6 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Maven plugin that simplifies running Cucumber scenarios in parallel.

Apache V2 License Maven Central Mastodon Follow

cucable logo

Run Cucumber Scenarios in Parallel with Maven

Cucumber compatible

Cucable Maven Plugin

Cucable is a Maven plugin for Cucumber scenarios that simplifies fine-grained and efficient parallel test runs.

This plugin does the following:

  • Generate single Cucumber features containing one single scenario each (scenario outlines are also split up into separate scenarios)
  • Generating Cucumber runners
    • for every generated "single scenario" feature file or
    • for multiple generated "single scenario" feature files

Those generated runners and features can then be used with Maven Failsafe in order to parallelize test runs.

This also works for non-english feature files!

Cucumber 4

Even though Cucumber 4 supports basic parallel runs, Cucable has more options that may be beneficial for your use case:

  • It supports running single scenarios, complete features or sequences of single scenarios in parallel
  • It supports splitting scenarios and attaching them to a fixed number of runners
  • It supports splitting scenarios and attaching batches of them to a dynamic number of runners
  • You don't need any test framework changes because Cucable runs before the framework invocations
  • You have full control over your runners because of template variables and custom placeholders

Cucumber 5 and higher

  • Cucumber starting with version 5 (using testng or junit 5) can natively run features and scenarios in parallel. Cucable can be used but does not have to be.

Repository Structure

  • plugin-code contains the full plugin source code.
  • example-project contains an example Maven project to see the plugin in action.

Changelog

All changes are documented in the full changelog.

Maven dependency

<dependency>
    <groupId>com.trivago.rta</groupId>
    <artifactId>cucable-plugin</artifactId>
    <version>(check version on top of the page)</version>
</dependency>

How it works

  • Cucable will cut up feature file into the smallest possible runnable scenarios
  • Each generated feature file includes a single scenario
  • After this, the runner classes for those generated features are generated based on a provided template file, either
    • one runner per generated "single scenario" feature file or
    • one runner per group of "single scenario" feature files

Template placeholders

[CUCABLE:RUNNER]

The [CUCABLE:RUNNER] template placeholder is automatically replaced with the class name of the generated runner class.

If the generated runner runs only one "single scenario" feature, its name will be the same as the generated feature (e.g. Runner_MyFeature_scenario001_run001_IT).

In case the runner runs multiple "single scenario" features, its name will be auto-generated (e.g. CucableMultiRunner_1da810a2_c4c6_4edb_b078_d81329593950_IT).

[CUCABLE:FEATURE]

The [CUCABLE:FEATURE] can be placed in the feature option of the @CucumberOptions block in your template:

@CucumberOptions(
  features = {"target/parallel/features/[CUCABLE:FEATURE].feature"}
)

Cucable will automatically detect the string containing the [CUCABLE:FEATURE] placeholder and use this to generate one line for each feature this runner should trigger.

Custom template placeholders - [CUCABLE:CUSTOM:xxx]

In some cases, you may need to set custom values that should be written to your template files.

In this case, just add a block to your POM file:

<customPlaceholders>
    <somename>Any value</somename>
    <foo>bar</foo>
</customPlaceholders>

These custom placeholders can be used anywhere in your template:

import cucumber.api.CucumberOptions;

@CucumberOptions(
        features = {"target/parallel/features/[CUCABLE:FEATURE].feature"},
        plugin = {"json:target/cucumber-report/[CUCABLE:CUSTOM:foo].json"}
)
public class [CUCABLE:RUNNER] {
    // [CUCABLE:CUSTOM:somename]
}

In this case the result would be

import cucumber.api.CucumberOptions;

@CucumberOptions(
        features = {"target/parallel/features/[CUCABLE:FEATURE].feature"},
        plugin = {"json:target/cucumber-report/bar.json"}
)
public class [CUCABLE:RUNNER] {
    // Any value
}

Note: The custom placeholder names are case sensitive!

One runner per generated scenario

This is the default mode of Cucable. Having multiple runners that run one "single scenario" feature each is best for parallelization with Maven Failsafe.

Single feature runner generation

One runner per group of generated scenarios

If you use the desiredNumberOfRunners or desiredNumberOfFeaturesPerRunner option, Cucable will automatically switch to the multi-feature runner mode.

This means that it will only generate the specified number of runners (or features per runner) and distribute the generated features evenly among the runners. This is helpful if a group of scenarios should be executed during each forked run of your test framework.

Note: If a runner runs only one feature, it automatically has the same name as the feature. Otherwise it will have a unique auto-generated name.

Multi feature runner generation

Typical workflow

  1. Generation of runners and features
  2. Running the generated tests with Maven Failsafe
  3. Aggregation of a single test report after all test runs

The following sections break down the above steps.

1. Generation of runners and features

<plugin>
    <groupId>com.trivago.rta</groupId>
    <artifactId>cucable-plugin</artifactId>
    <version>${cucable-plugin.version}</version>
    <executions>
        <execution>
            <id>generate-test-resources</id>
            <phase>generate-test-resources</phase>
            <goals>
                <goal>parallel</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <!-- Required properties -->
        <sourceRunnerTemplateFile>src/test/resources/parallel/cucable.template</sourceRunnerTemplateFile>
        <sourceFeatures>src/test/resources/features</sourceFeatures>
        <generatedFeatureDirectory>src/test/resources/parallel/features</generatedFeatureDirectory>
        <generatedRunnerDirectory>src/test/java/parallel/runners</generatedRunnerDirectory>
        
        <!-- Optional properties -->
        <numberOfTestRuns>1</numberOfTestRuns>
        <includeScenarioTags>@includeMe and @includeMeAsWell</includeScenarioTags>                                
        <logLevel>compact</logLevel>
        
        <desiredNumberOfRunners>2</desiredNumberOfRunners>                                
        <!-- or <desiredNumberOfFeaturesPerRunner>5</desiredNumberOfRunners> -->
    </configuration>    
</plugin>

Required Parameters

sourceRunnerTemplateFile

The specified file will be used to generate runner classes for the generated feature file that can be run using Maven Failsafe.

This can be either a text file or a Java class. The difference can be seen below:

Using a java file as a runner template

If you use a java file (e.g. src/test/java/some/template/CucableJavaTemplate.java), the [CUCABLE:FEATURE] placeholder as well as the class name will be substituted for the generated feature file name(s). The [CUCABLE:RUNNER] placeholder will be replaced by the runner class name.

Additionally, the package declaration will be stripped.

Example:

package some.template;

import cucumber.api.CucumberOptions;

@CucumberOptions(
        features = {"target/parallel/features/[CUCABLE:FEATURE].feature"},
        plugin = {"json:target/cucumber-report/[CUCABLE:RUNNER].json"}
)
public class CucableJavaTemplate {

}

will turn into

import cucumber.api.CucumberOptions;

@CucumberOptions(
        features = {"target/parallel/features/MyFeature_scenario001_run001_IT.feature"},
        plugin = {"json:target/cucumber-report/MyFeature_scenario001_run001_IT.json"}
)
public class MyFeature_scenario001_run001_IT {
}

// Generated by Cucable from src/test/java/some/template/CucableJavaTemplate.java

In case of a fixed number of runners that contain multiple scenarios (via desiredNumberOfRunners property), the runner name will be auto-generated:

import cucumber.api.junit.Cucumber;
import cucumber.api.CucumberOptions;
import org.junit.runner.RunWith;

@RunWith(Cucumber.class)
@CucumberOptions(
    features = {"target/parallel/features/Bookmarks_scenario001_run001_IT.feature",
"target/parallel/features/Bookmarks_scenario003_run001_IT.feature"},
    plugin = {
        "json:target/cucumber-report/CucableMultiRunner_1da810a2_c4c6_4edb_b078_d81329593950_IT.json",
        "com.trivago.trupi.plugin.TrupiCucumberPlugin"
    },
    glue = {"com.trivago.trupi.glue"}
)
public class CucableMultiRunner_1da810a2_c4c6_4edb_b078_d81329593950_IT {
}

// Generated by Cucable from src/test/java/some/template/CucableJavaTemplate.java
Using a text file as a runner template

If you use a text file (e.g. src/test/resources/cucable.template), all [CUCABLE:FEATURE] placeholder will be substituted for the generated feature file name(s). The [CUCABLE:RUNNER] placeholder will be replaced by the runner class name.

sourceFeatures

This property specifies the location of the features that Cucable should process. It must point to one or more of the following:

  • the root path of your existing Cucumber .feature files, e.g. src/test/resources/features

  • the path to a specific existing Cucumber .feature file, e.g. src/test/resources/features/MyFeature.feature

  • the path to a specific existing Cucumber .feature file with optional line numbers of specific scenarios e.g. src/test/resources/features/MyFeature.feature:12:19

  • the path to a Cucumber text file containing the path to a feature including line number(s) per line (as written by the Cucumber rerun reporter plugin, e.g.

    @src/test/resources/rerun.txt
    

    Note: The path to a text file has to start with an @ character!

    The file contents can look like this:

    file:///pathToProject/resources/features/feature1.feature:12
    file:///pathToProject/resources/features/feature4.feature:6
    
  • the root path of your existing Cucumber text files (also starting with an @), e.g.

    @src/test/resources
    

Combining different feature sources

Starting from Cucumber 1.10.0, you can use any combination of sources by separating them with commas, e.g.

<sourceFeatures>src/test/resources/features, @src/test/rerun.txt</sourceFeatures>

This example would use all .feature files in src/test/resources/features plus all features that are defined in src/test/rerun.txt!

Note: You need to be careful when selecting multiple sources as the same feature could be generated multiple times if it appears in more than one source.

generatedFeatureDirectory

The path where the generated Cucumber .feature files should be located (e.g. src/test/resources/parallel).

Additionally, a file called generated-features.properties will be generated there that shows all generated features along with their reference to the respective source feature.

Note: This directory should be located under a valid resource folder to be included as a test source by Maven. If you want to use a directory inside Maven's target folder, check this example.

Caution: This directory will be wiped prior to the feature file generation!

generatedRunnerDirectory

The path where the generated runner classes should be located (e.g. src/test/java/parallel/runners).

Note: This directory should be located under a valid source folder to be included as a test source by Maven. If you want to use a directory inside Maven's target folder, check this example.

Caution: This directory will be wiped prior to the runner file generation!

Optional Parameters

numberOfTestRuns

Optional number of test runs. This can be used if specific scenarios should be run multiple times. If this options is not set, its default value is 1.

For each test run, the whole set of features and runners is generated like this:

  • MyFeature_scenario001_run001_IT.feature
  • MyFeature_scenario001_run002_IT.feature
  • MyFeature_scenario001_run003_IT.feature
  • etc.

Note: Characters other than letters from A to Z, numbers and underscores will be stripped out of the feature file name.

includeScenarioTags

includeScenarioTags can be used to provide a Cucumber tag expression in order to specify which tags should be included or excluded from scenario generation:

Example: include scenarios that are tagged with @scenario1:

<includeScenarioTags>@scenario1</includeScenarioTags>

Example: include scenarios that are tagged with @scenario1 or @scenario2:

<includeScenarioTags>@scenario1 or @scenario2</includeScenarioTags>

Example: include scenarios that are tagged with @scenario1 and @scenario2:

<includeScenarioTags>@scenario1 and @scenario2</includeScenarioTags>

Example: include scenarios that are not tagged with @scenario1:

<includeScenarioTags>not @scenario1</includeScenarioTags>

Example: include scenarios that are not tagged with @scenario1 but tagged with scenario2 or scenario3:

<includeScenarioTags>not @scenario1 and (@scenario2 or scenario3)</includeScenarioTags>

parallelizationMode

By default, Cucable uses the parallelizationMode = scenarios meaning that feature files are split into individual scenarios that each have a dedicated runner.

Sometimes it may be desirable, to parallelize complete features. When setting the parallelizationMode = features, only complete features containing all of their source scenarios are generated so each runner runs a complete feature.

<parallelizationMode>features</parallelizationMode>

Note: For this mode to work, <sourceFeatures> must specify a directory. Also, includeScenarioTags cannot be used.

logLevel

By default, Cucable logs all information including

  • its own name and version
  • all passed property values
  • a list of processed feature paths

This can be configured by passing the logLevel property:

<logLevel>default|compact|minimal|off</logLevel>
  • default will log all the mentioned information
  • compact will only log the plugin name, version, properties and one line of summary
  • minimal will only log a summary line
  • off will prevent any logging

desiredNumberOfRunners

If you set this options, all generated features will be distributed to a fixed set of runner classes. This means that one runner can potentially run multiple features in sequence.

If this option is not set, its default value is 0 which basically means "Generate a dedicated runner for every generated feature".

Note: This cannot be used together with desiredNumberOfFeaturesPerRunner!

desiredNumberOfFeaturesPerRunner

If you set this option, all generated features will be distributed to a dynamic set of runner classes so that every runner contains a fixed number of generated features. This means that one runner can potentially run multiple features in sequence.

If this option is not set, its default value is 0 which basically means "Generate a dedicated runner for every generated feature".

Note: This cannot be used together with desiredNumberOfRunners!

scenarioNames

A comma separated list of strings matching a scenario name, either completely or partially. Please see --name in Cucumber command-line options (java cucumber.api.cli.Main --help or mvn test -Dcucumber.options="--help). If you set this option, only scenarios matching the specified names will be loaded into the generated runners. The number of runner files will default to the number of scenario names and each runner file will contain the scenarios matching 1 name. Please note that this will override desiredNumberOfRunners. For example, if the following scenario names are specified:

<scenarioNames>
    name1,
    name2
</scenarioNames>

2 runner files will be generated. The first file will contain all the scenarios matching name1 and the second file will contain all the scenarios matching name2.

Note: This cannot be used together with desiredNumberOfFeaturesPerRunner or parallelizationMode = features!

Generating runners and features inside target directory

It may be desirable for you to generate the Cucable features and runners in Maven's target directory. The advantage of this is that this directory is wiped by the mvn clean command and older generated files do not reside in your src directory.

In order to achieve this, you can specify subdirectories under target (${project.build.directory}) for Cucable, e.g. ${project.build.directory}/parallel/runners and ${project.build.directory}/parallel/features

After this step, use the build-helper-maven-plugin in your POM file in order to consider the generated runner classes test sources:

<plugins>
    <plugin>
        <groupId>com.trivago.rta</groupId>
        <artifactId>cucable-plugin</artifactId>
        <version>${cucable.plugin.version}</version>
        <executions>
            <execution>
                <id>generate-test-resources</id>
                <phase>generate-test-resources</phase>
                <goals>
                    <goal>parallel</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <sourceRunnerTemplateFile>path_to_template_file</sourceRunnerTemplateFile>
            <sourceFeatures>path_to_features</sourceFeatures>
            <generatedFeatureDirectory>${project.build.directory}/parallel/features</generatedFeatureDirectory>
            <generatedRunnerDirectory>${project.build.directory}/parallel/runners</generatedRunnerDirectory>
        </configuration>    
    </plugin>
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <version>${build.helper.plugin.version}</version>
        <executions>
            <execution>
                <id>add-test-source</id>
                <phase>generate-test-sources</phase>
                <goals>
                    <goal>add-test-source</goal>
                </goals>
                <configuration>
                  <sources>
                    <source>${project.build.directory}/parallel/runners</source>
                  </sources>
                </configuration>   
            </execution>
        </executions> 
    </plugin>
</plugins>

Complete Example

Below, you can see a full example of what Cucable does.

Source feature file

This is our source feature file. It contains a scenario and a scenario outline with two examples.

MyFeature.feature

Feature: This is the feature name

    Scenario: First scenario
        Given I am on the start page
        And I click the login button
        Then I see an error message

    Scenario Outline: Second scenario with an amount of <amount>
        Given I am on the start page
        And I add <amount> items
        And I navigate to the shopping basket
        Then I see <amount> items
        Examples:
            | amount |
            | 12     |
            | 85     |

Runner template file

This is the runner template file (in this example we use a text file) that is used to generate single scenario runners.

  • The placeholder [CUCABLE:FEATURE] and its enclosing string will be replaced with the generated feature names by Cucable.
  • The placeholder [CUCABLE:RUNNER] will be replaced with the generated runner class name by Cucable.
import cucumber.api.CucumberOptions;

@CucumberOptions(
        features = {"target/parallel/features/[CUCABLE:FEATURE].feature"},
        plugin = {"json:target/cucumber-report/[CUCABLE:RUNNER].json"}
)
public class [CUCABLE:RUNNER] {
}

Note: The specified plugin generates Cucumber JSON files which are needed for custom aggregated test reports.

Generated Scenarios

For each scenario, a single feature file is created:

MyFeature_scenario001_run001_IT.feature

Feature: This is the feature name

Scenario: First scenario
Given I am on the start page
And I click the login button
Then I see an error message

Note that for the scenario outlines, each example is converted to its own scenario and feature file:

MyFeature_scenario002_run001_IT.feature

Feature: This is the feature name

Scenario: Second scenario with an amount of 12
Given I am on the start page
And I add 12 items
And I navigate to the shopping basket
Then I see 12 items

MyFeature_scenario003_run001_IT.feature

Feature: This is the feature name

Scenario: Second scenario with an amount of 85
Given I am on the start page
And I add 85 items
And I navigate to the shopping basket
Then I see 85 items

Generated runners

The generated runners point to each one of the generated feature files (unless you use the desiredNumberOfRunners or desiredNumberOfFeaturesPerRunner option).

This is an example for one of the generated runners - note how the placeholders are now replaced with the name of the feature to run:

Runner_MyFeature_scenario001_run001_IT.java

import cucumber.api.CucumberOptions;

@CucumberOptions(
        features = {"target/parallel/features/MyFeature_scenario001_run001_IT.feature"},
        plugin = {"json:target/cucumber-report/MyFeature_scenario001_run001_IT.json"}
)
public class MyFeature_scenario001_run001_IT {
}

2. Running the generated tests with Maven failsafe

This will skip the unit tests (if any) and run the generated runner classes with Maven Failsafe. Since all generated runner classes from the step before end with _IT, they are automatically considered integration tests and run with Maven Failsafe.

Note: If all tests should be run regardless of their result, it is important to set <testFailureIgnore>true</testFailureIgnore> for Maven Failsafe - otherwise the plugin execution will stop on failing tests. However, if this is specified, the build will not fail in case of failing tests!

To circumvent that, it is possible to specify a custom rule for Maven enforcer that passes or fails the build depending on custom conditions.

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
            <skipTests>true</skipTests>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <executions>
            <execution>
                <id>Run parallel tests</id>
                <phase>integration-test</phase>
                <goals>
                    <goal>integration-test</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <testFailureIgnore>true</testFailureIgnore>
            <forkCount>${maven.fork.count}</forkCount>
            <reuseForks>false</reuseForks>
            <argLine>-Dfile.encoding=UTF-8</argLine>
            <disableXmlReport>true</disableXmlReport>
        </configuration>
    </plugin>
</plugins>

3. Aggregation of a single test report after all test runs

We use the Cluecumber plugin to aggregate all generated .json report files into one overall test report.

<plugins>
    <plugin>
        <groupId>com.trivago.rta</groupId>
        <artifactId>cluecumber-report-plugin</artifactId>
        <version>${cluecumber.report.version}</version>
        <executions>
            <execution>
                <id>report</id>
                <phase>post-integration-test</phase>
                <goals>
                    <goal>reporting</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <sourceJsonReportDirectory>${project.build.directory}/cucumber-report</sourceJsonReportDirectory>
            <generatedHtmlReportDirectory>${project.build.directory}/test-report</generatedHtmlReportDirectory>
        </configuration>    
    </plugin>
</plugins>

Example project

You can test the complete flow and POM configuration by checking out the Cucable example project.

Appendix

Building

Cucable requires Java >= 8 and Maven >= 3.3.9. It is available in Maven central.

License

Copyright 2017 trivago N.V.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Credits

This plugin was inspired by the Cucumber Slices Maven Plugin.

More Repositories

1

prettier-plugin-sort-imports

A prettier plugin to sort imports in typescript and javascript files by the provided RegEx order.
TypeScript
3,284
star
2

parallel-webpack

Builds multi-config webpack projects in parallel
JavaScript
1,483
star
3

gollum

An n:m message multiplexer written in Go
Go
939
star
4

Heimdallr.swift

Easy to use OAuth 2 library for iOS, written in Swift.
Swift
639
star
5

cluecumber

Clear and concise reporting for the Cucumber BDD JSON format.
Java
270
star
6

Heimdall.droid

Easy to use OAuth 2 library for Android by trivago.
Kotlin
258
star
7

melody

Melody is a library for building JavaScript web applications.
JavaScript
215
star
8

Dobby

Swift helpers for mocking and stubbing
Swift
165
star
9

prettier-plugin-twig-melody

Code formatting plugin for Prettier which can handle Twig/Melody templates
JavaScript
155
star
10

triava

The triava project contains several of trivago's core libraries for Java-based projects: caching, collections, annotations, concurrency libraries and more.
Java
75
star
11

scalad

Horizontal Job Autoscaler for Nomad
Go
69
star
12

hamara

Export datasource from the existing Grafana DB into a YAML provisioning file
Go
57
star
13

tgo

trivago go utilities
Go
57
star
14

jade

A simple but yet powerful library to expose your entities through JSON API.
PHP
55
star
15

nomad-pot-driver

Nomad task driver for launching freebsd jails.
Go
54
star
16

Protector

A circuit breaker for InfluxDB
Python
48
star
17

fastutil-concurrent-wrapper

Set of concurrent wrappers around fastutil primitive maps
Java
37
star
18

babel-plugin-cloudinary

Compile cloudinary URLs at build time.
JavaScript
24
star
19

pbf-loader

Webpack loader for .proto files to be used within mapbox/pbf
JavaScript
21
star
20

rumi

trivago continuous integration executor
PHP
20
star
21

influxdbviewer

JavaScript
18
star
22

preact-hooks-testing-library

preact port of https://github.com/testing-library/react-hooks-testing-library
TypeScript
18
star
23

project-ironman

CSS skeleton / structure we used at trivago for our large scale refactoring project called Project Ironman
CSS
17
star
24

logstash-codec-protobuf

Protobuf codec for parsing data into logstash
17
star
25

samsa

A high level NodeJS stream processing library
TypeScript
17
star
26

jcha

Java Class Histogram Analyser
Java
17
star
27

hive-lambda-sting

A small library of hive UDFS using Macros to process and manipulate complex types
Java
15
star
28

reportoire

Kotlin
15
star
29

ReactiveHeimdall

Reactive wrapper around Heimdall.swift
Swift
14
star
30

chapi

chronos & marathon console client - Manage your jobs like a git repository
PHP
14
star
31

rebase

A small python library to make your data layer more robust.
Python
13
star
32

Mail-Pigeon

Mail Pigeon is a mail delivery plattform, which was created in the trivago developer days (something like the Google 20% rule) to replace some of the PHP based mailing scripts that were present that days. trivago has a lot of customers and therefore the focus laid on the fast and relyable sending process of a future mail tool. We decided to build a plattform that just can send mails in a performant manner, later on we built mail pigeon on top of it.
Java
13
star
33

boerewors

Release framework based on Python
Python
11
star
34

rtl-scss-kit

A right-to-left mixin set to create right-to-left and left-to-right css out of one scss-source
CSS
8
star
35

svn-daemon

A daemon to control a svn checkout via a web interface, written in go.
Go
8
star
36

exporter-edgecast

A Prometheus exporter for the Edgecast CDN
Go
7
star
37

triversity

trivago's university collaboration tool
Vue
7
star
38

libvips-mozjpeg-amazonlinux-buildscript

Modified libvips build script which helps to build libvips with mozjpeg support on AWS 'AmazonLinux' EC2 instances.
Shell
7
star
39

junior-java-software-engineer-casestudy

Case study for Junior Software Engineer - Java Backend Services
6
star
40

exporter-chinacache

A Prometheus exporter for the Chinacache CDN
Go
5
star
41

express-booking-selfconnect-api

trivago Express Booking - Self Connect API
PHP
5
star
42

recsys-challenge-2019-benchmarks

Run benchmark algorithms on the data sets of the RecSys Challenge 2019. https://recsys.trivago.cloud/
Python
4
star
43

create-melody-app

Create Melody apps quickly from the command line.
JavaScript
3
star
44

oauth-sdk-js

A tiny javascript library that allows to log in/register with trivago
JavaScript
2
star
45

melody-web

Public web site of the Melody JavaScript framework
HTML
2
star
46

.github

@trivago organization
2
star
47

intellij-idea-plugin

Internal IntelliJ plugin by trivago. Quick and dirty implementation.
Kotlin
1
star
48

melody-template

Melody Starter Example
JavaScript
1
star
49

mod_whatkilledus

Copy of sources from https://emptyhammock.com/projects/httpd/diag/
C
1
star
50

TriMamba

Collection of tools aimed to gather event information from different sources into a database
JavaScript
1
star