| commit | aa553172ae5609c23aa926c108a5b5bd6e5690b5 | [log] [tgz] |
|---|---|---|
| author | Jens Nyman <jnyman@google.com> | Wed Mar 03 14:00:27 2021 +0000 |
| committer | Jens Nyman <jnyman@google.com> | Wed Mar 03 14:00:27 2021 +0000 |
| tree | b1109b04d291e24f0ef2eb965af1c2cb19f55e63 | |
| parent | 99e892ac628e7c02796b6e69b0e8c33e5dfe0ab4 [diff] |
README: Fix typo in package name
Parameterized tests are a great way to avoid code duplication between tests and promote high test coverage for data-driven tests.
To start using TestParameterInjector right away, copy the following snippet:
import com.google.testing.junit.testparameterinjector.TestParameterInjector; import com.google.testing.junit.testparameterinjector.TestParameter; @RunWith(TestParameterInjector.class) public class MyTest { @TestParameter boolean isDryRun; @Test public void test1(@TestParameter boolean enableFlag) { // ... } @Test public void test2(@TestParameter MyEnum myEnum) { // ... } enum MyEnum { VALUE_A, VALUE_B, VALUE_C } }
@TestParameter for testing all combinationsThe simplest way to use this library is to use @TestParameter. For example:
@RunWith(TestParameterInjector.class) public class MyTest { @Test public void test(@TestParameter boolean isOwner) {...} }
In this example, two tests will be automatically generated by the test framework:
isOwner set to trueisOwner set to falseWhen running the tests, the result will show the following test names:
MyTest#test[isOwner=true] MyTest#test[isOwner=false]
@TestParameter can also annotate a field:
@RunWith(TestParameterInjector.class) public class MyTest { @TestParameter private boolean isOwner; @Test public void test1() {...} @Test public void test2() {...} }
In this example, both test1 and test2 will be run twice (once for each parameter value).
The following examples show most of the supported types. See the @TestParameter javadoc for more details.
// Enums @TestParameter AnimalEnum a; // Implies all possible values of AnimalEnum @TestParameter({"CAT", "DOG"}) AnimalEnum a; // Implies AnimalEnum.CAT and AnimalEnum.DOG. // Strings @TestParameter({"cat", "dog"}) String animalName; // Java primitives @TestParameter boolean b; // Implies {true, false} @TestParameter({"1", "2", "3"}) int i; @TestParameter({"1", "1.5", "2"}) double d;
If there are multiple @TestParameter-annotated values applicable to one test method, the test is run for all possible combinations of those values. Example:
@RunWith(TestParameterInjector.class) public class MyTest { @TestParameter private boolean a; @Test public void test1(@TestParameter boolean b, @TestParameter boolean c) { // Run for these combinations: // (a=false, b=false, c=false) // (a=false, b=false, c=true ) // (a=false, b=true, c=false) // (a=false, b=true, c=true ) // (a=true, b=false, c=false) // (a=true, b=false, c=true ) // (a=true, b=true, c=false) // (a=true, b=true, c=true ) } }
If you want to explicitly define which combinations are run, see the next sections.
Use this strategy if you want to:
String in a readable wayExample:
@RunWith(TestParameterInjector.class) class MyTest { enum FruitVolumeTestCase { APPLE(Fruit.newBuilder().setName("Apple").setShape(SPHERE).build(), /* expectedVolume= */ 3.1), BANANA(Fruit.newBuilder().setName("Banana").setShape(CURVED).build(), /* expectedVolume= */ 2.1), MELON(Fruit.newBuilder().setName("Melon").setShape(SPHERE).build(), /* expectedVolume= */ 6); final Fruit fruit; final double expectedVolume; FruitVolumeTestCase(Fruit fruit, double expectedVolume) { ... } } @Test public void calculateVolume_success(@TestParameter FruitVolumeTestCase fruitVolumeTestCase) { assertThat(calculateVolume(fruitVolumeTestCase.fruit)) .isEqualTo(fruitVolumeTestCase.expectedVolume); } }
The enum constant name has the added benefit of making for sensible test names:
MyTest#calculateVolume_success[APPLE] MyTest#calculateVolume_success[BANANA] MyTest#calculateVolume_success[MELON]
@TestParameters for defining sets of parametersYou can also explicitly enumerate the sets of test parameters via a list of YAML mappings:
@Test @TestParameters({ "{age: 17, expectIsAdult: false}", "{age: 22, expectIsAdult: true}", }) public void personIsAdult(int age, boolean expectIsAdult) { ... }
The string format supports the same types as @TestParameter (e.g. enums). See the @TestParameters javadoc for more info.
@TestParameters works in the same way on the constructor, in which case all tests will be run for the given parameter sets.
@TestParameterInstead of providing a list of parsable strings, you can implement your own TestParameterValuesProvider as follows:
@Test public void matchesAllOf_throwsOnNull( @TestParameter(valuesProvider = CharMatcherProvider.class) CharMatcher charMatcher) { assertThrows(NullPointerException.class, () -> charMatcher.matchesAllOf(null)); } private static final class CharMatcherProvider implements TestParameterValuesProvider { @Override public List<CharMatcher> provideValues() { return ImmutableList.of(CharMatcher.any(), CharMatcher.ascii(), CharMatcher.whitespace()); } }
Note that provideValues() dynamically construct the returned list, e.g. by reading a file. There are no restrictions on the object types returned, but note that toString() will be used for the test names.
@TestParametersInstead of providing a YAML mapping of parameters, you can implement your own TestParametersValuesProvider as follows:
@Test @TestParameters(valuesProvider = IsAdultValueProvider.class) public void personIsAdult(int age, boolean expectIsAdult) { ... } static final class IsAdultValueProvider implements TestParametersValuesProvider { @Override public ImmutableList<TestParametersValues> provideValues() { return ImmutableList.of( TestParametersValues.builder() .name("teenager") .addParameter("age", 17) .addParameter("expectIsAdult", false) .build(), TestParametersValues.builder() .name("young adult") .addParameter("age", 22) .addParameter("expectIsAdult", true) .build() ); } }