diff --git a/testing-modules/pom.xml b/testing-modules/pom.xml
index a6b5fba570..9080d5a0ea 100644
--- a/testing-modules/pom.xml
+++ b/testing-modules/pom.xml
@@ -52,6 +52,7 @@
xmlunit-2
zerocode
mockito-2
+ testing-techniques
gatling-java
diff --git a/testing-modules/testing-techniques/pom.xml b/testing-modules/testing-techniques/pom.xml
new file mode 100644
index 0000000000..5902047aeb
--- /dev/null
+++ b/testing-modules/testing-techniques/pom.xml
@@ -0,0 +1,14 @@
+
+
+
+ testing-techniques
+ 4.0.0
+
+
+ testing-modules
+ com.baeldung
+ 1.0.0-SNAPSHOT
+
+
\ No newline at end of file
diff --git a/testing-modules/testing-techniques/src/main/java/com/baeldung/greyboxtesting/SalaryCommissionPercentageCalculator.java b/testing-modules/testing-techniques/src/main/java/com/baeldung/greyboxtesting/SalaryCommissionPercentageCalculator.java
new file mode 100644
index 0000000000..d97b6687b3
--- /dev/null
+++ b/testing-modules/testing-techniques/src/main/java/com/baeldung/greyboxtesting/SalaryCommissionPercentageCalculator.java
@@ -0,0 +1,67 @@
+package com.baeldung.greyboxtesting;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.stream.DoubleStream;
+
+public class SalaryCommissionPercentageCalculator {
+ public BigDecimal calculate(Level level, Type type, Seniority seniority, SalesImpact impact) {
+ return BigDecimal.valueOf(DoubleStream.of(level.getBonus(), type.getBonus(), seniority.getBonus(), impact.getBonus(), type.getBonus())
+ .average()
+ .orElse(0))
+ .setScale(2, RoundingMode.CEILING);
+ }
+
+ public enum Level {
+ L1(0.06), L2(0.12), L3(0.2);
+ private double bonus;
+
+ Level(double bonus) {
+ this.bonus = bonus;
+ }
+
+ public double getBonus() {
+ return bonus;
+ }
+ }
+
+ public enum Type {
+ FULL_TIME_COMMISSIONED(0.18), CONTRACTOR(0.1), FREELANCER(0.06);
+
+ private double bonus;
+
+ Type(double bonus) {
+ this.bonus = bonus;
+ }
+
+ public double getBonus() {
+ return bonus;
+ }
+ }
+
+ public enum Seniority {
+ JR(0.8), MID(0.13), SR(0.19);
+ private double bonus;
+
+ Seniority(double bonus) {
+ this.bonus = bonus;
+ }
+
+ public double getBonus() {
+ return bonus;
+ }
+ }
+
+ public enum SalesImpact {
+ LOW(0.06), MEDIUM(0.12), HIGH(0.2);
+ private double bonus;
+
+ SalesImpact(double bonus) {
+ this.bonus = bonus;
+ }
+
+ public double getBonus() {
+ return bonus;
+ }
+ }
+}
diff --git a/testing-modules/testing-techniques/src/test/java/com/baeldung/greyboxtesting/SalaryCommissionPercentageCalculatorUnitTest.java b/testing-modules/testing-techniques/src/test/java/com/baeldung/greyboxtesting/SalaryCommissionPercentageCalculatorUnitTest.java
new file mode 100644
index 0000000000..e39a1e5445
--- /dev/null
+++ b/testing-modules/testing-techniques/src/test/java/com/baeldung/greyboxtesting/SalaryCommissionPercentageCalculatorUnitTest.java
@@ -0,0 +1,41 @@
+package com.baeldung.greyboxtesting;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import java.math.BigDecimal;
+import java.util.stream.Stream;
+
+import static com.baeldung.greyboxtesting.SalaryCommissionPercentageCalculator.*;
+import static com.baeldung.greyboxtesting.SalaryCommissionPercentageCalculator.Level.*;
+import static com.baeldung.greyboxtesting.SalaryCommissionPercentageCalculator.SalesImpact.*;
+import static com.baeldung.greyboxtesting.SalaryCommissionPercentageCalculator.Seniority.*;
+import static com.baeldung.greyboxtesting.SalaryCommissionPercentageCalculator.Type.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class SalaryCommissionPercentageCalculatorUnitTest {
+
+ private SalaryCommissionPercentageCalculator testTarget = new SalaryCommissionPercentageCalculator();
+
+ @ParameterizedTest
+ @MethodSource("provideReferenceTestScenarioTable")
+ void givenReferenceTable_whenCalculateAverageCommission_thenReturnExpectedResult(Level level, Type type, Seniority seniority, SalesImpact impact, double expected) {
+ BigDecimal got = testTarget.calculate(level, type, seniority, impact);
+ assertEquals(BigDecimal.valueOf(expected), got);
+ }
+
+ private static Stream provideReferenceTestScenarioTable() {
+ return Stream.of(
+ Arguments.of(L1, FULL_TIME_COMMISSIONED, JR, LOW, 0.26),
+ Arguments.of(L1, CONTRACTOR, SR, MEDIUM, 0.12),
+ Arguments.of(L1, FREELANCER, MID, HIGH, 0.11),
+ Arguments.of(L2, FULL_TIME_COMMISSIONED, SR, HIGH, 0.18),
+ Arguments.of(L2, CONTRACTOR, MID, LOW, 0.11),
+ Arguments.of(L2, FREELANCER, JR, MEDIUM, 0.24),
+ Arguments.of(L3, FULL_TIME_COMMISSIONED, MID, MEDIUM, 0.17),
+ Arguments.of(L3, CONTRACTOR, JR, HIGH, 0.28),
+ Arguments.of(L3, FREELANCER, SR, LOW, 0.12)
+ );
+ }
+}
\ No newline at end of file