When writing test code, following the AAA pattern (Arrange/Act/Assert) improves readability and helps others understand your test code.
AAA pattern refers to dividing the test code into the following three steps.
- Arrange : Arrange the necessary things before running the tests. For example, it means creating an object, creating a mock object, or calling APIs that need to be called before testing.
- Act : Execute the test code
- Assert : Verifies that the executed code behaves as expected. Codes such as
assertTrue()
,assertThat()
, etc.
example
This is the test code written in AAA pattern.
@Test
public void testAAAPattern() {
// Arrange
List<String> list = new ArrayList<>();
// Act
list.add("123");
list.add("abc");
list.remove("abc");
// Assert
assertThat(list, hasItem("123"));
assertThat(list, not(hasItem("abc")));
}
- Arrange : Created a list object needed for testing
- Act : Executed the code to be tested. Here, as an example, we have added and deleted strings from the list.
- Assert: We have confirmed the expected result.
As in the example above, separating each step with a blank line makes the test code more readable. (It is not necessary to input Arrange, Act, Assert as comments.)
Most developers know the AAA pattern, so you can read the code in anticipation of this flow.
Example 2
The above example is also very simple, but the Act part is a bit crazy, and asserts that check different contents are being called.
Even the name of the test doesnt clearly indicate what you
re testing for.
The above test was divided into two tests as follows. Each test checks for only one behavior.
@Test
public void testDoingSomething_hasItem() {
// Arrange
List<String> list = new ArrayList<>();
// Act
addAndRemoveThings(list);
// Assert
assertThat(list, hasItem("123"));
}
@Test
public void testDoingSomething_hasNotItem() {
// Arrange
List<String> list = new ArrayList<>();
// Act
addAndRemoveThings(list);
// Assert
assertThat(list, not(hasItem("abc")));
}
private void addAndRemoveThings(List<String> list) {
list.add("123");
list.add("abc");
list.remove("abc");
}
First, I changed the 3 lines of code performed in Act to one method called addAndRemoveThings()
.
Also, by naming the methods appropriately, we don`t need to see what the reader of the test is doing inside the method.
Finally, we added only 1 assert to each test. Having a lot of asserts that check different results can obscure what behavior this test tests for.
(It seems that there is no problem even if you check remove and add in one test. This is an extreme example, so please consider these parts.)
By keeping one test, you can save time in Arrange or Act. However, it can be difficult to understand the test code, and when the test fails, the assert code behind it is not checked and the test is terminated.
So, its a good idea to have a small number of asserts added to a single test, while keeping it lightweight so that splitting it up into multiple tests doesn
t take too long.
Of course, this is only a guide, and in some cases its fine to do so if there
s a benefit to adding a lot of asserts.
Related Posts
- Java - Remove items from List while iterating
- Java - How to find key by value in HashMap
- Java - Update the value of a key in HashMap
- Java - How to put quotes in a string
- Java - How to put a comma (,) after every 3 digits
- BiConsumer example in Java 8
- Java 8 - Consumer example
- Java 8 - BinaryOperator example
- Java 8 - BiPredicate Example
- Java 8 - Predicate example
- Java 8 - Convert Stream to List
- Java 8 - BiFunction example
- Java 8 - Function example
- Java - Convert List to Map
- Exception testing in JUnit
- Hamcrest Collections Matcher
- Hamcrest equalTo () Matcher
- AAA pattern of unit test (Arrange/Act/Assert)
- Hamcrest Text Matcher
- Hamcrest Custom Matcher
- Why Junit uses Hamcrest
- Java - ForkJoinPool
- Java - How to use Futures
- Java - Simple HashTable implementation
- Java - Create a file in a specific path
- Java - Mockito의 @Mock, @Spy, @Captor, @InjectMocks
- Java - How to write test code using Mockito
- Java - Synchronized block
- Java - How to decompile a ".class" file into a Java file (jd-cli decompiler)
- Java - How to generate a random number
- Java - Calculate powers, Math.pow()
- Java - Calculate the square root, Math.sqrt()
- Java - How to compare String (==, equals, compare)
- Java - Calculate String Length
- Java - case conversion & comparison insensitive (toUpperCase, toLowerCase, equalsIgnoreCase)