Parameterized testing
1. Parameterized testing
Hello again! In this section, we'll learn how to make tests less verbose and repetitive.2. Example: Username validation
Let’s start with an example. In the username validation exercise from Chapter 1, we wrote multiple unit tests for different invalid cases: - The username is null - It's empty - It contains spaces3. Example: Repetitive validation test
All our false-case tests followed the same structure, only the username value changed. Writing them separately was repetitive and broke the DRY principle: Don’t Repeat Yourself. Parameterized tests in JUnit solve this problem!4. Parameterized tests: syntax
To parameterize a test, we annotate it with `@ParameterizedTest` instead of the familiar `@Test`. It comes from JUnit's `params` package. JUnit then expects a value source, which we provide using the `@ValueSource` annotation.5. Parameterized tests: example test
Previously, the tests took no arguments. Now, the test will take one argument - String username, provided by the values listed in the `@ValueSource` annotation. As shown here, Java annotations can also take arguments. Notice the arguments are custom to the annotation. Here ValueSource takes "strings" rather than String as type of the values it provides. JUnit will execute this as two separate tests and print this result.6. @ValueSource limitations
While useful, ValueSource has its limitations. It can only be used to provide certain types. They are all listed as examples here - bytes, integer and non-integer numeric types, characters, booleans and strings, and finally class names.7. @NullSource
In the previous slide, we missed an edge case: we did not test for the null input. This is because `@ValueSource` does not accept null, and if we pass it, it will not compile. The solution is to use the additional annotation `@NullSource`.8. Running the full ParameterizedTest
We add NullSource along with the other annotations. This will add a third test case, which will execute with the others.9. Multiple arguments per test
Another limitation of `@ValueSource` is that it can only pass one value per test. Consider the following example, where we count the symbols in a string. The output will be different for every input.10. @CsvSource
To pass multiple values, use `@CsvSource`, where Csv means "comma separated values". Now we can input any number of arguments - we pass them into the CsvSource annotation as a list of strings in the braces. Each string consists of comma separated values. Note empty string before the comma is interpreted as null in newer versions of JUnit. To make an empty string, we use single quotes before the comma. CvsSource also has type limitations like ValueSource, but again, we can use it with primitives and Strings. There are more sophisticated ways to add arguments, and we will discuss them in the next video.11. Note: Importing Source annotation
As a final note, all Source annotations we will discuss can be imported from the `junit.jupiter.provider` package.12. Let's practice!
Now let's practice combining our repetitive tests into one!Create Your Free Account
or
By continuing, you accept our Terms of Use, our Privacy Policy and that your data is stored in the USA.